diff options
author | Aron Xu <aron@debian.org> | 2014-10-26 07:02:25 +0800 |
---|---|---|
committer | Aron Xu <aron@debian.org> | 2014-10-26 07:02:25 +0800 |
commit | 3871a83a5f0aebd8c00879eab14fe901c93dbfcf (patch) | |
tree | b022967f880b7fb1e56c8cc4c3f200d6ffbc9efd /xinclude.c | |
parent | 7042e17490515a990a45aa7237d11bc49ab0eaf0 (diff) | |
download | libxml2-3871a83a5f0aebd8c00879eab14fe901c93dbfcf.tar.gz |
Imported Upstream version 2.9.2+dfsg1
Diffstat (limited to 'xinclude.c')
-rw-r--r-- | xinclude.c | 132 |
1 files changed, 75 insertions, 57 deletions
@@ -17,6 +17,7 @@ #include <libxml/tree.h> #include <libxml/parser.h> #include <libxml/uri.h> +#include <libxml/xpath.h> #include <libxml/xpointer.h> #include <libxml/parserInternals.h> #include <libxml/xmlerror.h> @@ -26,6 +27,7 @@ #ifdef LIBXML_XINCLUDE_ENABLED #include <libxml/xinclude.h> +#include "buf.h" #define XINCLUDE_MAX_DEPTH 40 @@ -92,7 +94,7 @@ xmlXIncludeDoProcess(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc, xmlNodePtr tree); /************************************************************************ * * - * XInclude error handler * + * XInclude error handler * * * ************************************************************************/ @@ -412,7 +414,7 @@ xmlXIncludeFreeContext(xmlXIncludeCtxtPtr ctxt) { * xmlXIncludeParseFile: * @ctxt: the XInclude context * @URL: the URL or file path - * + * * parse a document for XInclude */ static xmlDocPtr @@ -433,7 +435,7 @@ xmlXIncludeParseFile(xmlXIncludeCtxtPtr ctxt, const char *URL) { * pass in the application data to the parser context. */ pctxt->_private = ctxt->_private; - + /* * try to ensure that new documents included are actually * built with the same dictionary as the including document. @@ -446,7 +448,7 @@ xmlXIncludeParseFile(xmlXIncludeCtxtPtr ctxt, const char *URL) { } xmlCtxtUseOptions(pctxt, ctxt->parseFlags | XML_PARSE_DTDLOAD); - + inputStream = xmlLoadExternalEntity(URL, NULL, pctxt); if (inputStream == NULL) { xmlFreeParserCtxt(pctxt); @@ -472,7 +474,7 @@ xmlXIncludeParseFile(xmlXIncludeCtxtPtr ctxt, const char *URL) { pctxt->myDoc = NULL; } xmlFreeParserCtxt(pctxt); - + return(ret); } @@ -480,7 +482,7 @@ xmlXIncludeParseFile(xmlXIncludeCtxtPtr ctxt, const char *URL) { * xmlXIncludeAddNode: * @ctxt: the XInclude context * @cur: the new node - * + * * Add a new node to process to an XInclude context */ static int @@ -511,7 +513,7 @@ xmlXIncludeAddNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr cur) { href = xmlXIncludeGetProp(ctxt, cur, XINCLUDE_HREF); if (href == NULL) { href = xmlStrdup(BAD_CAST ""); /* @@@@ href is now optional */ - if (href == NULL) + if (href == NULL) return(-1); } if ((href[0] == '#') || (href[0] == 0)) @@ -655,7 +657,7 @@ xmlXIncludeAddNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr cur) { * @ctxt: the XInclude context * @doc: the new document * @url: the associated URL - * + * * The XInclude recursive nature is handled at this point. */ static void @@ -684,7 +686,7 @@ xmlXIncludeRecurseDoc(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc, /* * Copy the private user data */ - newctxt->_private = ctxt->_private; + newctxt->_private = ctxt->_private; /* * Copy the existing document set */ @@ -749,7 +751,7 @@ xmlXIncludeRecurseDoc(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc, * @ctxt: the XInclude context * @txt: the new text node * @url: the associated URL - * + * * Add a new txtument to the list */ static void @@ -808,7 +810,7 @@ xmlXIncludeCopyNodeList(xmlXIncludeCtxtPtr ctxt, xmlDocPtr target, * @target: the document target * @source: the document source * @elem: the element - * + * * Make a copy of the node while preserving the XInclude semantic * of the Infoset copy */ @@ -835,7 +837,7 @@ xmlXIncludeCopyNode(xmlXIncludeCtxtPtr ctxt, xmlDocPtr target, * @target: the document target * @source: the document source * @elem: the element list - * + * * Make a copy of the node list while preserving the XInclude semantic * of the Infoset copy */ @@ -874,11 +876,11 @@ xmlXIncludeCopyNodeList(xmlXIncludeCtxtPtr ctxt, xmlDocPtr target, static xmlNodePtr xmlXIncludeGetNthChild(xmlNodePtr cur, int no) { int i; - if (cur == NULL) - return(cur); + if ((cur == NULL) || (cur->type == XML_NAMESPACE_DECL)) + return(NULL); cur = cur->children; for (i = 0;i <= no;cur = cur->next) { - if (cur == NULL) + if (cur == NULL) return(cur); if ((cur->type == XML_ELEMENT_NODE) || (cur->type == XML_DOCUMENT_NODE) || @@ -922,11 +924,13 @@ xmlXIncludeCopyRange(xmlXIncludeCtxtPtr ctxt, xmlDocPtr target, return(NULL); start = (xmlNodePtr) range->user; - if (start == NULL) + if ((start == NULL) || (start->type == XML_NAMESPACE_DECL)) return(NULL); end = range->user2; if (end == NULL) return(xmlDocCopyNode(start, target, 1)); + if (end->type == XML_NAMESPACE_DECL) + return(NULL); cur = start; index1 = range->index; @@ -985,7 +989,7 @@ xmlXIncludeCopyRange(xmlXIncludeCtxtPtr ctxt, xmlDocPtr target, /* prune and return full set */ if (level == lastLevel) xmlAddNextSibling(last, tmp); - else + else xmlAddChild(last, tmp); return(list); } else { /* ending node not a text node */ @@ -1204,6 +1208,7 @@ xmlXIncludeCopyXPointer(xmlXIncludeCtxtPtr ctxt, xmlDocPtr target, } break; } +#ifdef LIBXML_XPTR_ENABLED case XPATH_LOCATIONSET: { xmlLocationSetPtr set = (xmlLocationSetPtr) obj->user; if (set == NULL) @@ -1223,7 +1228,6 @@ xmlXIncludeCopyXPointer(xmlXIncludeCtxtPtr ctxt, xmlDocPtr target, } break; } -#ifdef LIBXML_XPTR_ENABLED case XPATH_RANGE: return(xmlXIncludeCopyRange(ctxt, target, source, obj)); #endif @@ -1289,7 +1293,7 @@ xmlXIncludeMergeEntity(xmlEntityPtr ent, xmlXIncludeMergeDataPtr data, if (prev != NULL) { if (ent->etype != prev->etype) goto error; - + if ((ent->SystemID != NULL) && (prev->SystemID != NULL)) { if (!xmlStrEqual(ent->SystemID, prev->SystemID)) goto error; @@ -1389,7 +1393,7 @@ xmlXIncludeMergeEntities(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc, * @ctxt: the XInclude context * @url: the associated URL * @nr: the xinclude node number - * + * * Load the document, and store the result in the XInclude context * * Returns 0 in case of success, -1 in case of failure @@ -1413,7 +1417,7 @@ xmlXIncludeLoadDoc(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) { */ uri = xmlParseURI((const char *)url); if (uri == NULL) { - xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, + xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, XML_XINCLUDE_HREF_URI, "invalid value URI %s\n", url); return(-1); @@ -1431,7 +1435,7 @@ xmlXIncludeLoadDoc(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) { xmlFreeURI(uri); if (URL == NULL) { if (ctxt->incTab != NULL) - xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, + xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, XML_XINCLUDE_HREF_URI, "invalid value URI %s\n", url); else @@ -1550,7 +1554,7 @@ loaded: ctxt->incTab[nr]->inc = xmlXIncludeCopyNodeList(ctxt, ctxt->doc, doc, doc->children); } - } + } #ifdef LIBXML_XPTR_ENABLED else { /* @@ -1568,7 +1572,7 @@ loaded: xptrctxt = xmlXPtrNewContext(doc, NULL, NULL); } if (xptrctxt == NULL) { - xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, + xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, XML_XINCLUDE_XPTR_FAILED, "could not create XPointer context\n", NULL); xmlFree(URL); @@ -1594,7 +1598,7 @@ loaded: case XPATH_POINT: case XPATH_USERS: case XPATH_XSLT_TREE: - xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, + xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, XML_XINCLUDE_XPTR_RESULT, "XPointer is not a range: #%s\n", fragment); @@ -1636,14 +1640,14 @@ loaded: continue; case XML_ATTRIBUTE_NODE: - xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, + xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, XML_XINCLUDE_XPTR_RESULT, "XPointer selects an attribute: #%s\n", fragment); set->nodeTab[i] = NULL; continue; case XML_NAMESPACE_DECL: - xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, + xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, XML_XINCLUDE_XPTR_RESULT, "XPointer selects a namespace: #%s\n", fragment); @@ -1658,7 +1662,7 @@ loaded: case XML_ENTITY_DECL: case XML_XINCLUDE_START: case XML_XINCLUDE_END: - xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, + xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, XML_XINCLUDE_XPTR_RESULT, "XPointer selects unexpected nodes: #%s\n", fragment); @@ -1684,7 +1688,7 @@ loaded: /* * Do the xml:base fixup if needed */ - if ((doc != NULL) && (URL != NULL) && (xmlStrchr(URL, (xmlChar) '/')) && + if ((doc != NULL) && (URL != NULL) && (!(ctxt->parseFlags & XML_PARSE_NOBASEFIX)) && (!(doc->parseFlags & XML_PARSE_NOBASEFIX))) { xmlNodePtr node; @@ -1704,7 +1708,7 @@ loaded: */ curBase = xmlBuildRelativeURI(URL, ctxt->base); if (curBase == NULL) { /* Error return */ - xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, + xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, XML_XINCLUDE_HREF_URI, "trying to build relative URI from %s\n", URL); } else { @@ -1745,7 +1749,7 @@ loaded: xmlChar *relBase; relBase = xmlBuildURI(xmlBase, base); if (relBase == NULL) { /* error */ - xmlXIncludeErr(ctxt, + xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, XML_XINCLUDE_HREF_URI, "trying to rebuild base from %s\n", @@ -1782,7 +1786,7 @@ loaded: * @ctxt: the XInclude context * @url: the associated URL * @nr: the xinclude node number - * + * * Load the content, and store the result in the XInclude context * * Returns 0 in case of success, -1 in case of failure @@ -1798,6 +1802,7 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) { xmlCharEncoding enc = (xmlCharEncoding) 0; xmlParserCtxtPtr pctxt; xmlParserInputPtr inputStream; + int xinclude_multibyte_fallback_used = 0; /* * Check the URL and remove any fragment identifier @@ -1828,7 +1833,7 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) { * directly through ctxt->doc. */ if (URL[0] == 0) { - xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, + xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, XML_XINCLUDE_TEXT_DOCUMENT, "text serialization of document not available\n", NULL); xmlFree(URL); @@ -1894,30 +1899,39 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) { /* * Scan all chars from the resource and add the to the node */ +xinclude_multibyte_fallback: while (xmlParserInputBufferRead(buf, 128) > 0) { int len; const xmlChar *content; - content = xmlBufferContent(buf->buffer); - len = xmlBufferLength(buf->buffer); + content = xmlBufContent(buf->buffer); + len = xmlBufLength(buf->buffer); for (i = 0;i < len;) { int cur; int l; cur = xmlStringCurrentChar(NULL, &content[i], &l); if (!IS_CHAR(cur)) { - xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, - XML_XINCLUDE_INVALID_CHAR, - "%s contains invalid char\n", URL); - xmlFreeParserInputBuffer(buf); - xmlFree(URL); - return(-1); + /* Handle splitted multibyte char at buffer boundary */ + if (((len - i) < 4) && (!xinclude_multibyte_fallback_used)) { + xinclude_multibyte_fallback_used = 1; + xmlBufShrink(buf->buffer, i); + goto xinclude_multibyte_fallback; + } else { + xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, + XML_XINCLUDE_INVALID_CHAR, + "%s contains invalid char\n", URL); + xmlFreeParserInputBuffer(buf); + xmlFree(URL); + return(-1); + } } else { + xinclude_multibyte_fallback_used = 0; xmlNodeAddContentLen(node, &content[i], l); } i += l; } - xmlBufferShrink(buf->buffer, len); + xmlBufShrink(buf->buffer, len); } xmlFreeParserCtxt(pctxt); xmlXIncludeAddTxt(ctxt, node, URL); @@ -1937,7 +1951,7 @@ loaded: * @ctxt: the XInclude context * @fallback: the fallback node * @nr: the xinclude node number - * + * * Load the content of the fallback node, and store the result * in the XInclude context * @@ -1947,8 +1961,9 @@ static int xmlXIncludeLoadFallback(xmlXIncludeCtxtPtr ctxt, xmlNodePtr fallback, int nr) { xmlXIncludeCtxtPtr newctxt; int ret = 0; - - if ((fallback == NULL) || (ctxt == NULL)) + + if ((fallback == NULL) || (fallback->type == XML_NAMESPACE_DECL) || + (ctxt == NULL)) return(-1); if (fallback->children != NULL) { /* @@ -2033,7 +2048,7 @@ xmlXIncludeLoadNode(xmlXIncludeCtxtPtr ctxt, int nr) { href = xmlXIncludeGetProp(ctxt, cur, XINCLUDE_HREF); if (href == NULL) { href = xmlStrdup(BAD_CAST ""); /* @@@@ href is now optional */ - if (href == NULL) + if (href == NULL) return(-1); } parse = xmlXIncludeGetProp(ctxt, cur, XINCLUDE_PARSE); @@ -2078,7 +2093,7 @@ xmlXIncludeLoadNode(xmlXIncludeCtxtPtr ctxt, int nr) { xmlFree(eschref); } if (URI == NULL) { - xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, + xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, XML_XINCLUDE_HREF_URI, "failed build URL\n", NULL); if (parse != NULL) xmlFree(parse); @@ -2111,7 +2126,7 @@ xmlXIncludeLoadNode(xmlXIncludeCtxtPtr ctxt, int nr) { * Restore the original base before checking for fallback */ ctxt->base = oldBase; - + if (ret < 0) { xmlNodePtr children; @@ -2129,14 +2144,14 @@ xmlXIncludeLoadNode(xmlXIncludeCtxtPtr ctxt, int nr) { ((xmlStrEqual(children->ns->href, XINCLUDE_NS)) || (xmlStrEqual(children->ns->href, XINCLUDE_OLD_NS)))) { ret = xmlXIncludeLoadFallback(ctxt, children, nr); - if (ret == 0) + if (ret == 0) break; } children = children->next; } } if (ret < 0) { - xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, + xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, XML_XINCLUDE_NO_FALLBACK, "could not load %s, and no fallback was found\n", URI); @@ -2174,7 +2189,7 @@ xmlXIncludeIncludeNode(xmlXIncludeCtxtPtr ctxt, int nr) { if ((nr < 0) || (nr >= ctxt->incNr)) return(-1); cur = ctxt->incTab[nr]->ref; - if (cur == NULL) + if ((cur == NULL) || (cur->type == XML_NAMESPACE_DECL)) return(-1); /* @@ -2205,7 +2220,7 @@ xmlXIncludeIncludeNode(xmlXIncludeCtxtPtr ctxt, int nr) { tmp = tmp->next; } if (nb_elem > 1) { - xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, + xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, XML_XINCLUDE_MULTIPLE_ROOT, "XInclude error: would result in multiple root nodes\n", NULL); @@ -2252,7 +2267,7 @@ xmlXIncludeIncludeNode(xmlXIncludeCtxtPtr ctxt, int nr) { } } - + return(0); } @@ -2349,7 +2364,7 @@ xmlXIncludeDoProcess(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc, xmlNodePtr tree) { int ret = 0; int i, start; - if ((doc == NULL) || (tree == NULL)) + if ((doc == NULL) || (tree == NULL) || (tree->type == XML_NAMESPACE_DECL)) return(-1); if (ctxt == NULL) return(-1); @@ -2463,7 +2478,8 @@ xmlXIncludeProcessTreeFlagsData(xmlNodePtr tree, int flags, void *data) { xmlXIncludeCtxtPtr ctxt; int ret = 0; - if ((tree == NULL) || (tree->doc == NULL)) + if ((tree == NULL) || (tree->type == XML_NAMESPACE_DECL) || + (tree->doc == NULL)) return(-1); ctxt = xmlXIncludeNewContext(tree->doc); @@ -2548,7 +2564,8 @@ xmlXIncludeProcessTreeFlags(xmlNodePtr tree, int flags) { xmlXIncludeCtxtPtr ctxt; int ret = 0; - if ((tree == NULL) || (tree->doc == NULL)) + if ((tree == NULL) || (tree->type == XML_NAMESPACE_DECL) || + (tree->doc == NULL)) return(-1); ctxt = xmlXIncludeNewContext(tree->doc); if (ctxt == NULL) @@ -2592,7 +2609,8 @@ int xmlXIncludeProcessNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node) { int ret = 0; - if ((node == NULL) || (node->doc == NULL) || (ctxt == NULL)) + if ((node == NULL) || (node->type == XML_NAMESPACE_DECL) || + (node->doc == NULL) || (ctxt == NULL)) return(-1); ret = xmlXIncludeDoProcess(ctxt, node->doc, node); if ((ret >= 0) && (ctxt->nbErrors > 0)) |