[libxml2] Properly handle nested documents in xmlFreeNode



commit ea53fc18bccd88a5a010e63bf5d94b2f3f7a6fc8
Author: Nick Wellnhofer <wellnhofer aevum de>
Date:   Mon Feb 7 18:24:03 2022 +0100

    Properly handle nested documents in xmlFreeNode
    
    Client code should never add document nodes as children of other nodes,
    but even our own XPointer code has a bug that can produce such trees.
    Make sure to really free nested documents. Also see commits 0815302d
    and 0762c9b6.
    
    Should fix #269.

 tree.c | 26 ++++++++++++--------------
 1 file changed, 12 insertions(+), 14 deletions(-)
---
diff --git a/tree.c b/tree.c
index 50b6763b..96d3f324 100644
--- a/tree.c
+++ b/tree.c
@@ -3695,17 +3695,14 @@ xmlFreeNodeList(xmlNodePtr cur) {
        xmlFreeNsList((xmlNsPtr) cur);
        return;
     }
-    if ((cur->type == XML_DOCUMENT_NODE) ||
-#ifdef LIBXML_DOCB_ENABLED
-       (cur->type == XML_DOCB_DOCUMENT_NODE) ||
-#endif
-       (cur->type == XML_HTML_DOCUMENT_NODE)) {
-       xmlFreeDoc((xmlDocPtr) cur);
-       return;
-    }
     if (cur->doc != NULL) dict = cur->doc->dict;
     while (1) {
         while ((cur->children != NULL) &&
+               (cur->type != XML_DOCUMENT_NODE) &&
+#ifdef LIBXML_DOCB_ENABLED
+               (cur->type != XML_DOCB_DOCUMENT_NODE) &&
+#endif
+               (cur->type != XML_HTML_DOCUMENT_NODE) &&
                (cur->type != XML_DTD_NODE) &&
                (cur->type != XML_ENTITY_REF_NODE)) {
             cur = cur->children;
@@ -3714,7 +3711,13 @@ xmlFreeNodeList(xmlNodePtr cur) {
 
         next = cur->next;
         parent = cur->parent;
-       if (cur->type != XML_DTD_NODE) {
+       if ((cur->type == XML_DOCUMENT_NODE) ||
+#ifdef LIBXML_DOCB_ENABLED
+            (cur->type == XML_DOCB_DOCUMENT_NODE) ||
+#endif
+            (cur->type == XML_HTML_DOCUMENT_NODE)) {
+            xmlFreeDoc((xmlDocPtr) cur);
+        } else if (cur->type != XML_DTD_NODE) {
 
            if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))
                xmlDeregisterNodeDefaultValue(cur);
@@ -3728,11 +3731,6 @@ xmlFreeNodeList(xmlNodePtr cur) {
                (cur->type != XML_XINCLUDE_START) &&
                (cur->type != XML_XINCLUDE_END) &&
                (cur->type != XML_ENTITY_REF_NODE) &&
-               (cur->type != XML_DOCUMENT_NODE) &&
-#ifdef LIBXML_DOCB_ENABLED
-               (cur->type != XML_DOCB_DOCUMENT_NODE) &&
-#endif
-               (cur->type != XML_HTML_DOCUMENT_NODE) &&
                (cur->content != (xmlChar *) &(cur->properties))) {
                DICT_FREE(cur->content)
            }


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