1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2025-01-29 21:46:59 +03:00

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.
This commit is contained in:
Nick Wellnhofer 2023-02-13 14:38:05 +01:00
parent a96312db51
commit e20f4d7a65
5 changed files with 37 additions and 32 deletions

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,3 @@
<x xmlns:xinclude="http://www.w3.org/2001/XInclude">
<xinclude:include href="../ents/invalid_char.txt" parse="text"/>
</x>

View File

@ -0,0 +1 @@
invalid: ÿ

View 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;
while (xmlParserInputBufferRead(buf, 4096) > 0)
;
content = xmlBufContent(buf->buffer);
len = xmlBufLength(buf->buffer);
for (i = 0;i < len;) {
int cur;
int l;
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);
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);