From 2c747129779be9e3ce84a2f98ce5052a68d41098 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Mon, 17 Aug 2020 00:54:12 +0200
Subject: [PATCH] Fix error reporting with xi:fallback

When reporting errors, don't use href of xi:include if xi:fallback
was used. I think this can only be reproduced with
"xmllint --postvalid", see the original bug report:

https://bugzilla.gnome.org/show_bug.cgi?id=152623
---
 error.c    | 22 +++++++++++-----------
 xinclude.c |  4 ++++
 2 files changed, 15 insertions(+), 11 deletions(-)

diff --git a/error.c b/error.c
index 3e41e17..9ff1c2b 100644
--- a/error.c
+++ b/error.c
@@ -557,6 +557,7 @@ __xmlRaiseError(xmlStructuredErrorFunc schannel,
 	 * of the usual "base" (doc->URL) for the node (bug 152623).
 	 */
         xmlNodePtr prev = baseptr;
+        char *href = NULL;
 	int inclcount = 0;
 	while (prev != NULL) {
 	    if (prev->prev == NULL)
@@ -564,21 +565,20 @@ __xmlRaiseError(xmlStructuredErrorFunc schannel,
 	    else {
 	        prev = prev->prev;
 		if (prev->type == XML_XINCLUDE_START) {
-		    if (--inclcount < 0)
-		        break;
+		    if (inclcount > 0) {
+                        --inclcount;
+                    } else {
+                        href = (char *) xmlGetProp(prev, BAD_CAST "href");
+                        if (href != NULL)
+		            break;
+                    }
 		} else if (prev->type == XML_XINCLUDE_END)
 		    inclcount++;
 	    }
 	}
-	if (prev != NULL) {
-	    if (prev->type == XML_XINCLUDE_START) {
-		prev->type = XML_ELEMENT_NODE;
-		to->file = (char *) xmlGetProp(prev, BAD_CAST "href");
-		prev->type = XML_XINCLUDE_START;
-	    } else {
-		to->file = (char *) xmlGetProp(prev, BAD_CAST "href");
-	    }
-	} else
+        if (href != NULL)
+            to->file = href;
+	else
 #endif
 	    to->file = (char *) xmlStrdup(baseptr->doc->URL);
 	if ((to->file == NULL) && (node != NULL) && (node->doc != NULL)) {
diff --git a/xinclude.c b/xinclude.c
index 9a65ee5..2423a93 100644
--- a/xinclude.c
+++ b/xinclude.c
@@ -61,6 +61,7 @@ struct _xmlXIncludeRef {
     int                 count; /* how many refs use that specific doc */
     xmlXPathObjectPtr    xptr; /* the xpointer if needed */
     int		         skip; /* skip in case of errors */
+    int	             fallback; /* fallback was loaded */
 };
 
 struct _xmlXIncludeCtxt {
@@ -2007,6 +2008,7 @@ xmlXIncludeLoadFallback(xmlXIncludeCtxtPtr ctxt, xmlNodePtr fallback, int nr) {
     } else {
         ctxt->incTab[nr]->inc = NULL;
     }
+    ctxt->incTab[nr]->fallback = 1;
     return(ret);
 }
 
@@ -2266,6 +2268,8 @@ xmlXIncludeIncludeNode(xmlXIncludeCtxtPtr ctxt, int nr) {
 	 * Change the current node as an XInclude start one, and add an
 	 * XInclude end one
 	 */
+        if (ctxt->incTab[nr]->fallback)
+            xmlUnsetProp(cur, BAD_CAST "href");
 	cur->type = XML_XINCLUDE_START;
 	end = xmlNewDocNode(cur->doc, cur->ns, cur->name, NULL);
 	if (end == NULL) {
-- 
1.8.3.1

