malloc-fail: Fix memory leak in xmlXIncludeLoadTxt

Found with libFuzzer, see #344.
This commit is contained in:
Nick Wellnhofer 2023-02-16 12:40:02 +01:00
parent c02df68651
commit ec05f04d8b

View File

@ -1633,14 +1633,15 @@ static int
xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url,
xmlXIncludeRefPtr ref) { xmlXIncludeRefPtr ref) {
xmlParserInputBufferPtr buf; xmlParserInputBufferPtr buf;
xmlNodePtr node; xmlNodePtr node = NULL;
xmlURIPtr uri; xmlURIPtr uri = NULL;
xmlChar *URL; xmlChar *URL = NULL;
int i; int i;
int ret = -1;
xmlChar *encoding = NULL; xmlChar *encoding = NULL;
xmlCharEncoding enc = (xmlCharEncoding) 0; xmlCharEncoding enc = (xmlCharEncoding) 0;
xmlParserCtxtPtr pctxt; xmlParserCtxtPtr pctxt = NULL;
xmlParserInputPtr inputStream; xmlParserInputPtr inputStream = NULL;
int len; int len;
const xmlChar *content; const xmlChar *content;
@ -1656,21 +1657,19 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url,
if (uri == NULL) { if (uri == NULL) {
xmlXIncludeErr(ctxt, ref->elem, XML_XINCLUDE_HREF_URI, xmlXIncludeErr(ctxt, ref->elem, XML_XINCLUDE_HREF_URI,
"invalid value URI %s\n", url); "invalid value URI %s\n", url);
return(-1); goto error;
} }
if (uri->fragment != NULL) { if (uri->fragment != NULL) {
xmlXIncludeErr(ctxt, ref->elem, XML_XINCLUDE_TEXT_FRAGMENT, xmlXIncludeErr(ctxt, ref->elem, XML_XINCLUDE_TEXT_FRAGMENT,
"fragment identifier forbidden for text: %s\n", "fragment identifier forbidden for text: %s\n",
(const xmlChar *) uri->fragment); (const xmlChar *) uri->fragment);
xmlFreeURI(uri); goto error;
return(-1);
} }
URL = xmlSaveUri(uri); URL = xmlSaveUri(uri);
xmlFreeURI(uri);
if (URL == NULL) { if (URL == NULL) {
xmlXIncludeErr(ctxt, ref->elem, XML_XINCLUDE_HREF_URI, xmlXIncludeErr(ctxt, ref->elem, XML_XINCLUDE_HREF_URI,
"invalid value URI %s\n", url); "invalid value URI %s\n", url);
return(-1); goto error;
} }
/* /*
@ -1680,8 +1679,7 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url,
if (URL[0] == 0) { if (URL[0] == 0) {
xmlXIncludeErr(ctxt, ref->elem, XML_XINCLUDE_TEXT_DOCUMENT, xmlXIncludeErr(ctxt, ref->elem, XML_XINCLUDE_TEXT_DOCUMENT,
"text serialization of document not available\n", NULL); "text serialization of document not available\n", NULL);
xmlFree(URL); goto error;
return(-1);
} }
/* /*
@ -1711,11 +1709,8 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url,
if (enc == XML_CHAR_ENCODING_ERROR) { if (enc == XML_CHAR_ENCODING_ERROR) {
xmlXIncludeErr(ctxt, ref->elem, XML_XINCLUDE_UNKNOWN_ENCODING, xmlXIncludeErr(ctxt, ref->elem, XML_XINCLUDE_UNKNOWN_ENCODING,
"encoding %s not supported\n", encoding); "encoding %s not supported\n", encoding);
xmlFree(encoding); goto error;
xmlFree(URL);
return(-1);
} }
xmlFree(encoding);
} }
/* /*
@ -1723,27 +1718,18 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url,
*/ */
pctxt = xmlNewParserCtxt(); pctxt = xmlNewParserCtxt();
inputStream = xmlLoadExternalEntity((const char*)URL, NULL, pctxt); inputStream = xmlLoadExternalEntity((const char*)URL, NULL, pctxt);
if(inputStream == NULL) { if(inputStream == NULL)
xmlFreeParserCtxt(pctxt); goto error;
xmlFree(URL);
return(-1);
}
buf = inputStream->buf; buf = inputStream->buf;
if (buf == NULL) { if (buf == NULL)
xmlFreeInputStream (inputStream); goto error;
xmlFreeParserCtxt(pctxt);
xmlFree(URL);
return(-1);
}
if (buf->encoder) if (buf->encoder)
xmlCharEncCloseFunc(buf->encoder); xmlCharEncCloseFunc(buf->encoder);
buf->encoder = xmlGetCharEncodingHandler(enc); buf->encoder = xmlGetCharEncodingHandler(enc);
node = xmlNewDocText(ctxt->doc, NULL); node = xmlNewDocText(ctxt->doc, NULL);
if (node == NULL) { if (node == NULL) {
xmlFreeInputStream(inputStream); xmlXIncludeErrMemory(ctxt, ref->elem, NULL);
xmlFreeParserCtxt(pctxt); goto error;
xmlFree(URL);
return(-1);
} }
/* /*
@ -1762,19 +1748,13 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url,
if (!IS_CHAR(cur)) { if (!IS_CHAR(cur)) {
xmlXIncludeErr(ctxt, ref->elem, XML_XINCLUDE_INVALID_CHAR, xmlXIncludeErr(ctxt, ref->elem, XML_XINCLUDE_INVALID_CHAR,
"%s contains invalid char\n", URL); "%s contains invalid char\n", URL);
xmlFreeNode(node); goto error;
xmlFreeInputStream(inputStream);
xmlFreeParserCtxt(pctxt);
xmlFree(URL);
return(-1);
} }
i += l; i += l;
} }
xmlNodeAddContentLen(node, content, len); xmlNodeAddContentLen(node, content, len);
xmlFreeParserCtxt(pctxt);
xmlFreeInputStream(inputStream);
if (ctxt->txtNr >= ctxt->txtMax) { if (ctxt->txtNr >= ctxt->txtMax) {
xmlXIncludeTxt *tmp; xmlXIncludeTxt *tmp;
@ -1784,7 +1764,7 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url,
if (tmp == NULL) { if (tmp == NULL) {
xmlXIncludeErrMemory(ctxt, ref->elem, xmlXIncludeErrMemory(ctxt, ref->elem,
"growing XInclude text table"); "growing XInclude text table");
return(-1); goto error;
} }
ctxt->txtMax = newSize; ctxt->txtMax = newSize;
ctxt->txtTab = tmp; ctxt->txtTab = tmp;
@ -1798,8 +1778,17 @@ loaded:
* Add the element as the replacement copy. * Add the element as the replacement copy.
*/ */
ref->inc = node; ref->inc = node;
node = NULL;
ret = 0;
error:
xmlFreeNode(node);
xmlFreeInputStream(inputStream);
xmlFreeParserCtxt(pctxt);
xmlFree(encoding);
xmlFreeURI(uri);
xmlFree(URL); xmlFree(URL);
return(0); return(ret);
} }
/** /**