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