diff options
author | Nick Wellnhofer <wellnhofer@aevum.de> | 2023-02-13 14:38:05 +0100 |
---|---|---|
committer | Nick Wellnhofer <wellnhofer@aevum.de> | 2023-02-14 12:25:07 +0100 |
commit | e20f4d7a656e47553f9da9d594e299e2fa2dbe41 (patch) | |
tree | 7bacf4c73707b9c8f2bb965ed795055dd53e542b | |
parent | a96312db516b7ad9fb9a12560a680fa6d3fc3d9f (diff) | |
download | libxml2-e20f4d7a656e47553f9da9d594e299e2fa2dbe41.tar.gz |
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.
-rw-r--r-- | result/XInclude/invalid_char.xml.err | 2 | ||||
-rw-r--r-- | result/XInclude/invalid_char.xml.rdr | 7 | ||||
-rw-r--r-- | test/XInclude/docs/invalid_char.xml | 3 | ||||
-rw-r--r-- | test/XInclude/ents/invalid_char.txt | 1 | ||||
-rw-r--r-- | xinclude.c | 60 |
5 files changed, 39 insertions, 34 deletions
diff --git a/result/XInclude/invalid_char.xml.err b/result/XInclude/invalid_char.xml.err new file mode 100644 index 00000000..c28c1095 --- /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 00000000..1fb57744 --- /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 00000000..28e5a486 --- /dev/null +++ b/test/XInclude/docs/invalid_char.xml @@ -0,0 +1,3 @@ +<x xmlns:xinclude="http://www.w3.org/2001/XInclude"> + <xinclude:include href="../ents/invalid_char.txt" parse="text"/> +</x> diff --git a/test/XInclude/ents/invalid_char.txt b/test/XInclude/ents/invalid_char.txt new file mode 100644 index 00000000..ae066189 --- /dev/null +++ b/test/XInclude/ents/invalid_char.txt @@ -0,0 +1 @@ +invalid: ÿ
\ No newline at end of file @@ -1639,7 +1639,9 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, 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) @@ -1745,40 +1747,30 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, /* * 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, ref->elem, 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, ref->elem, 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); xmlFreeInputStream(inputStream); |