[libxml2] Fix xmlBuildRelativeURI for URIs starting with './'



commit 91e549678019a14cb6df4a1b58ce5681d0b16264
Author: Nick Wellnhofer <wellnhofer aevum de>
Date:   Thu Jun 8 18:25:30 2017 +0200

    Fix xmlBuildRelativeURI for URIs starting with './'
    
    If the relative URI started with './', the 'pos' index was increased
    which also affected indexing into the base path. Aside from producing
    wrong results, this could also lead to a heap overread of the base
    path buffer. The data read from beyond the buffer was only compared
    to some char values, so this is mostly harmless.
    
    Inside libxml2, xmlBuildRelativeURI is only called from xinclude.c.
    
    Found with libFuzzer and ASan.

 uri.c |   32 +++++++++++++++++---------------
 1 files changed, 17 insertions(+), 15 deletions(-)
---
diff --git a/uri.c b/uri.c
index 530ce21..3b627e8 100644
--- a/uri.c
+++ b/uri.c
@@ -2163,7 +2163,6 @@ xmlBuildRelativeURI (const xmlChar * URI, const xmlChar * base)
     xmlChar *val = NULL;
     int ret;
     int ix;
-    int pos = 0;
     int nbslash = 0;
     int len;
     xmlURIPtr ref = NULL;
@@ -2254,19 +2253,22 @@ xmlBuildRelativeURI (const xmlChar * URI, const xmlChar * base)
        uptr = NULL;
        len = 1;        /* this is for a string terminator only */
     } else {
-    /*
-     * Next we compare the two strings and find where they first differ
-     */
-       if ((ref->path[pos] == '.') && (ref->path[pos+1] == '/'))
-            pos += 2;
+        xmlChar *rptr = (xmlChar *) ref->path;
+        int pos = 0;
+
+        /*
+         * Next we compare the two strings and find where they first differ
+         */
+       if ((*rptr == '.') && (rptr[1] == '/'))
+            rptr += 2;
        if ((*bptr == '.') && (bptr[1] == '/'))
             bptr += 2;
-       else if ((*bptr == '/') && (ref->path[pos] != '/'))
+       else if ((*bptr == '/') && (*rptr != '/'))
            bptr++;
-       while ((bptr[pos] == ref->path[pos]) && (bptr[pos] != 0))
+       while ((bptr[pos] == rptr[pos]) && (bptr[pos] != 0))
            pos++;
 
-       if (bptr[pos] == ref->path[pos]) {
+       if (bptr[pos] == rptr[pos]) {
            val = xmlStrdup(BAD_CAST "");
            goto done;          /* (I can't imagine why anyone would do this) */
        }
@@ -2276,25 +2278,25 @@ xmlBuildRelativeURI (const xmlChar * URI, const xmlChar * base)
         * beginning of the "unique" suffix of URI
         */
        ix = pos;
-       if ((ref->path[ix] == '/') && (ix > 0))
+       if ((rptr[ix] == '/') && (ix > 0))
            ix--;
-       else if ((ref->path[ix] == 0) && (ix > 1) && (ref->path[ix - 1] == '/'))
+       else if ((rptr[ix] == 0) && (ix > 1) && (rptr[ix - 1] == '/'))
            ix -= 2;
        for (; ix > 0; ix--) {
-           if (ref->path[ix] == '/')
+           if (rptr[ix] == '/')
                break;
        }
        if (ix == 0) {
-           uptr = (xmlChar *)ref->path;
+           uptr = (xmlChar *)rptr;
        } else {
            ix++;
-           uptr = (xmlChar *)&ref->path[ix];
+           uptr = (xmlChar *)&rptr[ix];
        }
 
        /*
         * In base, count the number of '/' from the differing point
         */
-       if (bptr[pos] != ref->path[pos]) {/* check for trivial URI == base */
+       if (bptr[pos] != rptr[pos]) {/* check for trivial URI == base */
            for (; bptr[ix] != 0; ix++) {
                if (bptr[ix] == '/')
                    nbslash++;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]