Index: third_party/libxml/src/xinclude.c |
diff --git a/third_party/libxml/src/xinclude.c b/third_party/libxml/src/xinclude.c |
index 2916ffaab10427842c9639da8ae3fb207c420ce2..ff3dafbb9860e05ff205594c5b72deec9700ee54 100644 |
--- a/third_party/libxml/src/xinclude.c |
+++ b/third_party/libxml/src/xinclude.c |
@@ -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 |
@@ -1796,6 +1800,9 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) { |
int i; |
xmlChar *encoding = NULL; |
xmlCharEncoding enc = (xmlCharEncoding) 0; |
+ xmlParserCtxtPtr pctxt; |
+ xmlParserInputPtr inputStream; |
+ int xinclude_multibyte_fallback_used = 0; |
/* |
* Check the URL and remove any fragment identifier |
@@ -1826,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); |
@@ -1870,43 +1877,65 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) { |
/* |
* Load it. |
*/ |
- buf = xmlParserInputBufferCreateFilename((const char *)URL, enc); |
+ pctxt = xmlNewParserCtxt(); |
+ inputStream = xmlLoadExternalEntity((const char*)URL, NULL, pctxt); |
+ if(inputStream == NULL) { |
+ xmlFreeParserCtxt(pctxt); |
+ xmlFree(URL); |
+ return(-1); |
+ } |
+ buf = inputStream->buf; |
if (buf == NULL) { |
+ xmlFreeInputStream (inputStream); |
+ xmlFreeParserCtxt(pctxt); |
xmlFree(URL); |
return(-1); |
} |
+ if (buf->encoder) |
+ xmlCharEncCloseFunc(buf->encoder); |
+ buf->encoder = xmlGetCharEncodingHandler(enc); |
node = xmlNewText(NULL); |
/* |
* 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); |
} |
- xmlFreeParserInputBuffer(buf); |
+ xmlFreeParserCtxt(pctxt); |
xmlXIncludeAddTxt(ctxt, node, URL); |
+ xmlFreeInputStream(inputStream); |
loaded: |
/* |
@@ -1922,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 |
* |
@@ -1932,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) { |
/* |
@@ -2018,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); |
@@ -2063,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); |
@@ -2096,7 +2126,7 @@ xmlXIncludeLoadNode(xmlXIncludeCtxtPtr ctxt, int nr) { |
* Restore the original base before checking for fallback |
*/ |
ctxt->base = oldBase; |
- |
+ |
if (ret < 0) { |
xmlNodePtr children; |
@@ -2114,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); |
@@ -2159,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); |
/* |
@@ -2190,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); |
@@ -2237,7 +2267,7 @@ xmlXIncludeIncludeNode(xmlXIncludeCtxtPtr ctxt, int nr) { |
} |
} |
- |
+ |
return(0); |
} |
@@ -2334,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); |
@@ -2448,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); |
@@ -2533,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) |
@@ -2577,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)) |