From e20f4d7a656e47553f9da9d594e299e2fa2dbe41 Mon Sep 17 00:00:00 2001 From: Nick Wellnhofer Date: Mon, 13 Feb 2023 14:38:05 +0100 Subject: [PATCH] xinclude: Fix quadratic behavior in xmlXIncludeLoadTxt Also make text inclusions work with memory buffers, for example when using a custom entity loader, and fix a memory leak in case of invalid characters. Fixes #483. Reference:https://github.com/GNOME/libxml2/commit/e20f4d7a656e47553f9da9d594e299e2fa2dbe41 Conflict:NA --- result/XInclude/invalid_char.xml.err | 2 + result/XInclude/invalid_char.xml.rdr | 7 ++++ test/XInclude/docs/invalid_char.xml | 3 ++ test/XInclude/ents/invalid_char.txt | 1 + xinclude.c | 61 ++++++++++++---------------- 5 files changed, 39 insertions(+), 35 deletions(-) create mode 100644 result/XInclude/invalid_char.xml.err create mode 100644 result/XInclude/invalid_char.xml.rdr create mode 100644 test/XInclude/docs/invalid_char.xml create mode 100644 test/XInclude/ents/invalid_char.txt diff --git a/result/XInclude/invalid_char.xml.err b/result/XInclude/invalid_char.xml.err new file mode 100644 index 0000000..c28c109 --- /dev/null +++ b/result/XInclude/invalid_char.xml.err @@ -0,0 +1,2 @@ +./test/XInclude/docs/invalid_char.xml:2: element include: XInclude error : test/XInclude/ents/invalid_char.txt contains invalid char +./test/XInclude/docs/invalid_char.xml:2: element include: XInclude error : could not load test/XInclude/ents/invalid_char.txt, and no fallback was found diff --git a/result/XInclude/invalid_char.xml.rdr b/result/XInclude/invalid_char.xml.rdr new file mode 100644 index 0000000..1fb5774 --- /dev/null +++ b/result/XInclude/invalid_char.xml.rdr @@ -0,0 +1,7 @@ +0 1 x 0 0 +1 14 #text 0 1 + +1 1 xinclude:include 1 0 +1 14 #text 0 1 + +0 15 x 0 0 diff --git a/test/XInclude/docs/invalid_char.xml b/test/XInclude/docs/invalid_char.xml new file mode 100644 index 0000000..28e5a48 --- /dev/null +++ b/test/XInclude/docs/invalid_char.xml @@ -0,0 +1,3 @@ + + + diff --git a/test/XInclude/ents/invalid_char.txt b/test/XInclude/ents/invalid_char.txt new file mode 100644 index 0000000..ae06618 --- /dev/null +++ b/test/XInclude/ents/invalid_char.txt @@ -0,0 +1 @@ +invalid: ÿ \ No newline at end of file diff --git a/xinclude.c b/xinclude.c index cc486f5..6e5b61d 100644 --- a/xinclude.c +++ b/xinclude.c @@ -1798,7 +1798,9 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) { xmlCharEncoding enc = (xmlCharEncoding) 0; xmlParserCtxtPtr pctxt; xmlParserInputPtr inputStream; - int xinclude_multibyte_fallback_used = 0; + int len; + const xmlChar *content; + /* Don't read from stdin. */ if (xmlStrcmp(url, BAD_CAST "-") == 0) @@ -1905,41 +1907,30 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) { /* * Scan all chars from the resource and add the to the node */ -xinclude_multibyte_fallback: - while (xmlParserInputBufferRead(buf, 128) > 0) { - int len; - const xmlChar *content; - - content = xmlBufContent(buf->buffer); - len = xmlBufLength(buf->buffer); - for (i = 0;i < len;) { - int cur; - int l; - - cur = xmlStringCurrentChar(NULL, &content[i], &l); - if (!IS_CHAR(cur)) { - /* Handle split multibyte char at buffer boundary */ - if (((len - i) < 4) && (!xinclude_multibyte_fallback_used)) { - xinclude_multibyte_fallback_used = 1; - xmlBufShrink(buf->buffer, i); - goto xinclude_multibyte_fallback; - } else { - xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, - XML_XINCLUDE_INVALID_CHAR, - "%s contains invalid char\n", URL); - xmlFreeParserCtxt(pctxt); - xmlFreeParserInputBuffer(buf); - xmlFree(URL); - return(-1); - } - } else { - xinclude_multibyte_fallback_used = 0; - xmlNodeAddContentLen(node, &content[i], l); - } - i += l; - } - xmlBufShrink(buf->buffer, len); + while (xmlParserInputBufferRead(buf, 4096) > 0) + ; + + content = xmlBufContent(buf->buffer); + len = xmlBufLength(buf->buffer); + for (i = 0; i < len;) { + int cur; + int l; + + cur = xmlStringCurrentChar(NULL, &content[i], &l); + if (!IS_CHAR(cur)) { + xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, XML_XINCLUDE_INVALID_CHAR, + "%s contains invalid char\n", URL); + xmlFreeNode(node); + xmlFreeInputStream(inputStream); + xmlFreeParserCtxt(pctxt); + xmlFree(URL); + return(-1); + } + + i += l; } + + xmlNodeAddContentLen(node, content, len); xmlFreeParserCtxt(pctxt); xmlXIncludeAddTxt(ctxt, node->content, URL); xmlFreeInputStream(inputStream); -- 2.27.0