153aa9179Sopenharmony_ciFrom ec05f04d8b5a0a60515235f65ed1256644a77741 Mon Sep 17 00:00:00 2001
253aa9179Sopenharmony_ciFrom: Nick Wellnhofer <wellnhofer@aevum.de>
353aa9179Sopenharmony_ciDate: Thu, 16 Feb 2023 12:40:02 +0100
453aa9179Sopenharmony_ciSubject: [PATCH] malloc-fail: Fix memory leak in xmlXIncludeLoadTxt
553aa9179Sopenharmony_ci
653aa9179Sopenharmony_ciFound with libFuzzer, see #344.
753aa9179Sopenharmony_ci
853aa9179Sopenharmony_ciReference:https://github.com/GNOME/libxml2/commit/ec05f04d8b5a0a60515235f65ed1256644a77741
953aa9179Sopenharmony_ciConflict:xinclude.c
1053aa9179Sopenharmony_ci
1153aa9179Sopenharmony_ci---
1253aa9179Sopenharmony_ci xinclude.c | 67 +++++++++++++++++++++++-------------------------------
1353aa9179Sopenharmony_ci 1 file changed, 28 insertions(+), 39 deletions(-)
1453aa9179Sopenharmony_ci
1553aa9179Sopenharmony_cidiff --git a/xinclude.c b/xinclude.c
1653aa9179Sopenharmony_ciindex cc22848..c0b4439 100644
1753aa9179Sopenharmony_ci--- a/xinclude.c
1853aa9179Sopenharmony_ci+++ b/xinclude.c
1953aa9179Sopenharmony_ci@@ -1791,14 +1791,15 @@ error:
2053aa9179Sopenharmony_ci static int
2153aa9179Sopenharmony_ci xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) {
2253aa9179Sopenharmony_ci     xmlParserInputBufferPtr buf;
2353aa9179Sopenharmony_ci-    xmlNodePtr node;
2453aa9179Sopenharmony_ci-    xmlURIPtr uri;
2553aa9179Sopenharmony_ci-    xmlChar *URL;
2653aa9179Sopenharmony_ci+    xmlNodePtr node = NULL;
2753aa9179Sopenharmony_ci+    xmlURIPtr uri = NULL;
2853aa9179Sopenharmony_ci+    xmlChar *URL = NULL;
2953aa9179Sopenharmony_ci     int i;
3053aa9179Sopenharmony_ci+    int ret = -1;
3153aa9179Sopenharmony_ci     xmlChar *encoding = NULL;
3253aa9179Sopenharmony_ci     xmlCharEncoding enc = (xmlCharEncoding) 0;
3353aa9179Sopenharmony_ci-    xmlParserCtxtPtr pctxt;
3453aa9179Sopenharmony_ci-    xmlParserInputPtr inputStream;
3553aa9179Sopenharmony_ci+    xmlParserCtxtPtr pctxt = NULL;
3653aa9179Sopenharmony_ci+    xmlParserInputPtr inputStream = NULL;
3753aa9179Sopenharmony_ci     int len;
3853aa9179Sopenharmony_ci     const xmlChar *content;
3953aa9179Sopenharmony_ci 
4053aa9179Sopenharmony_ci@@ -1814,21 +1815,19 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) {
4153aa9179Sopenharmony_ci     if (uri == NULL) {
4253aa9179Sopenharmony_ci 	xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, XML_XINCLUDE_HREF_URI,
4353aa9179Sopenharmony_ci 	               "invalid value URI %s\n", url);
4453aa9179Sopenharmony_ci-	return(-1);
4553aa9179Sopenharmony_ci+	goto error;
4653aa9179Sopenharmony_ci     }
4753aa9179Sopenharmony_ci     if (uri->fragment != NULL) {
4853aa9179Sopenharmony_ci 	xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, XML_XINCLUDE_TEXT_FRAGMENT,
4953aa9179Sopenharmony_ci 	               "fragment identifier forbidden for text: %s\n",
5053aa9179Sopenharmony_ci 		       (const xmlChar *) uri->fragment);
5153aa9179Sopenharmony_ci-	xmlFreeURI(uri);
5253aa9179Sopenharmony_ci-	return(-1);
5353aa9179Sopenharmony_ci+	goto error;
5453aa9179Sopenharmony_ci     }
5553aa9179Sopenharmony_ci     URL = xmlSaveUri(uri);
5653aa9179Sopenharmony_ci-    xmlFreeURI(uri);
5753aa9179Sopenharmony_ci     if (URL == NULL) {
5853aa9179Sopenharmony_ci 	xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, XML_XINCLUDE_HREF_URI,
5953aa9179Sopenharmony_ci 	               "invalid value URI %s\n", url);
6053aa9179Sopenharmony_ci-	return(-1);
6153aa9179Sopenharmony_ci+	goto error;
6253aa9179Sopenharmony_ci     }
6353aa9179Sopenharmony_ci 
6453aa9179Sopenharmony_ci     /*
6553aa9179Sopenharmony_ci@@ -1839,8 +1838,7 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) {
6653aa9179Sopenharmony_ci 	xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref,
6753aa9179Sopenharmony_ci 	               XML_XINCLUDE_TEXT_DOCUMENT,
6853aa9179Sopenharmony_ci 		       "text serialization of document not available\n", NULL);
6953aa9179Sopenharmony_ci-	xmlFree(URL);
7053aa9179Sopenharmony_ci-	return(-1);
7153aa9179Sopenharmony_ci+	goto error;
7253aa9179Sopenharmony_ci     }
7353aa9179Sopenharmony_ci 
7453aa9179Sopenharmony_ci     /*
7553aa9179Sopenharmony_ci@@ -1870,11 +1868,8 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) {
7653aa9179Sopenharmony_ci 	    xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref,
7753aa9179Sopenharmony_ci 	                   XML_XINCLUDE_UNKNOWN_ENCODING,
7853aa9179Sopenharmony_ci 			   "encoding %s not supported\n", encoding);
7953aa9179Sopenharmony_ci-	    xmlFree(encoding);
8053aa9179Sopenharmony_ci-	    xmlFree(URL);
8153aa9179Sopenharmony_ci-	    return(-1);
8253aa9179Sopenharmony_ci+	    goto error;
8353aa9179Sopenharmony_ci 	}
8453aa9179Sopenharmony_ci-	xmlFree(encoding);
8553aa9179Sopenharmony_ci     }
8653aa9179Sopenharmony_ci 
8753aa9179Sopenharmony_ci     /*
8853aa9179Sopenharmony_ci@@ -1882,27 +1877,18 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) {
8953aa9179Sopenharmony_ci      */
9053aa9179Sopenharmony_ci     pctxt = xmlNewParserCtxt();
9153aa9179Sopenharmony_ci     inputStream = xmlLoadExternalEntity((const char*)URL, NULL, pctxt);
9253aa9179Sopenharmony_ci-    if(inputStream == NULL) {
9353aa9179Sopenharmony_ci-	xmlFreeParserCtxt(pctxt);
9453aa9179Sopenharmony_ci-	xmlFree(URL);
9553aa9179Sopenharmony_ci-	return(-1);
9653aa9179Sopenharmony_ci-    }
9753aa9179Sopenharmony_ci+    if(inputStream == NULL)
9853aa9179Sopenharmony_ci+	goto error;
9953aa9179Sopenharmony_ci     buf = inputStream->buf;
10053aa9179Sopenharmony_ci-    if (buf == NULL) {
10153aa9179Sopenharmony_ci-	xmlFreeInputStream (inputStream);
10253aa9179Sopenharmony_ci-	xmlFreeParserCtxt(pctxt);
10353aa9179Sopenharmony_ci-	xmlFree(URL);
10453aa9179Sopenharmony_ci-	return(-1);
10553aa9179Sopenharmony_ci-    }
10653aa9179Sopenharmony_ci+    if (buf == NULL)
10753aa9179Sopenharmony_ci+	goto error;
10853aa9179Sopenharmony_ci     if (buf->encoder)
10953aa9179Sopenharmony_ci 	xmlCharEncCloseFunc(buf->encoder);
11053aa9179Sopenharmony_ci     buf->encoder = xmlGetCharEncodingHandler(enc);
11153aa9179Sopenharmony_ci     node = xmlNewText(NULL);
11253aa9179Sopenharmony_ci     if (node == NULL) {
11353aa9179Sopenharmony_ci-        xmlFreeInputStream(inputStream);
11453aa9179Sopenharmony_ci-        xmlFreeParserCtxt(pctxt);
11553aa9179Sopenharmony_ci-        xmlFree(URL);
11653aa9179Sopenharmony_ci-        return(-1);
11753aa9179Sopenharmony_ci+        xmlXIncludeErrMemory(ctxt, ctxt->incTab[nr]->ref, NULL);
11853aa9179Sopenharmony_ci+	goto error;
11953aa9179Sopenharmony_ci     }
12053aa9179Sopenharmony_ci 
12153aa9179Sopenharmony_ci     /*
12253aa9179Sopenharmony_ci@@ -1921,28 +1907,31 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) {
12353aa9179Sopenharmony_ci         if (!IS_CHAR(cur)) {
12453aa9179Sopenharmony_ci             xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, XML_XINCLUDE_INVALID_CHAR,
12553aa9179Sopenharmony_ci                            "%s contains invalid char\n", URL);
12653aa9179Sopenharmony_ci-            xmlFreeNode(node);
12753aa9179Sopenharmony_ci-            xmlFreeInputStream(inputStream);
12853aa9179Sopenharmony_ci-            xmlFreeParserCtxt(pctxt);
12953aa9179Sopenharmony_ci-            xmlFree(URL);
13053aa9179Sopenharmony_ci-            return(-1);
13153aa9179Sopenharmony_ci+            goto error;
13253aa9179Sopenharmony_ci         }
13353aa9179Sopenharmony_ci 
13453aa9179Sopenharmony_ci         i += l;
13553aa9179Sopenharmony_ci     }
13653aa9179Sopenharmony_ci 
13753aa9179Sopenharmony_ci     xmlNodeAddContentLen(node, content, len);
13853aa9179Sopenharmony_ci-    xmlFreeParserCtxt(pctxt);
13953aa9179Sopenharmony_ci     xmlXIncludeAddTxt(ctxt, node->content, URL);
14053aa9179Sopenharmony_ci-    xmlFreeInputStream(inputStream);
14153aa9179Sopenharmony_ci 
14253aa9179Sopenharmony_ci loaded:
14353aa9179Sopenharmony_ci     /*
14453aa9179Sopenharmony_ci      * Add the element as the replacement copy.
14553aa9179Sopenharmony_ci      */
14653aa9179Sopenharmony_ci     ctxt->incTab[nr]->inc = node;
14753aa9179Sopenharmony_ci+    node = NULL;
14853aa9179Sopenharmony_ci+    ret = 0;
14953aa9179Sopenharmony_ci+
15053aa9179Sopenharmony_ci+error:
15153aa9179Sopenharmony_ci+    xmlFreeNode(node);
15253aa9179Sopenharmony_ci+    xmlFreeInputStream(inputStream);
15353aa9179Sopenharmony_ci+    xmlFreeParserCtxt(pctxt);
15453aa9179Sopenharmony_ci+    xmlFree(encoding);
15553aa9179Sopenharmony_ci+    xmlFreeURI(uri);
15653aa9179Sopenharmony_ci     xmlFree(URL);
15753aa9179Sopenharmony_ci-    return(0);
15853aa9179Sopenharmony_ci+    return(ret);
15953aa9179Sopenharmony_ci }
16053aa9179Sopenharmony_ci 
16153aa9179Sopenharmony_ci /**
16253aa9179Sopenharmony_ci-- 
16353aa9179Sopenharmony_ci2.27.0
16453aa9179Sopenharmony_ci
165