1From 2fbf7876510dd9c5996151e2569078146e869697 Mon Sep 17 00:00:00 2001 2From: Nick Wellnhofer <wellnhofer@aevum.de> 3Date: Wed, 2 Nov 2022 16:22:54 +0100 4Subject: [PATCH 12/28] malloc-fail: Fix memory leak in xmlStringGetNodeList 5 6Also make sure to return NULL on error instead of a partial node list. 7 8Found with libFuzzer, see #344. 9 10Reference: https://github.com/GNOME/libxml2/commit/b45927095e0c857b68a96466e3075d60a6a5dd9e 11Conflict: NA 12--- 13 tree.c | 36 ++++++++++++++++++------------------ 14 1 file changed, 18 insertions(+), 18 deletions(-) 15 16diff --git a/tree.c b/tree.c 17index bb85220..ac156e1 100644 18--- a/tree.c 19+++ b/tree.c 20@@ -1496,9 +1496,9 @@ out: 21 */ 22 xmlNodePtr 23 xmlStringGetNodeList(const xmlDoc *doc, const xmlChar *value) { 24- xmlNodePtr ret = NULL, last = NULL; 25+ xmlNodePtr ret = NULL, head = NULL, last = NULL; 26 xmlNodePtr node; 27- xmlChar *val; 28+ xmlChar *val = NULL; 29 const xmlChar *cur = value; 30 const xmlChar *q; 31 xmlEntityPtr ent; 32@@ -1596,14 +1596,12 @@ xmlStringGetNodeList(const xmlDoc *doc, const xmlChar *value) { 33 */ 34 if (!xmlBufIsEmpty(buf)) { 35 node = xmlNewDocText(doc, NULL); 36- if (node == NULL) { 37- if (val != NULL) xmlFree(val); 38- goto out; 39- } 40+ if (node == NULL) 41+ goto out; 42 node->content = xmlBufDetach(buf); 43 44 if (last == NULL) { 45- last = ret = node; 46+ last = head = node; 47 } else { 48 last = xmlAddNextSibling(last, node); 49 } 50@@ -1613,11 +1611,9 @@ xmlStringGetNodeList(const xmlDoc *doc, const xmlChar *value) { 51 * Create a new REFERENCE_REF node 52 */ 53 node = xmlNewReference(doc, val); 54- if (node == NULL) { 55- if (val != NULL) xmlFree(val); 56+ if (node == NULL) 57 goto out; 58- } 59- else if ((ent != NULL) && (ent->children == NULL)) { 60+ if ((ent != NULL) && (ent->children == NULL)) { 61 xmlNodePtr temp; 62 63 /* Set to non-NULL value to avoid recursion. */ 64@@ -1633,12 +1629,13 @@ xmlStringGetNodeList(const xmlDoc *doc, const xmlChar *value) { 65 } 66 } 67 if (last == NULL) { 68- last = ret = node; 69+ last = head = node; 70 } else { 71 last = xmlAddNextSibling(last, node); 72 } 73 } 74 xmlFree(val); 75+ val = NULL; 76 } 77 cur++; 78 q = cur; 79@@ -1657,7 +1654,7 @@ xmlStringGetNodeList(const xmlDoc *doc, const xmlChar *value) { 80 } else 81 cur++; 82 } 83- if ((cur != q) || (ret == NULL)) { 84+ if ((cur != q) || (head == NULL)) { 85 /* 86 * Handle the last piece of text. 87 */ 88@@ -1666,21 +1663,24 @@ xmlStringGetNodeList(const xmlDoc *doc, const xmlChar *value) { 89 90 if (!xmlBufIsEmpty(buf)) { 91 node = xmlNewDocText(doc, NULL); 92- if (node == NULL) { 93- xmlBufFree(buf); 94- return(NULL); 95- } 96+ if (node == NULL) 97+ goto out; 98 node->content = xmlBufDetach(buf); 99 100 if (last == NULL) { 101- ret = node; 102+ head = node; 103 } else { 104 xmlAddNextSibling(last, node); 105 } 106 } 107 108+ ret = head; 109+ head = NULL; 110+ 111 out: 112 xmlBufFree(buf); 113+ if (val != NULL) xmlFree(val); 114+ if (head != NULL) xmlFreeNodeList(head); 115 return(ret); 116 } 117 118-- 1192.27.0 120 121