summaryrefslogtreecommitdiff
path: root/xinclude.c
diff options
context:
space:
mode:
authorAron Xu <aron@debian.org>2014-10-26 07:02:25 +0800
committerAron Xu <aron@debian.org>2014-10-26 07:02:25 +0800
commit3871a83a5f0aebd8c00879eab14fe901c93dbfcf (patch)
treeb022967f880b7fb1e56c8cc4c3f200d6ffbc9efd /xinclude.c
parent7042e17490515a990a45aa7237d11bc49ab0eaf0 (diff)
downloadlibxml2-3871a83a5f0aebd8c00879eab14fe901c93dbfcf.tar.gz
Imported Upstream version 2.9.2+dfsg1
Diffstat (limited to 'xinclude.c')
-rw-r--r--xinclude.c132
1 files changed, 75 insertions, 57 deletions
diff --git a/xinclude.c b/xinclude.c
index d01f978..ff3dafb 100644
--- a/xinclude.c
+++ b/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
@@ -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))