1From ec05f04d8b5a0a60515235f65ed1256644a77741 Mon Sep 17 00:00:00 2001
2From: Nick Wellnhofer <wellnhofer@aevum.de>
3Date: Thu, 16 Feb 2023 12:40:02 +0100
4Subject: [PATCH] malloc-fail: Fix memory leak in xmlXIncludeLoadTxt
5
6Found with libFuzzer, see #344.
7
8Reference:https://github.com/GNOME/libxml2/commit/ec05f04d8b5a0a60515235f65ed1256644a77741
9Conflict:xinclude.c
10
11---
12 xinclude.c | 67 +++++++++++++++++++++++-------------------------------
13 1 file changed, 28 insertions(+), 39 deletions(-)
14
15diff --git a/xinclude.c b/xinclude.c
16index cc22848..c0b4439 100644
17--- a/xinclude.c
18+++ b/xinclude.c
19@@ -1791,14 +1791,15 @@ error:
20 static int
21 xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) {
22     xmlParserInputBufferPtr buf;
23-    xmlNodePtr node;
24-    xmlURIPtr uri;
25-    xmlChar *URL;
26+    xmlNodePtr node = NULL;
27+    xmlURIPtr uri = NULL;
28+    xmlChar *URL = NULL;
29     int i;
30+    int ret = -1;
31     xmlChar *encoding = NULL;
32     xmlCharEncoding enc = (xmlCharEncoding) 0;
33-    xmlParserCtxtPtr pctxt;
34-    xmlParserInputPtr inputStream;
35+    xmlParserCtxtPtr pctxt = NULL;
36+    xmlParserInputPtr inputStream = NULL;
37     int len;
38     const xmlChar *content;
39 
40@@ -1814,21 +1815,19 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) {
41     if (uri == NULL) {
42 	xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, XML_XINCLUDE_HREF_URI,
43 	               "invalid value URI %s\n", url);
44-	return(-1);
45+	goto error;
46     }
47     if (uri->fragment != NULL) {
48 	xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, XML_XINCLUDE_TEXT_FRAGMENT,
49 	               "fragment identifier forbidden for text: %s\n",
50 		       (const xmlChar *) uri->fragment);
51-	xmlFreeURI(uri);
52-	return(-1);
53+	goto error;
54     }
55     URL = xmlSaveUri(uri);
56-    xmlFreeURI(uri);
57     if (URL == NULL) {
58 	xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, XML_XINCLUDE_HREF_URI,
59 	               "invalid value URI %s\n", url);
60-	return(-1);
61+	goto error;
62     }
63 
64     /*
65@@ -1839,8 +1838,7 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) {
66 	xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref,
67 	               XML_XINCLUDE_TEXT_DOCUMENT,
68 		       "text serialization of document not available\n", NULL);
69-	xmlFree(URL);
70-	return(-1);
71+	goto error;
72     }
73 
74     /*
75@@ -1870,11 +1868,8 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) {
76 	    xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref,
77 	                   XML_XINCLUDE_UNKNOWN_ENCODING,
78 			   "encoding %s not supported\n", encoding);
79-	    xmlFree(encoding);
80-	    xmlFree(URL);
81-	    return(-1);
82+	    goto error;
83 	}
84-	xmlFree(encoding);
85     }
86 
87     /*
88@@ -1882,27 +1877,18 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) {
89      */
90     pctxt = xmlNewParserCtxt();
91     inputStream = xmlLoadExternalEntity((const char*)URL, NULL, pctxt);
92-    if(inputStream == NULL) {
93-	xmlFreeParserCtxt(pctxt);
94-	xmlFree(URL);
95-	return(-1);
96-    }
97+    if(inputStream == NULL)
98+	goto error;
99     buf = inputStream->buf;
100-    if (buf == NULL) {
101-	xmlFreeInputStream (inputStream);
102-	xmlFreeParserCtxt(pctxt);
103-	xmlFree(URL);
104-	return(-1);
105-    }
106+    if (buf == NULL)
107+	goto error;
108     if (buf->encoder)
109 	xmlCharEncCloseFunc(buf->encoder);
110     buf->encoder = xmlGetCharEncodingHandler(enc);
111     node = xmlNewText(NULL);
112     if (node == NULL) {
113-        xmlFreeInputStream(inputStream);
114-        xmlFreeParserCtxt(pctxt);
115-        xmlFree(URL);
116-        return(-1);
117+        xmlXIncludeErrMemory(ctxt, ctxt->incTab[nr]->ref, NULL);
118+	goto error;
119     }
120 
121     /*
122@@ -1921,28 +1907,31 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) {
123         if (!IS_CHAR(cur)) {
124             xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, XML_XINCLUDE_INVALID_CHAR,
125                            "%s contains invalid char\n", URL);
126-            xmlFreeNode(node);
127-            xmlFreeInputStream(inputStream);
128-            xmlFreeParserCtxt(pctxt);
129-            xmlFree(URL);
130-            return(-1);
131+            goto error;
132         }
133 
134         i += l;
135     }
136 
137     xmlNodeAddContentLen(node, content, len);
138-    xmlFreeParserCtxt(pctxt);
139     xmlXIncludeAddTxt(ctxt, node->content, URL);
140-    xmlFreeInputStream(inputStream);
141 
142 loaded:
143     /*
144      * Add the element as the replacement copy.
145      */
146     ctxt->incTab[nr]->inc = node;
147+    node = NULL;
148+    ret = 0;
149+
150+error:
151+    xmlFreeNode(node);
152+    xmlFreeInputStream(inputStream);
153+    xmlFreeParserCtxt(pctxt);
154+    xmlFree(encoding);
155+    xmlFreeURI(uri);
156     xmlFree(URL);
157-    return(0);
158+    return(ret);
159 }
160 
161 /**
162-- 
1632.27.0
164
165