From 4e0c978e54054de441e8c126c63f6218cf97ea91 Mon Sep 17 00:00:00 2001 From: Stephen Gallagher Date: Mar 16 2012 12:32:11 +0000 Subject: Make path_concat return empty string on ENOBUFS --- diff --git a/0003-path_utils-path_concat-should-return-empty-string-on.patch b/0003-path_utils-path_concat-should-return-empty-string-on.patch new file mode 100644 index 0000000..ddb5f5c --- /dev/null +++ b/0003-path_utils-path_concat-should-return-empty-string-on.patch @@ -0,0 +1,153 @@ +From c4fdad249bf62d61856d26f97849e61351a356d5 Mon Sep 17 00:00:00 2001 +From: Stephen Gallagher +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 + diff --git a/ding-libs.spec b/ding-libs.spec index 389c8cf..0b47704 100644 --- a/ding-libs.spec +++ b/ding-libs.spec @@ -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 - 0.1.3-8 +- Make path_concat return empty string on ENOBUFS + * Tue Mar 06 2012 Stephen Gallagher - 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