Make path_concat return empty string on ENOBUFS
This commit is contained in:
parent
82d0379be9
commit
4e0c978e54
153
0003-path_utils-path_concat-should-return-empty-string-on.patch
Normal file
153
0003-path_utils-path_concat-should-return-empty-string-on.patch
Normal file
@ -0,0 +1,153 @@
|
||||
From c4fdad249bf62d61856d26f97849e61351a356d5 Mon Sep 17 00:00:00 2001
|
||||
From: Stephen Gallagher <sgallagh@redhat.com>
|
||||
Date: Wed, 7 Mar 2012 09:29:46 -0500
|
||||
Subject: [PATCH] path_utils: path_concat should return empty string on
|
||||
ENOBUFS
|
||||
|
||||
Also clean up the code a bit and add more comments
|
||||
---
|
||||
path_utils/path_utils.c | 48 ++++++++++++++++++++++++++++++++++---------
|
||||
path_utils/path_utils.h | 3 +-
|
||||
path_utils/path_utils_ut.c | 19 +++++++++++++---
|
||||
3 files changed, 55 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/path_utils/path_utils.c b/path_utils/path_utils.c
|
||||
index 25ca4267fc0d7d9f3483646c2aef22fcdef1eb24..0a758c5bfd09ef5708e9f68d3aecc0733607e3d8 100644
|
||||
--- a/path_utils/path_utils.c
|
||||
+++ b/path_utils/path_utils.c
|
||||
@@ -192,6 +192,7 @@ bool is_absolute_path(const char *path)
|
||||
|
||||
int path_concat(char *path, size_t path_size, const char *head, const char *tail)
|
||||
{
|
||||
+ int ret;
|
||||
const char *p, *src;
|
||||
char *dst, *dst_end;
|
||||
|
||||
@@ -201,13 +202,27 @@ int path_concat(char *path, size_t path_size, const char *head, const char *tail
|
||||
dst_end = path + path_size - 1; /* -1 allows for NULL terminator */
|
||||
|
||||
if (head && *head) {
|
||||
- for (p = head; *p; p++); /* walk to end of head */
|
||||
- for (p--; p > head && *p == '/'; p--); /* skip any trailing slashes in head */
|
||||
- if ((p - head) > path_size-1) return ENOBUFS;
|
||||
- for (src = head; src <= p && dst < dst_end;) *dst++ = *src++; /* copy head */
|
||||
+ /* walk to end of head */
|
||||
+ for (p = head; *p; p++);
|
||||
+
|
||||
+ /* skip any trailing slashes in head */
|
||||
+ for (p--; p > head && *p == '/'; p--);
|
||||
+
|
||||
+ /* If the length of head exceeds the buffer size, fail */
|
||||
+ if ((p - head) > path_size-1) {
|
||||
+ ret = ENOBUFS;
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ /* Copy head into path */
|
||||
+ for (src = head; src <= p && dst < dst_end;) {
|
||||
+ *dst++ = *src++;
|
||||
+ }
|
||||
}
|
||||
if (tail && *tail) {
|
||||
- for (p = tail; *p && *p == '/'; p++); /* skip any leading slashes in tail */
|
||||
+ /* skip any leading slashes in tail */
|
||||
+ for (p = tail; *p && *p == '/'; p++);
|
||||
+
|
||||
if (dst > path)
|
||||
/* insert single slash between head & tail
|
||||
* Making sure not to add an extra if the
|
||||
@@ -218,15 +233,28 @@ int path_concat(char *path, size_t path_size, const char *head, const char *tail
|
||||
if (dst < dst_end && *(dst-1) != '/') {
|
||||
*dst++ = '/';
|
||||
}
|
||||
- for (src = p; *src && dst < dst_end;) *dst++ = *src++; /* copy tail */
|
||||
- if (*src) return ENOBUFS; /* failed to copy everything */
|
||||
+
|
||||
+ /* Copy the tail into the path */
|
||||
+ for (src = p; *src && dst < dst_end;) {
|
||||
+ *dst++ = *src++;
|
||||
+ }
|
||||
+
|
||||
+ /* If we got past dst_end and there is more data
|
||||
+ * in the src buffer, we should return ENOBUFS
|
||||
+ */
|
||||
+ if (*src) {
|
||||
+ ret = ENOBUFS; /* failed to copy everything */
|
||||
+ goto fail;
|
||||
+ }
|
||||
}
|
||||
*dst = 0;
|
||||
- if (dst > dst_end) {
|
||||
- return ENOBUFS;
|
||||
- }
|
||||
+
|
||||
return SUCCESS;
|
||||
|
||||
+fail:
|
||||
+ /* On failure, set the buffer to the empty string for safety */
|
||||
+ *path = '\0';
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
int make_path_absolute(char *absolute_path, size_t absolute_path_size, const char *path)
|
||||
diff --git a/path_utils/path_utils.h b/path_utils/path_utils.h
|
||||
index 2fd567c4eaa30ee1eb05af868d7d14b6e2a71a43..17ed1f4324a192c32d8229417d527424ef01ccd2 100644
|
||||
--- a/path_utils/path_utils.h
|
||||
+++ b/path_utils/path_utils.h
|
||||
@@ -198,7 +198,8 @@ bool is_absolute_path(const char *path);
|
||||
* @param[in] tail The second component of the path
|
||||
*
|
||||
* @return \c SUCCESS if successful, non-zero error code otherwise.
|
||||
- * \li \c ENOBUFS If the buffer space is too small
|
||||
+ * \li \c ENOBUFS If the buffer space is too small. In this case,
|
||||
+ * path will be set to an empty string.
|
||||
*/
|
||||
int path_concat(char *path, size_t path_size, const char *head, const char *tail);
|
||||
|
||||
diff --git a/path_utils/path_utils_ut.c b/path_utils/path_utils_ut.c
|
||||
index 34462cfdd4a2238f878a170fba2481b31f96e33e..aadd89b74420a4f8bc51ace779ecfb4223afa0e3 100644
|
||||
--- a/path_utils/path_utils_ut.c
|
||||
+++ b/path_utils/path_utils_ut.c
|
||||
@@ -252,24 +252,35 @@ START_TEST(test_path_concat_neg)
|
||||
char small[3];
|
||||
char small2[5];
|
||||
char small3[7];
|
||||
- char p2[9];
|
||||
+ char p2[10];
|
||||
|
||||
/* these two test different conditions */
|
||||
|
||||
/* Test if head is longer than the buffer */
|
||||
fail_unless(path_concat(small, 3, "/foo", "bar") == ENOBUFS);
|
||||
+ /* On ENOBUFS, path should be empty */
|
||||
+ fail_unless_str_equal(small, "");
|
||||
|
||||
/* Test if head is the same length as the buffer */
|
||||
fail_unless(path_concat(small2, 5, "/foo", "bar") == ENOBUFS);
|
||||
+ /* On ENOBUFS, path should be empty */
|
||||
+ fail_unless_str_equal(small2, "");
|
||||
|
||||
/* Test if head+tail is the longer than the buffer */
|
||||
fail_unless(path_concat(small3, 7, "/foo", "bar") == ENOBUFS);
|
||||
+ /* On ENOBUFS, path should be empty */
|
||||
+ fail_unless_str_equal(small3, "");
|
||||
|
||||
/* off-by-one */
|
||||
- p2[8] = 1; /* Check whether we've written too far */
|
||||
+ /* Fill with garbage data for now */
|
||||
+ memset(p2, 'Z', 9);
|
||||
+ p2[9] = '\0';
|
||||
+
|
||||
fail_unless(path_concat(p2, 8, "/foo", "bar") == ENOBUFS);
|
||||
- fail_unless(p2[8] == 1); /* This should be untouched */
|
||||
- fail_unless_str_equal(p2, "/foo/ba");
|
||||
+ /* Make sure we don't write past the end of the buffer */
|
||||
+ fail_unless(p2[8] == 'Z', "Got [%d]", p2[8]);
|
||||
+ /* On ENOBUFS, path should be empty */
|
||||
+ fail_unless_str_equal(p2, "");
|
||||
}
|
||||
END_TEST
|
||||
|
||||
--
|
||||
1.7.7.6
|
||||
|
@ -1,6 +1,6 @@
|
||||
Name: ding-libs
|
||||
Version: 0.1.3
|
||||
Release: 7%{?dist}
|
||||
Release: 8%{?dist}
|
||||
Summary: "Ding is not GLib" assorted utility libraries
|
||||
Group: Development/Libraries
|
||||
License: LGPLv3+
|
||||
@ -18,6 +18,7 @@ BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
|
||||
|
||||
Patch0001: 0001-path_utils-handle-off-by-one-error-in-path_concat.patch
|
||||
Patch0002: 0002-path_utils-Handle-in-path_concat.patch
|
||||
Patch0003: 0003-path_utils-path_concat-should-return-empty-string-on.patch
|
||||
|
||||
### Dependencies ###
|
||||
|
||||
@ -252,6 +253,7 @@ structure
|
||||
|
||||
%patch0001 -p1
|
||||
%patch0002 -p1
|
||||
%patch0003 -p1
|
||||
|
||||
%build
|
||||
%configure \
|
||||
@ -285,6 +287,9 @@ rm -f */doc/html/installdox
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
%changelog
|
||||
* Tue Mar 06 2012 Stephen Gallagher <sgallagh@redhat.com> - 0.1.3-8
|
||||
- Make path_concat return empty string on ENOBUFS
|
||||
|
||||
* Tue Mar 06 2012 Stephen Gallagher <sgallagh@redhat.com> - 0.1.3-7
|
||||
- Fix off-by-one bug in path_concat()
|
||||
- Resolves: rhbz#799347 - path_utils:test_path_concat_neg fails on 64-bit big
|
||||
|
Loading…
Reference in New Issue
Block a user