mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2025-08-29 01:49:22 +03:00
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.
This commit is contained in:
32
uri.c
32
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++;
|
||||
|
Reference in New Issue
Block a user