summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Wellnhofer <wellnhofer@aevum.de>2019-05-10 14:23:24 +0200
committerNick Wellnhofer <wellnhofer@aevum.de>2019-05-10 14:33:29 +0200
commit8a5dcc6e9da769bb49ce6a750cc0ef094d621b43 (patch)
tree498a5c22d7c8943616b3d0855ea55a3646380b09
parent311da8c8864e4f4f838434d769e0644cc02c9da9 (diff)
downloadlibxslt-8a5dcc6e9da769bb49ce6a750cc0ef094d621b43.tar.gz
Avoid quadratic behavior in xsltSaveResultTo
xmlNodeDumpOutput tries to detect XHTML documents and calls xmlGetIntSubset which iterates the children of the result document fragment again, leading to quadratic behavior. Unfortunately, there's no way to tell xmlNodeDumpOutput which serialization mode to use and skip auto-detection. The xmlsave API has such an option, but it lacks a function to create an xmlSaveCtxt from an existing xmlOutputBuffer. Temporarily set result->children to NULL. This works because the internal subset is always available from result->intSubset. Found by OSS-Fuzz.
-rw-r--r--libxslt/xsltutils.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/libxslt/xsltutils.c b/libxslt/xsltutils.c
index 61f5c25d..5e957876 100644
--- a/libxslt/xsltutils.c
+++ b/libxslt/xsltutils.c
@@ -1578,7 +1578,15 @@ xsltSaveResultTo(xmlOutputBufferPtr buf, xmlDocPtr result,
xmlOutputBufferWriteString(buf, "?>\n");
}
if (result->children != NULL) {
- xmlNodePtr child = result->children;
+ xmlNodePtr children = result->children;
+ xmlNodePtr child = children;
+
+ /*
+ * Hack to avoid quadratic behavior when scanning
+ * result->children in xmlGetIntSubset called by
+ * xmlNodeDumpOutput.
+ */
+ result->children = NULL;
while (child != NULL) {
xmlNodeDumpOutput(buf, result, child, 0, (indent == 1),
@@ -1591,6 +1599,8 @@ xsltSaveResultTo(xmlOutputBufferPtr buf, xmlDocPtr result,
}
if (indent)
xmlOutputBufferWriteString(buf, "\n");
+
+ result->children = children;
}
xmlOutputBufferFlush(buf);
}