[libxslt] Avoid quadratic behavior in xsltSaveResultTo



commit 8a5dcc6e9da769bb49ce6a750cc0ef094d621b43
Author: Nick Wellnhofer <wellnhofer aevum de>
Date:   Fri May 10 14:23:24 2019 +0200

    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.

 libxslt/xsltutils.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)
---
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);
     }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]