153aa9179Sopenharmony_ciFrom e20f4d7a656e47553f9da9d594e299e2fa2dbe41 Mon Sep 17 00:00:00 2001
253aa9179Sopenharmony_ciFrom: Nick Wellnhofer <wellnhofer@aevum.de>
353aa9179Sopenharmony_ciDate: Mon, 13 Feb 2023 14:38:05 +0100
453aa9179Sopenharmony_ciSubject: [PATCH] xinclude: Fix quadratic behavior in xmlXIncludeLoadTxt
553aa9179Sopenharmony_ci
653aa9179Sopenharmony_ciAlso make text inclusions work with memory buffers, for example when
753aa9179Sopenharmony_ciusing a custom entity loader, and fix a memory leak in case of invalid
853aa9179Sopenharmony_cicharacters.
953aa9179Sopenharmony_ci
1053aa9179Sopenharmony_ciFixes #483.
1153aa9179Sopenharmony_ci
1253aa9179Sopenharmony_ciReference:https://github.com/GNOME/libxml2/commit/e20f4d7a656e47553f9da9d594e299e2fa2dbe41
1353aa9179Sopenharmony_ciConflict:NA
1453aa9179Sopenharmony_ci
1553aa9179Sopenharmony_ci---
1653aa9179Sopenharmony_ci result/XInclude/invalid_char.xml.err |  2 +
1753aa9179Sopenharmony_ci result/XInclude/invalid_char.xml.rdr |  7 ++++
1853aa9179Sopenharmony_ci test/XInclude/docs/invalid_char.xml  |  3 ++
1953aa9179Sopenharmony_ci test/XInclude/ents/invalid_char.txt  |  1 +
2053aa9179Sopenharmony_ci xinclude.c                           | 61 ++++++++++++----------------
2153aa9179Sopenharmony_ci 5 files changed, 39 insertions(+), 35 deletions(-)
2253aa9179Sopenharmony_ci create mode 100644 result/XInclude/invalid_char.xml.err
2353aa9179Sopenharmony_ci create mode 100644 result/XInclude/invalid_char.xml.rdr
2453aa9179Sopenharmony_ci create mode 100644 test/XInclude/docs/invalid_char.xml
2553aa9179Sopenharmony_ci create mode 100644 test/XInclude/ents/invalid_char.txt
2653aa9179Sopenharmony_ci
2753aa9179Sopenharmony_cidiff --git a/result/XInclude/invalid_char.xml.err b/result/XInclude/invalid_char.xml.err
2853aa9179Sopenharmony_cinew file mode 100644
2953aa9179Sopenharmony_ciindex 0000000..c28c109
3053aa9179Sopenharmony_ci--- /dev/null
3153aa9179Sopenharmony_ci+++ b/result/XInclude/invalid_char.xml.err
3253aa9179Sopenharmony_ci@@ -0,0 +1,2 @@
3353aa9179Sopenharmony_ci+./test/XInclude/docs/invalid_char.xml:2: element include: XInclude error : test/XInclude/ents/invalid_char.txt contains invalid char
3453aa9179Sopenharmony_ci+./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
3553aa9179Sopenharmony_cidiff --git a/result/XInclude/invalid_char.xml.rdr b/result/XInclude/invalid_char.xml.rdr
3653aa9179Sopenharmony_cinew file mode 100644
3753aa9179Sopenharmony_ciindex 0000000..1fb5774
3853aa9179Sopenharmony_ci--- /dev/null
3953aa9179Sopenharmony_ci+++ b/result/XInclude/invalid_char.xml.rdr
4053aa9179Sopenharmony_ci@@ -0,0 +1,7 @@
4153aa9179Sopenharmony_ci+0 1 x 0 0
4253aa9179Sopenharmony_ci+1 14 #text 0 1 
4353aa9179Sopenharmony_ci+   
4453aa9179Sopenharmony_ci+1 1 xinclude:include 1 0
4553aa9179Sopenharmony_ci+1 14 #text 0 1 
4653aa9179Sopenharmony_ci+
4753aa9179Sopenharmony_ci+0 15 x 0 0
4853aa9179Sopenharmony_cidiff --git a/test/XInclude/docs/invalid_char.xml b/test/XInclude/docs/invalid_char.xml
4953aa9179Sopenharmony_cinew file mode 100644
5053aa9179Sopenharmony_ciindex 0000000..28e5a48
5153aa9179Sopenharmony_ci--- /dev/null
5253aa9179Sopenharmony_ci+++ b/test/XInclude/docs/invalid_char.xml
5353aa9179Sopenharmony_ci@@ -0,0 +1,3 @@
5453aa9179Sopenharmony_ci+<x xmlns:xinclude="http://www.w3.org/2001/XInclude">
5553aa9179Sopenharmony_ci+   <xinclude:include href="../ents/invalid_char.txt" parse="text"/>
5653aa9179Sopenharmony_ci+</x>
5753aa9179Sopenharmony_cidiff --git a/test/XInclude/ents/invalid_char.txt b/test/XInclude/ents/invalid_char.txt
5853aa9179Sopenharmony_cinew file mode 100644
5953aa9179Sopenharmony_ciindex 0000000..ae06618
6053aa9179Sopenharmony_ci--- /dev/null
6153aa9179Sopenharmony_ci+++ b/test/XInclude/ents/invalid_char.txt
6253aa9179Sopenharmony_ci@@ -0,0 +1 @@
6353aa9179Sopenharmony_ci+invalid: �
6453aa9179Sopenharmony_ci\ No newline at end of file
6553aa9179Sopenharmony_cidiff --git a/xinclude.c b/xinclude.c
6653aa9179Sopenharmony_ciindex cc486f5..6e5b61d 100644
6753aa9179Sopenharmony_ci--- a/xinclude.c
6853aa9179Sopenharmony_ci+++ b/xinclude.c
6953aa9179Sopenharmony_ci@@ -1798,7 +1798,9 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) {
7053aa9179Sopenharmony_ci     xmlCharEncoding enc = (xmlCharEncoding) 0;
7153aa9179Sopenharmony_ci     xmlParserCtxtPtr pctxt;
7253aa9179Sopenharmony_ci     xmlParserInputPtr inputStream;
7353aa9179Sopenharmony_ci-    int xinclude_multibyte_fallback_used = 0;
7453aa9179Sopenharmony_ci+    int len;
7553aa9179Sopenharmony_ci+    const xmlChar *content;
7653aa9179Sopenharmony_ci+
7753aa9179Sopenharmony_ci 
7853aa9179Sopenharmony_ci     /* Don't read from stdin. */
7953aa9179Sopenharmony_ci     if (xmlStrcmp(url, BAD_CAST "-") == 0)
8053aa9179Sopenharmony_ci@@ -1905,41 +1907,30 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) {
8153aa9179Sopenharmony_ci     /*
8253aa9179Sopenharmony_ci      * Scan all chars from the resource and add the to the node
8353aa9179Sopenharmony_ci      */
8453aa9179Sopenharmony_ci-xinclude_multibyte_fallback:
8553aa9179Sopenharmony_ci-    while (xmlParserInputBufferRead(buf, 128) > 0) {
8653aa9179Sopenharmony_ci-	int len;
8753aa9179Sopenharmony_ci-	const xmlChar *content;
8853aa9179Sopenharmony_ci-
8953aa9179Sopenharmony_ci-	content = xmlBufContent(buf->buffer);
9053aa9179Sopenharmony_ci-	len = xmlBufLength(buf->buffer);
9153aa9179Sopenharmony_ci-	for (i = 0;i < len;) {
9253aa9179Sopenharmony_ci-	    int cur;
9353aa9179Sopenharmony_ci-	    int l;
9453aa9179Sopenharmony_ci-
9553aa9179Sopenharmony_ci-	    cur = xmlStringCurrentChar(NULL, &content[i], &l);
9653aa9179Sopenharmony_ci-	    if (!IS_CHAR(cur)) {
9753aa9179Sopenharmony_ci-		/* Handle split multibyte char at buffer boundary */
9853aa9179Sopenharmony_ci-		if (((len - i) < 4) && (!xinclude_multibyte_fallback_used)) {
9953aa9179Sopenharmony_ci-		    xinclude_multibyte_fallback_used = 1;
10053aa9179Sopenharmony_ci-		    xmlBufShrink(buf->buffer, i);
10153aa9179Sopenharmony_ci-		    goto xinclude_multibyte_fallback;
10253aa9179Sopenharmony_ci-		} else {
10353aa9179Sopenharmony_ci-		    xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref,
10453aa9179Sopenharmony_ci-				   XML_XINCLUDE_INVALID_CHAR,
10553aa9179Sopenharmony_ci-				   "%s contains invalid char\n", URL);
10653aa9179Sopenharmony_ci-		    xmlFreeParserCtxt(pctxt);
10753aa9179Sopenharmony_ci-		    xmlFreeParserInputBuffer(buf);
10853aa9179Sopenharmony_ci-		    xmlFree(URL);
10953aa9179Sopenharmony_ci-		    return(-1);
11053aa9179Sopenharmony_ci-		}
11153aa9179Sopenharmony_ci-	    } else {
11253aa9179Sopenharmony_ci-		xinclude_multibyte_fallback_used = 0;
11353aa9179Sopenharmony_ci-		xmlNodeAddContentLen(node, &content[i], l);
11453aa9179Sopenharmony_ci-	    }
11553aa9179Sopenharmony_ci-	    i += l;
11653aa9179Sopenharmony_ci-	}
11753aa9179Sopenharmony_ci-	xmlBufShrink(buf->buffer, len);
11853aa9179Sopenharmony_ci+    while (xmlParserInputBufferRead(buf, 4096) > 0)
11953aa9179Sopenharmony_ci+        ;
12053aa9179Sopenharmony_ci+
12153aa9179Sopenharmony_ci+    content = xmlBufContent(buf->buffer);
12253aa9179Sopenharmony_ci+    len = xmlBufLength(buf->buffer);
12353aa9179Sopenharmony_ci+    for (i = 0; i < len;) {
12453aa9179Sopenharmony_ci+        int cur;
12553aa9179Sopenharmony_ci+        int l;
12653aa9179Sopenharmony_ci+
12753aa9179Sopenharmony_ci+        cur = xmlStringCurrentChar(NULL, &content[i], &l);
12853aa9179Sopenharmony_ci+        if (!IS_CHAR(cur)) {
12953aa9179Sopenharmony_ci+            xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, XML_XINCLUDE_INVALID_CHAR,
13053aa9179Sopenharmony_ci+                           "%s contains invalid char\n", URL);
13153aa9179Sopenharmony_ci+            xmlFreeNode(node);
13253aa9179Sopenharmony_ci+            xmlFreeInputStream(inputStream);
13353aa9179Sopenharmony_ci+            xmlFreeParserCtxt(pctxt);
13453aa9179Sopenharmony_ci+            xmlFree(URL);
13553aa9179Sopenharmony_ci+            return(-1);
13653aa9179Sopenharmony_ci+        }
13753aa9179Sopenharmony_ci+
13853aa9179Sopenharmony_ci+        i += l;
13953aa9179Sopenharmony_ci     }
14053aa9179Sopenharmony_ci+
14153aa9179Sopenharmony_ci+    xmlNodeAddContentLen(node, content, len);
14253aa9179Sopenharmony_ci     xmlFreeParserCtxt(pctxt);
14353aa9179Sopenharmony_ci     xmlXIncludeAddTxt(ctxt, node->content, URL);
14453aa9179Sopenharmony_ci     xmlFreeInputStream(inputStream);
14553aa9179Sopenharmony_ci-- 
14653aa9179Sopenharmony_ci2.27.0
14753aa9179Sopenharmony_ci
148