summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--xinclude.c83
2 files changed, 71 insertions, 17 deletions
diff --git a/ChangeLog b/ChangeLog
index 1f008523..34e62713 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Tue May 31 20:35:27 PDT 2005 William Brack <wbrack@mmm.com.hk>
+
+ * xinclude.c: Enhanced handling of xml:base for included
+ elements, fixing bugs 169209 and 302353.
+
Wed May 25 18:59:53 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
* xmlschemas.c: Fixed facet errors to be channelled back for
diff --git a/xinclude.c b/xinclude.c
index 8801f1e6..ab640968 100644
--- a/xinclude.c
+++ b/xinclude.c
@@ -1663,32 +1663,81 @@ loaded:
*/
if ((doc != NULL) && (URL != NULL) && (xmlStrchr(URL, (xmlChar) '/'))) {
xmlNodePtr node;
- xmlChar *relURI;
+ xmlChar *base;
xmlChar *curBase;
/*
- * The base is only adjusted if necessary for the existing base
+ * The base is only adjusted if "necessary", i.e. if the xinclude node
+ * has a base specified, or the URL is relative
*/
- relURI = xmlBuildRelativeURI(URL, ctxt->base);
- if (relURI == NULL) { /* Error return */
- xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref,
+ base = xmlGetNsProp(ctxt->incTab[nr]->ref, BAD_CAST "base",
+ XML_XML_NAMESPACE);
+ if (base == NULL) {
+ /*
+ * No xml:base on the xinclude node, so we check whether the
+ * URI base is different than (relative to) the context base
+ */
+ curBase = xmlBuildRelativeURI(URL, ctxt->base);
+ if (curBase == NULL) { /* Error return */
+ xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref,
XML_XINCLUDE_HREF_URI,
"trying to build relative URI from %s\n", URL);
- } else {
- if (xmlStrchr(relURI, (xmlChar) '/')) {
- node = ctxt->incTab[nr]->inc;
- while (node != NULL) {
- if (node->type == XML_ELEMENT_NODE) {
- curBase = xmlNodeGetBase(node->doc, node);
- if ((curBase == NULL) || xmlStrEqual(curBase, node->doc->URL))
- xmlNodeSetBase(node, relURI);
- if (curBase != NULL)
- xmlFree(curBase);
+ } else {
+ /* If the URI doesn't contain a slash, it's not relative */
+ if (!xmlStrchr(curBase, (xmlChar) '/'))
+ xmlFree(curBase);
+ else
+ base = curBase;
+ }
+ }
+ if (base != NULL) { /* Adjustment may be needed */
+ node = ctxt->incTab[nr]->inc;
+ while (node != NULL) {
+ /* Only work on element nodes */
+ if (node->type == XML_ELEMENT_NODE) {
+ curBase = xmlNodeGetBase(node->doc, node);
+ /* If no current base, set it */
+ if (curBase == NULL) {
+ xmlNodeSetBase(node, base);
+ } else {
+ /*
+ * If the current base is the same as the
+ * URL of the document, then reset it to be
+ * the specified xml:base or the relative URI
+ */
+ if (xmlStrEqual(curBase, node->doc->URL)) {
+ xmlNodeSetBase(node, base);
+ } else {
+ /*
+ * If the element already has an xml:base
+ * set, then relativise it if necessary
+ */
+ xmlChar *xmlBase;
+ xmlBase = xmlGetNsProp(node,
+ BAD_CAST "base",
+ XML_XML_NAMESPACE);
+ if (xmlBase != NULL) {
+ xmlChar *relBase;
+ relBase = xmlBuildURI(xmlBase, base);
+ if (relBase == NULL) { /* error */
+ xmlXIncludeErr(ctxt,
+ ctxt->incTab[nr]->ref,
+ XML_XINCLUDE_HREF_URI,
+ "trying to rebuild base from %s\n",
+ xmlBase);
+ } else {
+ xmlNodeSetBase(node, relBase);
+ xmlFree(relBase);
+ }
+ xmlFree(xmlBase);
+ }
+ }
+ xmlFree(curBase);
}
- node = node->next;
}
+ node = node->next;
}
- xmlFree(relURI);
+ xmlFree(base);
}
}
if ((nr < ctxt->incNr) && (ctxt->incTab[nr]->doc != NULL) &&