[libxml2] xinclude: Fix regression with nested includes



commit 7f04e297318b1b908cec20711f74f75625afed7f
Author: Nick Wellnhofer <wellnhofer aevum de>
Date:   Tue Oct 18 18:40:00 2022 +0200

    xinclude: Fix regression with nested includes
    
    This reverts commits 74dcc10b and 87d20b55.
    
    Fixes #424.

 result/XInclude/issue424.xml     |  6 ++++++
 result/XInclude/issue424.xml.rdr | 17 +++++++++++++++
 test/XInclude/docs/issue424.xml  |  5 +++++
 xinclude.c                       | 46 ++++++++++++++++++++++++++++++++++------
 4 files changed, 67 insertions(+), 7 deletions(-)
---
diff --git a/result/XInclude/issue424.xml b/result/XInclude/issue424.xml
new file mode 100644
index 00000000..dc497fa9
--- /dev/null
+++ b/result/XInclude/issue424.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<x xmlns:xinclude="http://www.w3.org/2001/XInclude";>
+   <p>Something</p>
+   <d xmlns:xinclude="http://www.w3.org/2001/XInclude";><p>Something</p></d>
+   <d xmlns:xinclude="http://www.w3.org/2001/XInclude";><p>Something</p></d>
+</x>
diff --git a/result/XInclude/issue424.xml.rdr b/result/XInclude/issue424.xml.rdr
new file mode 100644
index 00000000..39c3b82a
--- /dev/null
+++ b/result/XInclude/issue424.xml.rdr
@@ -0,0 +1,17 @@
+0 1 x 0 0
+1 14 #text 0 1 
+   
+1 1 p 0 0
+2 3 #text 0 1 Something
+1 15 p 0 0
+1 14 #text 0 1 
+   
+1 1 d 0 0
+2 1 xinclude:include 1 0
+1 15 d 0 0
+1 14 #text 0 1 
+   
+1 1 xinclude:include 1 0
+1 14 #text 0 1 
+
+0 15 x 0 0
diff --git a/test/XInclude/docs/issue424.xml b/test/XInclude/docs/issue424.xml
new file mode 100644
index 00000000..fc1cd6f3
--- /dev/null
+++ b/test/XInclude/docs/issue424.xml
@@ -0,0 +1,5 @@
+<x xmlns:xinclude="http://www.w3.org/2001/XInclude";>
+   <p>Something</p>
+   <d xmlns:xinclude="http://www.w3.org/2001/XInclude";><xinclude:include xpointer="xpointer(//p)"/></d>
+   <xinclude:include xpointer="xpointer(//d)"/>
+</x>
diff --git a/xinclude.c b/xinclude.c
index 93d7e525..e14176c6 100644
--- a/xinclude.c
+++ b/xinclude.c
@@ -60,6 +60,7 @@ struct _xmlXIncludeRef {
     xmlNodePtr            inc; /* the included copy */
     int                   xml; /* xml or txt */
     int                 count; /* how many refs use that specific doc */
+    xmlXPathObjectPtr    xptr; /* the xpointer if needed */
     int                     fallback; /* fallback was loaded */
     int                      emptyFb; /* flag to show fallback empty */
 };
@@ -211,6 +212,8 @@ xmlXIncludeFreeRef(xmlXIncludeRefPtr ref) {
        xmlFree(ref->URI);
     if (ref->fragment != NULL)
        xmlFree(ref->fragment);
+    if (ref->xptr != NULL)
+       xmlXPathFreeObject(ref->xptr);
     xmlFree(ref);
 }
 
@@ -1468,7 +1471,7 @@ xmlXIncludeLoadDoc(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) {
      */
     if ((URL[0] == 0) || (URL[0] == '#') ||
        ((ctxt->doc != NULL) && (xmlStrEqual(URL, ctxt->doc->URL)))) {
-       doc = ctxt->doc;
+       doc = NULL;
         goto loaded;
     }
 
@@ -1560,8 +1563,15 @@ loaded:
        /*
         * Add the top children list as the replacement copy.
         */
-       ctxt->incTab[nr]->inc = xmlXIncludeCopyNodeList(ctxt, ctxt->doc,
-                                                       doc, doc->children);
+       if (doc == NULL)
+       {
+           /* Hopefully a DTD declaration won't be copied from
+            * the same document */
+           ctxt->incTab[nr]->inc = xmlCopyNodeList(ctxt->doc->children);
+       } else {
+           ctxt->incTab[nr]->inc = xmlXIncludeCopyNodeList(ctxt, ctxt->doc,
+                                                      doc, doc->children);
+       }
     }
 #ifdef LIBXML_XPTR_ENABLED
     else {
@@ -1573,7 +1583,12 @@ loaded:
        xmlXPathContextPtr xptrctxt;
        xmlNodeSetPtr set;
 
-       xptrctxt = xmlXPtrNewContext(doc, NULL, NULL);
+       if (doc == NULL) {
+           xptrctxt = xmlXPtrNewContext(ctxt->doc, ctxt->incTab[nr]->ref,
+                                        NULL);
+       } else {
+           xptrctxt = xmlXPtrNewContext(doc, NULL, NULL);
+       }
        if (xptrctxt == NULL) {
            xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref,
                           XML_XINCLUDE_XPTR_FAILED,
@@ -1678,9 +1693,14 @@ loaded:
                }
            }
        }
-        ctxt->incTab[nr]->inc =
-            xmlXIncludeCopyXPointer(ctxt, ctxt->doc, doc, xptr);
-        xmlXPathFreeObject(xptr);
+       if (doc == NULL) {
+           ctxt->incTab[nr]->xptr = xptr;
+           ctxt->incTab[nr]->inc = NULL;
+       } else {
+           ctxt->incTab[nr]->inc =
+               xmlXIncludeCopyXPointer(ctxt, ctxt->doc, doc, xptr);
+           xmlXPathFreeObject(xptr);
+       }
        xmlXPathFreeContext(xptrctxt);
        xmlFree(fragment);
     }
@@ -2202,6 +2222,17 @@ xmlXIncludeIncludeNode(xmlXIncludeCtxtPtr ctxt, int nr) {
     if ((cur == NULL) || (cur->type == XML_NAMESPACE_DECL))
        return(-1);
 
+    /*
+     * If we stored an XPointer a late computation may be needed
+     */
+    if ((ctxt->incTab[nr]->inc == NULL) &&
+       (ctxt->incTab[nr]->xptr != NULL)) {
+       ctxt->incTab[nr]->inc =
+           xmlXIncludeCopyXPointer(ctxt, ctxt->doc, ctxt->doc,
+                                   ctxt->incTab[nr]->xptr);
+       xmlXPathFreeObject(ctxt->incTab[nr]->xptr);
+       ctxt->incTab[nr]->xptr = NULL;
+    }
     list = ctxt->incTab[nr]->inc;
     ctxt->incTab[nr]->inc = NULL;
     ctxt->incTab[nr]->emptyFb = 0;
@@ -2470,6 +2501,7 @@ xmlXIncludeDoProcess(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc, xmlNodePtr tree,
      */
     for (i = ctxt->incBase;i < ctxt->incNr; i++) {
        if ((ctxt->incTab[i]->inc != NULL) ||
+            (ctxt->incTab[i]->xptr != NULL) ||
            (ctxt->incTab[i]->emptyFb != 0))    /* (empty fallback) */
            xmlXIncludeIncludeNode(ctxt, i);
     }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]