diff options
author | Nick Wellnhofer <wellnhofer@aevum.de> | 2019-05-10 14:23:24 +0200 |
---|---|---|
committer | Nick Wellnhofer <wellnhofer@aevum.de> | 2019-05-10 14:33:29 +0200 |
commit | 8a5dcc6e9da769bb49ce6a750cc0ef094d621b43 (patch) | |
tree | 498a5c22d7c8943616b3d0855ea55a3646380b09 | |
parent | 311da8c8864e4f4f838434d769e0644cc02c9da9 (diff) | |
download | libxslt-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.c | 12 |
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); } |