1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2024-12-25 23:21:26 +03:00

Revert "Do not URI escape in server side includes"

This reverts commit 960f0e2756.

This commit introduced

- an infinite loop, found by OSS-Fuzz, which could be easily fixed.
- an algorithm with quadratic runtime
- a security issue, see
  https://bugzilla.gnome.org/show_bug.cgi?id=769760

A better approach is to add an option not to escape URLs at all
which libxml2 should have possibly done in the first place.
This commit is contained in:
Nick Wellnhofer 2020-08-15 18:32:29 +02:00
parent b82fa3dd26
commit c1ba6f54d3

View File

@ -706,49 +706,22 @@ htmlAttrDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlAttrPtr cur,
(!xmlStrcasecmp(cur->name, BAD_CAST "src")) || (!xmlStrcasecmp(cur->name, BAD_CAST "src")) ||
((!xmlStrcasecmp(cur->name, BAD_CAST "name")) && ((!xmlStrcasecmp(cur->name, BAD_CAST "name")) &&
(!xmlStrcasecmp(cur->parent->name, BAD_CAST "a"))))) { (!xmlStrcasecmp(cur->parent->name, BAD_CAST "a"))))) {
xmlChar *escaped;
xmlChar *tmp = value; xmlChar *tmp = value;
/* xmlURIEscapeStr() escapes '"' so it can be safely used. */
xmlBufCCat(buf->buffer, "\"");
while (IS_BLANK_CH(*tmp)) tmp++; while (IS_BLANK_CH(*tmp)) tmp++;
/* URI Escape everything, except server side includes. */ /*
for ( ; ; ) { * the < and > have already been escaped at the entity level
xmlChar *escaped; * And doing so here breaks server side includes
xmlChar endChar; */
xmlChar *end = NULL; escaped = xmlURIEscapeStr(tmp, BAD_CAST"@/:=?;#%&,+<>");
xmlChar *start = (xmlChar *)xmlStrstr(tmp, BAD_CAST "<!--"); if (escaped != NULL) {
if (start != NULL) { xmlBufWriteQuotedString(buf->buffer, escaped);
end = (xmlChar *)xmlStrstr(tmp, BAD_CAST "-->"); xmlFree(escaped);
if (end != NULL) { } else {
*start = '\0'; xmlBufWriteQuotedString(buf->buffer, value);
}
}
/* Escape the whole string, or until start (set to '\0'). */
escaped = xmlURIEscapeStr(tmp, BAD_CAST"@/:=?;#%&,+");
if (escaped != NULL) {
xmlBufCat(buf->buffer, escaped);
xmlFree(escaped);
} else {
xmlBufCat(buf->buffer, tmp);
}
if (end == NULL) { /* Everything has been written. */
break;
}
/* Do not escape anything within server side includes. */
*start = '<'; /* Restore the first character of "<!--". */
end += 3; /* strlen("-->") */
endChar = *end;
*end = '\0';
xmlBufCat(buf->buffer, start);
*end = endChar;
tmp = end;
} }
xmlBufCCat(buf->buffer, "\"");
} else { } else {
xmlBufWriteQuotedString(buf->buffer, value); xmlBufWriteQuotedString(buf->buffer, value);
} }