153aa9179Sopenharmony_ciFrom 2fbf7876510dd9c5996151e2569078146e869697 Mon Sep 17 00:00:00 2001
253aa9179Sopenharmony_ciFrom: Nick Wellnhofer <wellnhofer@aevum.de>
353aa9179Sopenharmony_ciDate: Wed, 2 Nov 2022 16:22:54 +0100
453aa9179Sopenharmony_ciSubject: [PATCH 12/28] malloc-fail: Fix memory leak in xmlStringGetNodeList
553aa9179Sopenharmony_ci
653aa9179Sopenharmony_ciAlso make sure to return NULL on error instead of a partial node list.
753aa9179Sopenharmony_ci
853aa9179Sopenharmony_ciFound with libFuzzer, see #344.
953aa9179Sopenharmony_ci
1053aa9179Sopenharmony_ciReference: https://github.com/GNOME/libxml2/commit/b45927095e0c857b68a96466e3075d60a6a5dd9e
1153aa9179Sopenharmony_ciConflict: NA
1253aa9179Sopenharmony_ci---
1353aa9179Sopenharmony_ci tree.c | 36 ++++++++++++++++++------------------
1453aa9179Sopenharmony_ci 1 file changed, 18 insertions(+), 18 deletions(-)
1553aa9179Sopenharmony_ci
1653aa9179Sopenharmony_cidiff --git a/tree.c b/tree.c
1753aa9179Sopenharmony_ciindex bb85220..ac156e1 100644
1853aa9179Sopenharmony_ci--- a/tree.c
1953aa9179Sopenharmony_ci+++ b/tree.c
2053aa9179Sopenharmony_ci@@ -1496,9 +1496,9 @@ out:
2153aa9179Sopenharmony_ci  */
2253aa9179Sopenharmony_ci xmlNodePtr
2353aa9179Sopenharmony_ci xmlStringGetNodeList(const xmlDoc *doc, const xmlChar *value) {
2453aa9179Sopenharmony_ci-    xmlNodePtr ret = NULL, last = NULL;
2553aa9179Sopenharmony_ci+    xmlNodePtr ret = NULL, head = NULL, last = NULL;
2653aa9179Sopenharmony_ci     xmlNodePtr node;
2753aa9179Sopenharmony_ci-    xmlChar *val;
2853aa9179Sopenharmony_ci+    xmlChar *val = NULL;
2953aa9179Sopenharmony_ci     const xmlChar *cur = value;
3053aa9179Sopenharmony_ci     const xmlChar *q;
3153aa9179Sopenharmony_ci     xmlEntityPtr ent;
3253aa9179Sopenharmony_ci@@ -1596,14 +1596,12 @@ xmlStringGetNodeList(const xmlDoc *doc, const xmlChar *value) {
3353aa9179Sopenharmony_ci 			 */
3453aa9179Sopenharmony_ci 			if (!xmlBufIsEmpty(buf)) {
3553aa9179Sopenharmony_ci 			    node = xmlNewDocText(doc, NULL);
3653aa9179Sopenharmony_ci-			    if (node == NULL) {
3753aa9179Sopenharmony_ci-				if (val != NULL) xmlFree(val);
3853aa9179Sopenharmony_ci-				goto out;
3953aa9179Sopenharmony_ci-			    }
4053aa9179Sopenharmony_ci+                            if (node == NULL)
4153aa9179Sopenharmony_ci+                                goto out;
4253aa9179Sopenharmony_ci 			    node->content = xmlBufDetach(buf);
4353aa9179Sopenharmony_ci 
4453aa9179Sopenharmony_ci 			    if (last == NULL) {
4553aa9179Sopenharmony_ci-				last = ret = node;
4653aa9179Sopenharmony_ci+				last = head = node;
4753aa9179Sopenharmony_ci 			    } else {
4853aa9179Sopenharmony_ci 				last = xmlAddNextSibling(last, node);
4953aa9179Sopenharmony_ci 			    }
5053aa9179Sopenharmony_ci@@ -1613,11 +1611,9 @@ xmlStringGetNodeList(const xmlDoc *doc, const xmlChar *value) {
5153aa9179Sopenharmony_ci 			 * Create a new REFERENCE_REF node
5253aa9179Sopenharmony_ci 			 */
5353aa9179Sopenharmony_ci 			node = xmlNewReference(doc, val);
5453aa9179Sopenharmony_ci-			if (node == NULL) {
5553aa9179Sopenharmony_ci-			    if (val != NULL) xmlFree(val);
5653aa9179Sopenharmony_ci+			if (node == NULL)
5753aa9179Sopenharmony_ci 			    goto out;
5853aa9179Sopenharmony_ci-			}
5953aa9179Sopenharmony_ci-			else if ((ent != NULL) && (ent->children == NULL)) {
6053aa9179Sopenharmony_ci+			if ((ent != NULL) && (ent->children == NULL)) {
6153aa9179Sopenharmony_ci 			    xmlNodePtr temp;
6253aa9179Sopenharmony_ci 
6353aa9179Sopenharmony_ci                             /* Set to non-NULL value to avoid recursion. */
6453aa9179Sopenharmony_ci@@ -1633,12 +1629,13 @@ xmlStringGetNodeList(const xmlDoc *doc, const xmlChar *value) {
6553aa9179Sopenharmony_ci 			    }
6653aa9179Sopenharmony_ci 			}
6753aa9179Sopenharmony_ci 			if (last == NULL) {
6853aa9179Sopenharmony_ci-			    last = ret = node;
6953aa9179Sopenharmony_ci+			    last = head = node;
7053aa9179Sopenharmony_ci 			} else {
7153aa9179Sopenharmony_ci 			    last = xmlAddNextSibling(last, node);
7253aa9179Sopenharmony_ci 			}
7353aa9179Sopenharmony_ci 		    }
7453aa9179Sopenharmony_ci 		    xmlFree(val);
7553aa9179Sopenharmony_ci+                    val = NULL;
7653aa9179Sopenharmony_ci 		}
7753aa9179Sopenharmony_ci 		cur++;
7853aa9179Sopenharmony_ci 		q = cur;
7953aa9179Sopenharmony_ci@@ -1657,7 +1654,7 @@ xmlStringGetNodeList(const xmlDoc *doc, const xmlChar *value) {
8053aa9179Sopenharmony_ci 	} else
8153aa9179Sopenharmony_ci 	    cur++;
8253aa9179Sopenharmony_ci     }
8353aa9179Sopenharmony_ci-    if ((cur != q) || (ret == NULL)) {
8453aa9179Sopenharmony_ci+    if ((cur != q) || (head == NULL)) {
8553aa9179Sopenharmony_ci         /*
8653aa9179Sopenharmony_ci 	 * Handle the last piece of text.
8753aa9179Sopenharmony_ci 	 */
8853aa9179Sopenharmony_ci@@ -1666,21 +1663,24 @@ xmlStringGetNodeList(const xmlDoc *doc, const xmlChar *value) {
8953aa9179Sopenharmony_ci 
9053aa9179Sopenharmony_ci     if (!xmlBufIsEmpty(buf)) {
9153aa9179Sopenharmony_ci 	node = xmlNewDocText(doc, NULL);
9253aa9179Sopenharmony_ci-        if (node == NULL) {
9353aa9179Sopenharmony_ci-            xmlBufFree(buf);
9453aa9179Sopenharmony_ci-            return(NULL);
9553aa9179Sopenharmony_ci-        }
9653aa9179Sopenharmony_ci+        if (node == NULL)
9753aa9179Sopenharmony_ci+            goto out;
9853aa9179Sopenharmony_ci 	node->content = xmlBufDetach(buf);
9953aa9179Sopenharmony_ci 
10053aa9179Sopenharmony_ci 	if (last == NULL) {
10153aa9179Sopenharmony_ci-	    ret = node;
10253aa9179Sopenharmony_ci+	    head = node;
10353aa9179Sopenharmony_ci 	} else {
10453aa9179Sopenharmony_ci 	    xmlAddNextSibling(last, node);
10553aa9179Sopenharmony_ci 	}
10653aa9179Sopenharmony_ci     }
10753aa9179Sopenharmony_ci 
10853aa9179Sopenharmony_ci+    ret = head;
10953aa9179Sopenharmony_ci+    head = NULL;
11053aa9179Sopenharmony_ci+
11153aa9179Sopenharmony_ci out:
11253aa9179Sopenharmony_ci     xmlBufFree(buf);
11353aa9179Sopenharmony_ci+    if (val != NULL) xmlFree(val);
11453aa9179Sopenharmony_ci+    if (head != NULL) xmlFreeNodeList(head);
11553aa9179Sopenharmony_ci     return(ret);
11653aa9179Sopenharmony_ci }
11753aa9179Sopenharmony_ci 
11853aa9179Sopenharmony_ci-- 
11953aa9179Sopenharmony_ci2.27.0
12053aa9179Sopenharmony_ci
121