1From d39f78069dff496ec865c73aa44d7110e429bce9 Mon Sep 17 00:00:00 2001
2From: Nick Wellnhofer <wellnhofer@aevum.de>
3Date: Wed, 23 Aug 2023 20:24:24 +0200
4Subject: [PATCH] tree: Fix copying of DTDs
5
6- Don't create multiple DTD nodes.
7- Fix UAF if malloc fails.
8- Skip DTD nodes if tree module is disabled.
9
10Fixes #583.
11---
12 tree.c | 31 ++++++++++++++++---------------
13 1 file changed, 16 insertions(+), 15 deletions(-)
14
15diff --git a/tree.c b/tree.c
16index 6c8a875b..02c1b579 100644
17--- a/tree.c
18+++ b/tree.c
19@@ -4386,29 +4386,28 @@ xmlNodePtr
20 xmlStaticCopyNodeList(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent) {
21     xmlNodePtr ret = NULL;
22     xmlNodePtr p = NULL,q;
23+    xmlDtdPtr newSubset = NULL;
24 
25     while (node != NULL) {
26-#ifdef LIBXML_TREE_ENABLED
27 	if (node->type == XML_DTD_NODE ) {
28-	    if (doc == NULL) {
29+#ifdef LIBXML_TREE_ENABLED
30+	    if ((doc == NULL) || (doc->intSubset != NULL)) {
31 		node = node->next;
32 		continue;
33 	    }
34-	    if (doc->intSubset == NULL) {
35-		q = (xmlNodePtr) xmlCopyDtd( (xmlDtdPtr) node );
36-		if (q == NULL) goto error;
37-		q->doc = doc;
38-		q->parent = parent;
39-		doc->intSubset = (xmlDtdPtr) q;
40-		xmlAddChild(parent, q);
41-	    } else {
42-		q = (xmlNodePtr) doc->intSubset;
43-		xmlAddChild(parent, q);
44-	    }
45-	} else
46+            q = (xmlNodePtr) xmlCopyDtd( (xmlDtdPtr) node );
47+            if (q == NULL) goto error;
48+            q->doc = doc;
49+            q->parent = parent;
50+            newSubset = (xmlDtdPtr) q;
51+#else
52+            node = node->next;
53+            continue;
54 #endif /* LIBXML_TREE_ENABLED */
55+	} else {
56 	    q = xmlStaticCopyNode(node, doc, parent, 1);
57-	if (q == NULL) goto error;
58+	    if (q == NULL) goto error;
59+        }
60 	if (ret == NULL) {
61 	    q->prev = NULL;
62 	    ret = p = q;
63@@ -4420,6 +4419,8 @@ xmlStaticCopyNodeList(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent) {
64 	}
65 	node = node->next;
66     }
67+    if (newSubset != NULL)
68+        doc->intSubset = newSubset;
69     return(ret);
70 error:
71     xmlFreeNodeList(ret);
72-- 
732.27.0
74
75