diff options
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | xinclude.c | 83 |
2 files changed, 71 insertions, 17 deletions
@@ -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 @@ -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) && |