Do not URI escape in server side includes · GNOME/libxml2@960f0e2
@@ -716,22 +716,49 @@ htmlAttrDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlAttrPtr cur,
716716 (!xmlStrcasecmp(cur->name, BAD_CAST "src")) ||
717717 ((!xmlStrcasecmp(cur->name, BAD_CAST "name")) &&
718718 (!xmlStrcasecmp(cur->parent->name, BAD_CAST "a"))))) {
719-xmlChar *escaped;
720719xmlChar *tmp = value;
720+/* xmlURIEscapeStr() escapes '"' so it can be safely used. */
721+xmlBufCCat(buf->buffer, "\"");
721722722723while (IS_BLANK_CH(*tmp)) tmp++;
723724724-/*
725- * the < and > have already been escaped at the entity level
726- * And doing so here breaks server side includes
727- */
728-escaped = xmlURIEscapeStr(tmp, BAD_CAST"@/:=?;#%&,+<>");
729-if (escaped != NULL) {
730-xmlBufWriteQuotedString(buf->buffer, escaped);
731-xmlFree(escaped);
732- } else {
733-xmlBufWriteQuotedString(buf->buffer, value);
725+/* URI Escape everything, except server side includes. */
726+for ( ; ; ) {
727+xmlChar *escaped;
728+xmlChar endChar;
729+xmlChar *end = NULL;
730+xmlChar *start = (xmlChar *)xmlStrstr(tmp, BAD_CAST "<!--");
731+if (start != NULL) {
732+end = (xmlChar *)xmlStrstr(tmp, BAD_CAST "-->");
733+if (end != NULL) {
734+*start = '\0';
735+ }
736+ }
737+738+/* Escape the whole string, or until start (set to '\0'). */
739+escaped = xmlURIEscapeStr(tmp, BAD_CAST"@/:=?;#%&,+");
740+if (escaped != NULL) {
741+xmlBufCat(buf->buffer, escaped);
742+xmlFree(escaped);
743+ } else {
744+xmlBufCat(buf->buffer, tmp);
745+ }
746+747+if (end == NULL) { /* Everything has been written. */
748+break;
749+ }
750+751+/* Do not escape anything within server side includes. */
752+*start = '<'; /* Restore the first character of "<!--". */
753+end += 3; /* strlen("-->") */
754+endChar = *end;
755+*end = '\0';
756+xmlBufCat(buf->buffer, start);
757+*end = endChar;
758+tmp = end;
734759 }
760+761+xmlBufCCat(buf->buffer, "\"");
735762 } else {
736763xmlBufWriteQuotedString(buf->buffer, value);
737764 }