[ding-libs] Fix off-by-one bug in path_concat()

Stephen Gallagher sgallagh at fedoraproject.org
Tue Mar 6 21:38:28 UTC 2012


commit 82d0379be915638f894a6ad470fdcceb56b9ee2c
Author: Stephen Gallagher <sgallagh at redhat.com>
Date:   Tue Mar 6 16:38:25 2012 -0500

    Fix off-by-one bug in path_concat()
    
    - Resolves: rhbz#799347 - path_utils:test_path_concat_neg fails on 64-bit big
                              endians

 ...ls-handle-off-by-one-error-in-path_concat.patch |   62 ++++++++++++++++++++
 0002-path_utils-Handle-in-path_concat.patch        |   62 ++++++++++++++++++++
 ding-libs.spec                                     |   13 ++++-
 3 files changed, 136 insertions(+), 1 deletions(-)
---
diff --git a/0001-path_utils-handle-off-by-one-error-in-path_concat.patch b/0001-path_utils-handle-off-by-one-error-in-path_concat.patch
new file mode 100644
index 0000000..7ba4508
--- /dev/null
+++ b/0001-path_utils-handle-off-by-one-error-in-path_concat.patch
@@ -0,0 +1,62 @@
+From 6bc68b4dfeaf3320adc58e52dea5530ce2ce8a6c Mon Sep 17 00:00:00 2001
+From: Stephen Gallagher <sgallagh at redhat.com>
+Date: Tue, 6 Mar 2012 11:05:53 -0500
+Subject: [PATCH 1/2] path_utils: handle off-by-one error in path_concat()
+
+https://fedorahosted.org/sssd/ticket/1230
+---
+ path_utils/path_utils.c    |    2 +-
+ path_utils/path_utils_ut.c |   18 ++++++++++++++----
+ 2 files changed, 15 insertions(+), 5 deletions(-)
+
+diff --git a/path_utils/path_utils.c b/path_utils/path_utils.c
+index 97c845c70f41e071c0d9524172ad3b0b33a84c3b..360d49943436681970691cc829c8039f3a0e8a5f 100644
+--- a/path_utils/path_utils.c
++++ b/path_utils/path_utils.c
+@@ -210,7 +210,7 @@ int path_concat(char *path, size_t path_size, const char *head, const char *tail
+         for (p = tail; *p && *p == '/'; p++);   /* skip any leading slashes in tail */
+         if (dst > path)
+             if (dst < dst_end) *dst++ = '/';    /* insert single slash between head & tail */
+-        for (src = p; *src && dst <= dst_end;) *dst++ = *src++; /* copy tail */
++        for (src = p; *src && dst < dst_end;) *dst++ = *src++; /* copy tail */
+         if (*src) return ENOBUFS; /* failed to copy everything */
+     }
+     *dst = 0;
+diff --git a/path_utils/path_utils_ut.c b/path_utils/path_utils_ut.c
+index 044e9ea2d12e396f9f68a23bde8b11f6ac3fcc09..fbefcab1eb66b5c36a3d7a74a099f569ea764b3b 100644
+--- a/path_utils/path_utils_ut.c
++++ b/path_utils/path_utils_ut.c
+@@ -241,16 +241,26 @@ END_TEST
+ START_TEST(test_path_concat_neg)
+ {
+     char small[3];
+-    char small2[4];
+-    char p2[8];
++    char small2[5];
++    char small3[7];
++    char p2[9];
+ 
+     /* these two test different conditions */
++
++    /* Test if head is longer than the buffer */
+     fail_unless(path_concat(small, 3, "/foo", "bar") == ENOBUFS);
+-    fail_unless(path_concat(small2, 4, "/foo", "bar") == ENOBUFS);
++
++    /* Test if head is the same length as the buffer */
++    fail_unless(path_concat(small2, 5, "/foo", "bar") == ENOBUFS);
++
++    /* Test if head+tail is the longer than the buffer */
++    fail_unless(path_concat(small3, 7, "/foo", "bar") == ENOBUFS);
+ 
+     /* off-by-one */
++    p2[8] = 1; /* Check whether we've written too far */
+     fail_unless(path_concat(p2, 8, "/foo", "bar") == ENOBUFS);
+-    fail_unless_str_equal(p2, "/foo/bar");
++    fail_unless(p2[8] == 1); /* This should be untouched */
++    fail_unless_str_equal(p2, "/foo/ba");
+ }
+ END_TEST
+ 
+-- 
+1.7.7.6
+
diff --git a/0002-path_utils-Handle-in-path_concat.patch b/0002-path_utils-Handle-in-path_concat.patch
new file mode 100644
index 0000000..f6415c5
--- /dev/null
+++ b/0002-path_utils-Handle-in-path_concat.patch
@@ -0,0 +1,62 @@
+From 641d6b290b49dad364a7de5fe5af7c983482d2b7 Mon Sep 17 00:00:00 2001
+From: Stephen Gallagher <sgallagh at redhat.com>
+Date: Tue, 6 Mar 2012 11:34:41 -0500
+Subject: [PATCH 2/2] path_utils: Handle "/" in path_concat
+
+---
+ path_utils/path_utils.c    |   12 ++++++++++--
+ path_utils/path_utils_ut.c |    9 +++++++++
+ 2 files changed, 19 insertions(+), 2 deletions(-)
+
+diff --git a/path_utils/path_utils.c b/path_utils/path_utils.c
+index 360d49943436681970691cc829c8039f3a0e8a5f..25ca4267fc0d7d9f3483646c2aef22fcdef1eb24 100644
+--- a/path_utils/path_utils.c
++++ b/path_utils/path_utils.c
+@@ -202,14 +202,22 @@ int path_concat(char *path, size_t path_size, const char *head, const char *tail
+ 
+     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 */
++        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 */
+     }
+     if (tail && *tail) {
+         for (p = tail; *p && *p == '/'; p++);   /* skip any leading slashes in tail */
+         if (dst > path)
+-            if (dst < dst_end) *dst++ = '/';    /* insert single slash between head & tail */
++            /* insert single slash between head & tail
++             * Making sure not to add an extra if the
++             * preceding character is also a slash
++             * (such as the case where head was the
++             * special-case "/".
++             */
++            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 */
+     }
+diff --git a/path_utils/path_utils_ut.c b/path_utils/path_utils_ut.c
+index fbefcab1eb66b5c36a3d7a74a099f569ea764b3b..34462cfdd4a2238f878a170fba2481b31f96e33e 100644
+--- a/path_utils/path_utils_ut.c
++++ b/path_utils/path_utils_ut.c
+@@ -229,6 +229,15 @@ START_TEST(test_path_concat)
+     fail_unless(path_concat(p, PATH_MAX, "", "foo") == SUCCESS);
+     fail_unless_str_equal(p, "foo");
+ 
++    fail_unless(path_concat(p, PATH_MAX, "/", "foo") == SUCCESS);
++    fail_unless_str_equal(p, "/foo");
++
++    fail_unless(path_concat(p, PATH_MAX, "/foo", "/") == SUCCESS);
++    fail_unless_str_equal(p, "/foo/");
++
++    fail_unless(path_concat(p, PATH_MAX, "/foo", "bar/") == SUCCESS);
++    fail_unless_str_equal(p, "/foo/bar/");
++
+     fail_unless(path_concat(p, PATH_MAX, NULL, "foo") == SUCCESS);
+     fail_unless_str_equal(p, "foo");
+ 
+-- 
+1.7.7.6
+
diff --git a/ding-libs.spec b/ding-libs.spec
index 2044b04..389c8cf 100644
--- a/ding-libs.spec
+++ b/ding-libs.spec
@@ -1,6 +1,6 @@
 Name: ding-libs
 Version: 0.1.3
-Release: 6%{?dist}
+Release: 7%{?dist}
 Summary: "Ding is not GLib" assorted utility libraries
 Group: Development/Libraries
 License: LGPLv3+
@@ -16,6 +16,9 @@ BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
 
 ### Patches ###
 
+Patch0001: 0001-path_utils-handle-off-by-one-error-in-path_concat.patch
+Patch0002: 0002-path_utils-Handle-in-path_concat.patch
+
 ### Dependencies ###
 
 ### Build Dependencies ###
@@ -247,6 +250,9 @@ structure
 %prep
 %setup -q
 
+%patch0001 -p1
+%patch0002 -p1
+
 %build
 %configure \
     --disable-static
@@ -279,6 +285,11 @@ rm -f */doc/html/installdox
 rm -rf $RPM_BUILD_ROOT
 
 %changelog
+* Tue Mar 06 2012 Stephen Gallagher <sgallagh at 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
+                          endians
+
 * Fri Jan 13 2012 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 0.1.3-6
 - Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild
 


More information about the scm-commits mailing list