new file mode 100644
@@ -0,0 +1,219 @@
+From 8d0c6eb94f8a32a49e3c9122a6da82c519198063 Mon Sep 17 00:00:00 2001
+From: Ruben Thijssen <ruben.thijssen@cba.com.au>
+Date: Fri, 15 May 2026 15:42:18 +1000
+Subject: [PATCH] fix(xinclude): propagate parseFlags in xmlXIncludeProcess and
+ xmlXIncludeProcessTree
+
+CVE: CVE-2026-86144
+Upstream-Status: Backport [https://github.com/GNOME/libxml2/commit/b63cd517afecb76582dd9488c55e54ceaf50de61]
+
+Backport Changes:
+- Use xmlLoadExternalEntity() with xmlCtxtUseOptions() because Scarthgap 2.12.10 predates xmlLoadResource() and resource-loader callbacks.
+- Adapt the regression tests for 2.12.10 by using the global structured-error handler, matching 2.12.10 loader network-entity diagnostics, and restoring the test handler after xmlXIncludeProcess().
+- Omit the upstream XML_IO_NETWORK_ATTEMPT filter because the 2.12.10 xmlLoadExternalEntity() path has no corresponding post-load error-filtering block.
+- Add a parser-context allocation guard because the target version can return NULL from xmlNewParserCtxt().
+
+(cherry picked from commit b63cd517afecb76582dd9488c55e54ceaf50de61)
+Signed-off-by: Hetvi Thakar <hthakar@cisco.com>
+---
+ result/XInclude/issue1120-1.xml | 4 ++
+ result/XInclude/issue1120-1.xml.err | 1 +
+ result/XInclude/issue1120-2.xml | 4 ++
+ result/XInclude/issue1120-2.xml.err | 1 +
+ runtest.c | 75 +++++++++++++++++++++++++
+ test/XInclude/issue1120/issue1120-1.xml | 6 ++
+ test/XInclude/issue1120/issue1120-2.xml | 6 ++
+ xinclude.c | 9 ++-
+ 8 files changed, 104 insertions(+), 2 deletions(-)
+ create mode 100644 result/XInclude/issue1120-1.xml
+ create mode 100644 result/XInclude/issue1120-1.xml.err
+ create mode 100644 result/XInclude/issue1120-2.xml
+ create mode 100644 result/XInclude/issue1120-2.xml.err
+ create mode 100644 test/XInclude/issue1120/issue1120-1.xml
+ create mode 100644 test/XInclude/issue1120/issue1120-2.xml
+
+diff --git a/result/XInclude/issue1120-1.xml b/result/XInclude/issue1120-1.xml
+new file mode 100644
+index 00000000..5d83cc96
+--- /dev/null
++++ b/result/XInclude/issue1120-1.xml
+@@ -0,0 +1,4 @@
++<?xml version="1.0"?>
++<doc xmlns:xi="http://www.w3.org/2001/XInclude">
++ Network access is not allowed
++</doc>
+diff --git a/result/XInclude/issue1120-1.xml.err b/result/XInclude/issue1120-1.xml.err
+new file mode 100644
+index 00000000..c134bed1
+--- /dev/null
++++ b/result/XInclude/issue1120-1.xml.err
+@@ -0,0 +1 @@
++I/O error : Attempt to load network entity http://example.invalid/file.txt
+diff --git a/result/XInclude/issue1120-2.xml b/result/XInclude/issue1120-2.xml
+new file mode 100644
+index 00000000..af5bde91
+--- /dev/null
++++ b/result/XInclude/issue1120-2.xml
+@@ -0,0 +1,4 @@
++<?xml version="1.0"?>
++<doc xmlns:xi="http://www.w3.org/2001/XInclude">
++ <p>Network access is not allowed</p>
++</doc>
+diff --git a/result/XInclude/issue1120-2.xml.err b/result/XInclude/issue1120-2.xml.err
+new file mode 100644
+index 00000000..051f5928
+--- /dev/null
++++ b/result/XInclude/issue1120-2.xml.err
+@@ -0,0 +1 @@
++I/O error : Attempt to load network entity http://example.invalid/file.xml
+diff --git a/runtest.c b/runtest.c
+index e91e2dfd..297cb5e2 100644
+--- a/runtest.c
++++ b/runtest.c
+@@ -2444,6 +2444,75 @@ noentParseTest(const char *filename, const char *result,
+ return(res);
+ }
+
++#ifdef LIBXML_XINCLUDE_ENABLED
++/**
++ * Parse a file and run xmlXIncludeProcess() to verify that doc->parseFlags
++ * is propagated properly.
++ *
++ * @param filename the file to parse
++ * @param result the file with expected result
++ * @param err the file with error messages
++ * @returns 0 in case of success, an error code otherwise
++ */
++static int
++xincludeProcessTest(const char *filename, const char *result, const char *err,
++ int options) {
++ xmlParserCtxtPtr ctxt;
++ xmlDocPtr doc;
++ xmlChar *base = NULL;
++ int size, res;
++ int ret = 0;
++
++ nb_tests++;
++
++ /* Create a new parser context */
++ ctxt = xmlNewParserCtxt();
++ if (ctxt == NULL)
++ return(-1);
++
++ /* Load the data from `filename` into a parser context */
++ xmlSetStructuredErrorFunc(NULL, testStructuredErrorHandler);
++ doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
++ xmlFreeParserCtxt(ctxt);
++
++ /* Check if `doc` was created successfully */
++ if (doc == NULL) {
++ testErrorHandler(NULL, "%s : failed to parse\n", filename);
++ return(-1);
++ }
++
++ /*
++ * Run xmlXIncludeProcess() with a structured error handler to check that
++ * the parse flags are propagated.
++ */
++ xmlSetStructuredErrorFunc(NULL, testStructuredErrorHandler);
++ xmlXIncludeProcess(doc);
++ xmlSetStructuredErrorFunc(NULL, testStructuredErrorHandler);
++
++ /* Check the result and for any errors */
++ if (result) {
++ xmlDocDumpMemory(doc, &base, &size);
++ res = compareFileMem(result, (char *) base, size);
++ xmlFree(base);
++ if (res != 0) {
++ fprintf(stderr, "Result for %s failed in %s\n", filename, result);
++ ret = -1;
++ }
++ }
++
++ if ((ret == 0) && (err != NULL)) {
++ res = compareFileMem(err, testErrors, testErrorsSize);
++ if (res != 0) {
++ fprintf(stderr, "Error for %s failed\n", filename);
++ ret = -1;
++ }
++ }
++
++ xmlFreeDoc(doc);
++ return(ret);
++}
++#endif
++
+ /**
+ * errParseTest:
+ * @filename: the file to parse
+@@ -5134,6 +5203,12 @@ testDesc testDescriptions[] = {
+ { "XInclude regression tests without reader",
+ errParseTest, "./test/XInclude/without-reader/*", "result/XInclude/", "",
+ ".err", XML_PARSE_XINCLUDE },
++ { "XInclude issue1120 regression tests",
++ errParseTest, "./test/XInclude/issue1120/*", "result/XInclude/", "",
++ ".err", XML_PARSE_XINCLUDE | XML_PARSE_NONET },
++ { "XInclude xmlXIncludeProcess() issue1120 regression tests",
++ xincludeProcessTest, "./test/XInclude/issue1120/*", "result/XInclude/",
++ "", ".err", XML_PARSE_NONET },
+ #endif
+ #ifdef LIBXML_XPATH_ENABLED
+ #ifdef LIBXML_DEBUG_ENABLED
+diff --git a/test/XInclude/issue1120/issue1120-1.xml b/test/XInclude/issue1120/issue1120-1.xml
+new file mode 100644
+index 00000000..b0b8feef
+--- /dev/null
++++ b/test/XInclude/issue1120/issue1120-1.xml
+@@ -0,0 +1,6 @@
++<?xml version="1.0"?>
++<doc xmlns:xi="http://www.w3.org/2001/XInclude">
++ <xi:include href="http://example.invalid/file.txt" parse="text">
++ <xi:fallback>Network access is not allowed</xi:fallback>
++ </xi:include>
++</doc>
+diff --git a/test/XInclude/issue1120/issue1120-2.xml b/test/XInclude/issue1120/issue1120-2.xml
+new file mode 100644
+index 00000000..b4c9fe5e
+--- /dev/null
++++ b/test/XInclude/issue1120/issue1120-2.xml
+@@ -0,0 +1,6 @@
++<?xml version="1.0"?>
++<doc xmlns:xi="http://www.w3.org/2001/XInclude">
++ <xi:include href="http://example.invalid/file.xml">
++ <xi:fallback><p>Network access is not allowed</p></xi:fallback>
++ </xi:include>
++</doc>
+diff --git a/xinclude.c b/xinclude.c
+index b6581558..0d57f5a1 100644
+--- a/xinclude.c
++++ b/xinclude.c
+@@ -1688,6 +1688,11 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url,
+ * Load it.
+ */
+ pctxt = xmlNewParserCtxt();
++ if (pctxt == NULL) {
++ xmlXIncludeErrMemory(ctxt, ref->elem, NULL);
++ goto error;
++ }
++ xmlCtxtUseOptions(pctxt, ctxt->parseFlags);
+ inputStream = xmlLoadExternalEntity((const char*)URL, NULL, pctxt);
+ if(inputStream == NULL)
+ goto error;
+@@ -2416,7 +2421,7 @@ xmlXIncludeProcessFlags(xmlDocPtr doc, int flags) {
+ */
+ int
+ xmlXIncludeProcess(xmlDocPtr doc) {
+- return(xmlXIncludeProcessFlags(doc, 0));
++ return(xmlXIncludeProcessFlags(doc, doc ? doc->parseFlags : 0));
+ }
+
+ /**
+@@ -2461,7 +2466,7 @@ xmlXIncludeProcessTreeFlags(xmlNodePtr tree, int flags) {
+ */
+ int
+ xmlXIncludeProcessTree(xmlNodePtr tree) {
+- return(xmlXIncludeProcessTreeFlags(tree, 0));
++ return(xmlXIncludeProcessTreeFlags(tree, (tree && tree->doc) ? tree->doc->parseFlags : 0));
+ }
+
+ /**
@@ -38,6 +38,7 @@ SRC_URI += "http://www.w3.org/XML/Test/xmlts20130923.tar;subdir=${BP};name=testt
file://CVE-2026-86141.patch \
file://CVE-2026-86142.patch \
file://CVE-2026-86143.patch \
+ file://CVE-2026-86144.patch \
"
SRC_URI[archive.sha256sum] = "c3d8c0c34aa39098f66576fe51969db12a5100b956233dc56506f7a8679be995"