• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1From e20f4d7a656e47553f9da9d594e299e2fa2dbe41 Mon Sep 17 00:00:00 2001
2From: Nick Wellnhofer <wellnhofer@aevum.de>
3Date: Mon, 13 Feb 2023 14:38:05 +0100
4Subject: [PATCH] xinclude: Fix quadratic behavior in xmlXIncludeLoadTxt
5
6Also make text inclusions work with memory buffers, for example when
7using a custom entity loader, and fix a memory leak in case of invalid
8characters.
9
10Fixes #483.
11
12Reference:https://github.com/GNOME/libxml2/commit/e20f4d7a656e47553f9da9d594e299e2fa2dbe41
13Conflict:NA
14
15---
16 result/XInclude/invalid_char.xml.err |  2 +
17 result/XInclude/invalid_char.xml.rdr |  7 ++++
18 test/XInclude/docs/invalid_char.xml  |  3 ++
19 test/XInclude/ents/invalid_char.txt  |  1 +
20 xinclude.c                           | 61 ++++++++++++----------------
21 5 files changed, 39 insertions(+), 35 deletions(-)
22 create mode 100644 result/XInclude/invalid_char.xml.err
23 create mode 100644 result/XInclude/invalid_char.xml.rdr
24 create mode 100644 test/XInclude/docs/invalid_char.xml
25 create mode 100644 test/XInclude/ents/invalid_char.txt
26
27diff --git a/result/XInclude/invalid_char.xml.err b/result/XInclude/invalid_char.xml.err
28new file mode 100644
29index 0000000..c28c109
30--- /dev/null
31+++ b/result/XInclude/invalid_char.xml.err
32@@ -0,0 +1,2 @@
33+./test/XInclude/docs/invalid_char.xml:2: element include: XInclude error : test/XInclude/ents/invalid_char.txt contains invalid char
34+./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
35diff --git a/result/XInclude/invalid_char.xml.rdr b/result/XInclude/invalid_char.xml.rdr
36new file mode 100644
37index 0000000..1fb5774
38--- /dev/null
39+++ b/result/XInclude/invalid_char.xml.rdr
40@@ -0,0 +1,7 @@
41+0 1 x 0 0
42+1 14 #text 0 1
43+
44+1 1 xinclude:include 1 0
45+1 14 #text 0 1
46+
47+0 15 x 0 0
48diff --git a/test/XInclude/docs/invalid_char.xml b/test/XInclude/docs/invalid_char.xml
49new file mode 100644
50index 0000000..28e5a48
51--- /dev/null
52+++ b/test/XInclude/docs/invalid_char.xml
53@@ -0,0 +1,3 @@
54+<x xmlns:xinclude="http://www.w3.org/2001/XInclude">
55+   <xinclude:include href="../ents/invalid_char.txt" parse="text"/>
56+</x>
57diff --git a/test/XInclude/ents/invalid_char.txt b/test/XInclude/ents/invalid_char.txt
58new file mode 100644
59index 0000000..ae06618
60--- /dev/null
61+++ b/test/XInclude/ents/invalid_char.txt
62@@ -0,0 +1 @@
63+invalid: �
64\ No newline at end of file
65diff --git a/xinclude.c b/xinclude.c
66index cc486f5..6e5b61d 100644
67--- a/xinclude.c
68+++ b/xinclude.c
69@@ -1798,7 +1798,9 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) {
70     xmlCharEncoding enc = (xmlCharEncoding) 0;
71     xmlParserCtxtPtr pctxt;
72     xmlParserInputPtr inputStream;
73-    int xinclude_multibyte_fallback_used = 0;
74+    int len;
75+    const xmlChar *content;
76+
77
78     /* Don't read from stdin. */
79     if (xmlStrcmp(url, BAD_CAST "-") == 0)
80@@ -1905,41 +1907,30 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) {
81     /*
82      * Scan all chars from the resource and add the to the node
83      */
84-xinclude_multibyte_fallback:
85-    while (xmlParserInputBufferRead(buf, 128) > 0) {
86-	int len;
87-	const xmlChar *content;
88-
89-	content = xmlBufContent(buf->buffer);
90-	len = xmlBufLength(buf->buffer);
91-	for (i = 0;i < len;) {
92-	    int cur;
93-	    int l;
94-
95-	    cur = xmlStringCurrentChar(NULL, &content[i], &l);
96-	    if (!IS_CHAR(cur)) {
97-		/* Handle split multibyte char at buffer boundary */
98-		if (((len - i) < 4) && (!xinclude_multibyte_fallback_used)) {
99-		    xinclude_multibyte_fallback_used = 1;
100-		    xmlBufShrink(buf->buffer, i);
101-		    goto xinclude_multibyte_fallback;
102-		} else {
103-		    xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref,
104-				   XML_XINCLUDE_INVALID_CHAR,
105-				   "%s contains invalid char\n", URL);
106-		    xmlFreeParserCtxt(pctxt);
107-		    xmlFreeParserInputBuffer(buf);
108-		    xmlFree(URL);
109-		    return(-1);
110-		}
111-	    } else {
112-		xinclude_multibyte_fallback_used = 0;
113-		xmlNodeAddContentLen(node, &content[i], l);
114-	    }
115-	    i += l;
116-	}
117-	xmlBufShrink(buf->buffer, len);
118+    while (xmlParserInputBufferRead(buf, 4096) > 0)
119+        ;
120+
121+    content = xmlBufContent(buf->buffer);
122+    len = xmlBufLength(buf->buffer);
123+    for (i = 0; i < len;) {
124+        int cur;
125+        int l;
126+
127+        cur = xmlStringCurrentChar(NULL, &content[i], &l);
128+        if (!IS_CHAR(cur)) {
129+            xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, XML_XINCLUDE_INVALID_CHAR,
130+                           "%s contains invalid char\n", URL);
131+            xmlFreeNode(node);
132+            xmlFreeInputStream(inputStream);
133+            xmlFreeParserCtxt(pctxt);
134+            xmlFree(URL);
135+            return(-1);
136+        }
137+
138+        i += l;
139     }
140+
141+    xmlNodeAddContentLen(node, content, len);
142     xmlFreeParserCtxt(pctxt);
143     xmlXIncludeAddTxt(ctxt, node->content, URL);
144     xmlFreeInputStream(inputStream);
145--
1462.27.0
147
148