mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2025-07-12 08:59:34 +03:00
xinclude: Report malloc failures
Fix many places where malloc failures aren't reported. Introduce a new API function xmlXIncludeGetLastError.
This commit is contained in:
@ -115,6 +115,8 @@ XMLPUBFUN xmlXIncludeCtxtPtr
|
|||||||
XMLPUBFUN int
|
XMLPUBFUN int
|
||||||
xmlXIncludeSetFlags (xmlXIncludeCtxtPtr ctxt,
|
xmlXIncludeSetFlags (xmlXIncludeCtxtPtr ctxt,
|
||||||
int flags);
|
int flags);
|
||||||
|
XMLPUBFUN int
|
||||||
|
xmlXIncludeGetLastError (xmlXIncludeCtxtPtr ctxt);
|
||||||
XMLPUBFUN void
|
XMLPUBFUN void
|
||||||
xmlXIncludeFreeContext (xmlXIncludeCtxtPtr ctxt);
|
xmlXIncludeFreeContext (xmlXIncludeCtxtPtr ctxt);
|
||||||
XMLPUBFUN int
|
XMLPUBFUN int
|
||||||
|
588
xinclude.c
588
xinclude.c
@ -89,6 +89,7 @@ struct _xmlXIncludeCtxt {
|
|||||||
|
|
||||||
int nbErrors; /* the number of errors detected */
|
int nbErrors; /* the number of errors detected */
|
||||||
int fatalErr; /* abort processing */
|
int fatalErr; /* abort processing */
|
||||||
|
int errNo; /* error code */
|
||||||
int legacy; /* using XINCLUDE_OLD_NS */
|
int legacy; /* using XINCLUDE_OLD_NS */
|
||||||
int parseFlags; /* the flags used for parsing XML documents */
|
int parseFlags; /* the flags used for parsing XML documents */
|
||||||
xmlChar * base; /* the current xml:base */
|
xmlChar * base; /* the current xml:base */
|
||||||
@ -100,6 +101,8 @@ struct _xmlXIncludeCtxt {
|
|||||||
#endif
|
#endif
|
||||||
int depth; /* recursion depth */
|
int depth; /* recursion depth */
|
||||||
int isStream; /* streaming mode */
|
int isStream; /* streaming mode */
|
||||||
|
|
||||||
|
xmlXPathContextPtr xpctxt;
|
||||||
};
|
};
|
||||||
|
|
||||||
static xmlXIncludeRefPtr
|
static xmlXIncludeRefPtr
|
||||||
@ -128,12 +131,13 @@ static void
|
|||||||
xmlXIncludeErrMemory(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node,
|
xmlXIncludeErrMemory(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node,
|
||||||
const char *extra)
|
const char *extra)
|
||||||
{
|
{
|
||||||
if (ctxt != NULL)
|
ctxt->nbErrors++;
|
||||||
ctxt->nbErrors++;
|
|
||||||
__xmlRaiseError(NULL, NULL, NULL, ctxt, node, XML_FROM_XINCLUDE,
|
__xmlRaiseError(NULL, NULL, NULL, ctxt, node, XML_FROM_XINCLUDE,
|
||||||
XML_ERR_NO_MEMORY, XML_ERR_ERROR, NULL, 0,
|
XML_ERR_NO_MEMORY, XML_ERR_ERROR, NULL, 0,
|
||||||
extra, NULL, NULL, 0, 0,
|
extra, NULL, NULL, 0, 0,
|
||||||
"Memory allocation failed : %s\n", extra);
|
"Memory allocation failed : %s\n", extra);
|
||||||
|
ctxt->errNo = XML_ERR_NO_MEMORY;
|
||||||
|
ctxt->fatalErr = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -149,12 +153,21 @@ static void LIBXML_ATTR_FORMAT(4,0)
|
|||||||
xmlXIncludeErr(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node, int error,
|
xmlXIncludeErr(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node, int error,
|
||||||
const char *msg, const xmlChar *extra)
|
const char *msg, const xmlChar *extra)
|
||||||
{
|
{
|
||||||
if (ctxt != NULL)
|
int res;
|
||||||
ctxt->nbErrors++;
|
|
||||||
__xmlRaiseError(NULL, NULL, NULL, ctxt, node, XML_FROM_XINCLUDE,
|
if (ctxt->fatalErr != 0)
|
||||||
error, XML_ERR_ERROR, NULL, 0,
|
return;
|
||||||
(const char *) extra, NULL, NULL, 0, 0,
|
ctxt->nbErrors++;
|
||||||
msg, (const char *) extra);
|
res = __xmlRaiseError(NULL, NULL, NULL, ctxt, node, XML_FROM_XINCLUDE,
|
||||||
|
error, XML_ERR_ERROR, NULL, 0,
|
||||||
|
(const char *) extra, NULL, NULL, 0, 0,
|
||||||
|
msg, (const char *) extra);
|
||||||
|
if (res < 0) {
|
||||||
|
ctxt->errNo = XML_ERR_NO_MEMORY;
|
||||||
|
ctxt->fatalErr = 1;
|
||||||
|
} else {
|
||||||
|
ctxt->errNo = error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
@ -193,15 +206,20 @@ xmlXIncludeGetProp(xmlXIncludeCtxtPtr ctxt, xmlNodePtr cur,
|
|||||||
const xmlChar *name) {
|
const xmlChar *name) {
|
||||||
xmlChar *ret;
|
xmlChar *ret;
|
||||||
|
|
||||||
ret = xmlGetNsProp(cur, XINCLUDE_NS, name);
|
if (xmlNodeGetAttrValue(cur, name, XINCLUDE_NS, &ret) < 0)
|
||||||
|
xmlXIncludeErrMemory(ctxt, NULL, NULL);
|
||||||
if (ret != NULL)
|
if (ret != NULL)
|
||||||
return(ret);
|
return(ret);
|
||||||
|
|
||||||
if (ctxt->legacy != 0) {
|
if (ctxt->legacy != 0) {
|
||||||
ret = xmlGetNsProp(cur, XINCLUDE_OLD_NS, name);
|
if (xmlNodeGetAttrValue(cur, name, XINCLUDE_OLD_NS, &ret) < 0)
|
||||||
if (ret != NULL)
|
xmlXIncludeErrMemory(ctxt, NULL, NULL);
|
||||||
return(ret);
|
if (ret != NULL)
|
||||||
|
return(ret);
|
||||||
}
|
}
|
||||||
ret = xmlGetProp(cur, name);
|
|
||||||
|
if (xmlNodeGetAttrValue(cur, name, NULL, &ret) < 0)
|
||||||
|
xmlXIncludeErrMemory(ctxt, NULL, NULL);
|
||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@ -242,10 +260,16 @@ xmlXIncludeNewRef(xmlXIncludeCtxtPtr ctxt, const xmlChar *URI,
|
|||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
memset(ret, 0, sizeof(xmlXIncludeRef));
|
memset(ret, 0, sizeof(xmlXIncludeRef));
|
||||||
if (URI == NULL)
|
if (URI == NULL) {
|
||||||
ret->URI = NULL;
|
ret->URI = NULL;
|
||||||
else
|
} else {
|
||||||
ret->URI = xmlStrdup(URI);
|
ret->URI = xmlStrdup(URI);
|
||||||
|
if (ret->URI == NULL) {
|
||||||
|
xmlXIncludeErrMemory(ctxt, elem, NULL);
|
||||||
|
xmlXIncludeFreeRef(ret);
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
ret->fragment = NULL;
|
ret->fragment = NULL;
|
||||||
ret->elem = elem;
|
ret->elem = elem;
|
||||||
ret->xml = 0;
|
ret->xml = 0;
|
||||||
@ -287,11 +311,8 @@ xmlXIncludeNewContext(xmlDocPtr doc) {
|
|||||||
if (doc == NULL)
|
if (doc == NULL)
|
||||||
return(NULL);
|
return(NULL);
|
||||||
ret = (xmlXIncludeCtxtPtr) xmlMalloc(sizeof(xmlXIncludeCtxt));
|
ret = (xmlXIncludeCtxtPtr) xmlMalloc(sizeof(xmlXIncludeCtxt));
|
||||||
if (ret == NULL) {
|
if (ret == NULL)
|
||||||
xmlXIncludeErrMemory(NULL, (xmlNodePtr) doc,
|
|
||||||
"creating XInclude context");
|
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
|
||||||
memset(ret, 0, sizeof(xmlXIncludeCtxt));
|
memset(ret, 0, sizeof(xmlXIncludeCtxt));
|
||||||
ret->doc = doc;
|
ret->doc = doc;
|
||||||
ret->incNr = 0;
|
ret->incNr = 0;
|
||||||
@ -336,9 +357,61 @@ xmlXIncludeFreeContext(xmlXIncludeCtxtPtr ctxt) {
|
|||||||
if (ctxt->base != NULL) {
|
if (ctxt->base != NULL) {
|
||||||
xmlFree(ctxt->base);
|
xmlFree(ctxt->base);
|
||||||
}
|
}
|
||||||
|
if (ctxt->xpctxt != NULL)
|
||||||
|
xmlXPathFreeContext(ctxt->xpctxt);
|
||||||
xmlFree(ctxt);
|
xmlFree(ctxt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static xmlChar *
|
||||||
|
xmlXIncludeBuildURI(xmlXIncludeCtxtPtr ctxt, xmlNodePtr cur,
|
||||||
|
const xmlChar *base, int *xmlOut) {
|
||||||
|
xmlChar *href = NULL;
|
||||||
|
xmlChar *parse = NULL;
|
||||||
|
xmlChar *URI = NULL;
|
||||||
|
int xml = 1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* read the attributes
|
||||||
|
*/
|
||||||
|
href = xmlXIncludeGetProp(ctxt, cur, XINCLUDE_HREF);
|
||||||
|
if (href == NULL) {
|
||||||
|
href = xmlStrdup(BAD_CAST ""); /* @@@@ href is now optional */
|
||||||
|
if (href == NULL) {
|
||||||
|
xmlXIncludeErrMemory(ctxt, cur, NULL);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
parse = xmlXIncludeGetProp(ctxt, cur, XINCLUDE_PARSE);
|
||||||
|
if (parse != NULL) {
|
||||||
|
if (xmlStrEqual(parse, XINCLUDE_PARSE_XML))
|
||||||
|
xml = 1;
|
||||||
|
else if (xmlStrEqual(parse, XINCLUDE_PARSE_TEXT))
|
||||||
|
xml = 0;
|
||||||
|
else {
|
||||||
|
xmlXIncludeErr(ctxt, cur, XML_XINCLUDE_PARSE_VALUE,
|
||||||
|
"invalid value %s for 'parse'\n", parse);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* compute the URI
|
||||||
|
*/
|
||||||
|
if (xmlBuildURISafe(href, base, &URI) < 0) {
|
||||||
|
xmlXIncludeErrMemory(ctxt, NULL, NULL);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if (URI == NULL)
|
||||||
|
xmlXIncludeErr(ctxt, cur, XML_XINCLUDE_HREF_URI,
|
||||||
|
"failed build URL\n", NULL);
|
||||||
|
|
||||||
|
error:
|
||||||
|
xmlFree(href);
|
||||||
|
xmlFree(parse);
|
||||||
|
*xmlOut = xml;
|
||||||
|
return(URI);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* xmlXIncludeParseFile:
|
* xmlXIncludeParseFile:
|
||||||
* @ctxt: the XInclude context
|
* @ctxt: the XInclude context
|
||||||
@ -348,7 +421,7 @@ xmlXIncludeFreeContext(xmlXIncludeCtxtPtr ctxt) {
|
|||||||
*/
|
*/
|
||||||
static xmlDocPtr
|
static xmlDocPtr
|
||||||
xmlXIncludeParseFile(xmlXIncludeCtxtPtr ctxt, const char *URL) {
|
xmlXIncludeParseFile(xmlXIncludeCtxtPtr ctxt, const char *URL) {
|
||||||
xmlDocPtr ret;
|
xmlDocPtr ret = NULL;
|
||||||
xmlParserCtxtPtr pctxt;
|
xmlParserCtxtPtr pctxt;
|
||||||
xmlParserInputPtr inputStream;
|
xmlParserInputPtr inputStream;
|
||||||
|
|
||||||
@ -383,15 +456,18 @@ xmlXIncludeParseFile(xmlXIncludeCtxtPtr ctxt, const char *URL) {
|
|||||||
URL = "./-";
|
URL = "./-";
|
||||||
|
|
||||||
inputStream = xmlLoadExternalEntity(URL, NULL, pctxt);
|
inputStream = xmlLoadExternalEntity(URL, NULL, pctxt);
|
||||||
if (inputStream == NULL) {
|
if (inputStream == NULL)
|
||||||
xmlFreeParserCtxt(pctxt);
|
goto error;
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
inputPush(pctxt, inputStream);
|
inputPush(pctxt, inputStream);
|
||||||
|
|
||||||
if (pctxt->directory == NULL)
|
if (pctxt->directory == NULL) {
|
||||||
pctxt->directory = xmlParserGetDirectory(URL);
|
pctxt->directory = xmlParserGetDirectory(URL);
|
||||||
|
if (pctxt->directory == NULL) {
|
||||||
|
xmlXIncludeErrMemory(ctxt, NULL, NULL);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pctxt->loadsubset |= XML_DETECT_IDS;
|
pctxt->loadsubset |= XML_DETECT_IDS;
|
||||||
|
|
||||||
@ -406,6 +482,10 @@ xmlXIncludeParseFile(xmlXIncludeCtxtPtr ctxt, const char *URL) {
|
|||||||
xmlFreeDoc(pctxt->myDoc);
|
xmlFreeDoc(pctxt->myDoc);
|
||||||
pctxt->myDoc = NULL;
|
pctxt->myDoc = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
error:
|
||||||
|
if (pctxt->errNo == XML_ERR_NO_MEMORY)
|
||||||
|
xmlXIncludeErrMemory(ctxt, NULL, NULL);
|
||||||
xmlFreeParserCtxt(pctxt);
|
xmlFreeParserCtxt(pctxt);
|
||||||
|
|
||||||
return(ret);
|
return(ret);
|
||||||
@ -424,88 +504,37 @@ xmlXIncludeAddNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr cur) {
|
|||||||
xmlURIPtr uri;
|
xmlURIPtr uri;
|
||||||
xmlChar *URL;
|
xmlChar *URL;
|
||||||
xmlChar *fragment = NULL;
|
xmlChar *fragment = NULL;
|
||||||
xmlChar *href;
|
|
||||||
xmlChar *parse;
|
|
||||||
xmlChar *base;
|
xmlChar *base;
|
||||||
xmlChar *URI;
|
xmlChar *URI;
|
||||||
int xml = 1;
|
int xml;
|
||||||
int local = 0;
|
int local = 0;
|
||||||
|
int res;
|
||||||
|
|
||||||
if (ctxt == NULL)
|
if (ctxt == NULL)
|
||||||
return(NULL);
|
return(NULL);
|
||||||
if (cur == NULL)
|
if (cur == NULL)
|
||||||
return(NULL);
|
return(NULL);
|
||||||
|
|
||||||
/*
|
if (xmlNodeGetBaseSafe(ctxt->doc, cur, &base) < 0) {
|
||||||
* read the attributes
|
xmlXIncludeErrMemory(ctxt, NULL, NULL);
|
||||||
*/
|
return(NULL);
|
||||||
href = xmlXIncludeGetProp(ctxt, cur, XINCLUDE_HREF);
|
|
||||||
if (href == NULL) {
|
|
||||||
href = xmlStrdup(BAD_CAST ""); /* @@@@ href is now optional */
|
|
||||||
if (href == NULL)
|
|
||||||
return(NULL);
|
|
||||||
}
|
}
|
||||||
parse = xmlXIncludeGetProp(ctxt, cur, XINCLUDE_PARSE);
|
URI = xmlXIncludeBuildURI(ctxt, cur, base, &xml);
|
||||||
if (parse != NULL) {
|
xmlFree(base);
|
||||||
if (xmlStrEqual(parse, XINCLUDE_PARSE_XML))
|
if (URI == NULL)
|
||||||
xml = 1;
|
|
||||||
else if (xmlStrEqual(parse, XINCLUDE_PARSE_TEXT))
|
|
||||||
xml = 0;
|
|
||||||
else {
|
|
||||||
xmlXIncludeErr(ctxt, cur, XML_XINCLUDE_PARSE_VALUE,
|
|
||||||
"invalid value %s for 'parse'\n", parse);
|
|
||||||
if (href != NULL)
|
|
||||||
xmlFree(href);
|
|
||||||
if (parse != NULL)
|
|
||||||
xmlFree(parse);
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* compute the URI
|
|
||||||
*/
|
|
||||||
base = xmlNodeGetBase(ctxt->doc, cur);
|
|
||||||
if (base == NULL) {
|
|
||||||
URI = xmlBuildURI(href, ctxt->doc->URL);
|
|
||||||
} else {
|
|
||||||
URI = xmlBuildURI(href, base);
|
|
||||||
}
|
|
||||||
if (URI == NULL) {
|
|
||||||
xmlChar *escbase;
|
|
||||||
xmlChar *eschref;
|
|
||||||
/*
|
|
||||||
* Some escaping may be needed
|
|
||||||
*/
|
|
||||||
escbase = xmlURIEscape(base);
|
|
||||||
eschref = xmlURIEscape(href);
|
|
||||||
URI = xmlBuildURI(eschref, escbase);
|
|
||||||
if (escbase != NULL)
|
|
||||||
xmlFree(escbase);
|
|
||||||
if (eschref != NULL)
|
|
||||||
xmlFree(eschref);
|
|
||||||
}
|
|
||||||
if (parse != NULL)
|
|
||||||
xmlFree(parse);
|
|
||||||
if (href != NULL)
|
|
||||||
xmlFree(href);
|
|
||||||
if (base != NULL)
|
|
||||||
xmlFree(base);
|
|
||||||
if (URI == NULL) {
|
|
||||||
xmlXIncludeErr(ctxt, cur, XML_XINCLUDE_HREF_URI,
|
|
||||||
"failed build URL\n", NULL);
|
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
|
||||||
fragment = xmlXIncludeGetProp(ctxt, cur, XINCLUDE_PARSE_XPOINTER);
|
fragment = xmlXIncludeGetProp(ctxt, cur, XINCLUDE_PARSE_XPOINTER);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check the URL and remove any fragment identifier
|
* Check the URL and remove any fragment identifier
|
||||||
*/
|
*/
|
||||||
uri = xmlParseURI((const char *)URI);
|
res = xmlParseURISafe((const char *)URI, &uri);
|
||||||
if (uri == NULL) {
|
if (uri == NULL) {
|
||||||
xmlXIncludeErr(ctxt, cur, XML_XINCLUDE_HREF_URI,
|
if (res < 0)
|
||||||
"invalid value URI %s\n", URI);
|
xmlXIncludeErrMemory(ctxt, NULL, NULL);
|
||||||
|
else
|
||||||
|
xmlXIncludeErr(ctxt, cur, XML_XINCLUDE_HREF_URI,
|
||||||
|
"invalid value URI %s\n", URI);
|
||||||
if (fragment != NULL)
|
if (fragment != NULL)
|
||||||
xmlFree(fragment);
|
xmlFree(fragment);
|
||||||
xmlFree(URI);
|
xmlFree(URI);
|
||||||
@ -534,8 +563,7 @@ xmlXIncludeAddNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr cur) {
|
|||||||
URL = xmlSaveUri(uri);
|
URL = xmlSaveUri(uri);
|
||||||
xmlFreeURI(uri);
|
xmlFreeURI(uri);
|
||||||
if (URL == NULL) {
|
if (URL == NULL) {
|
||||||
xmlXIncludeErr(ctxt, cur, XML_XINCLUDE_HREF_URI,
|
xmlXIncludeErrMemory(ctxt, NULL, NULL);
|
||||||
"invalid value URI %s\n", URI);
|
|
||||||
if (fragment != NULL)
|
if (fragment != NULL)
|
||||||
xmlFree(fragment);
|
xmlFree(fragment);
|
||||||
xmlFree(URI);
|
xmlFree(URI);
|
||||||
@ -666,13 +694,17 @@ xmlXIncludeCopyNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr elem,
|
|||||||
if (ref->inc != NULL) {
|
if (ref->inc != NULL) {
|
||||||
copy = xmlStaticCopyNodeList(ref->inc, ctxt->doc,
|
copy = xmlStaticCopyNodeList(ref->inc, ctxt->doc,
|
||||||
insertParent);
|
insertParent);
|
||||||
if (copy == NULL)
|
if (copy == NULL) {
|
||||||
|
xmlXIncludeErrMemory(ctxt, NULL, NULL);
|
||||||
goto error;
|
goto error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
copy = xmlStaticCopyNode(cur, ctxt->doc, insertParent, 2);
|
copy = xmlStaticCopyNode(cur, ctxt->doc, insertParent, 2);
|
||||||
if (copy == NULL)
|
if (copy == NULL) {
|
||||||
|
xmlXIncludeErrMemory(ctxt, NULL, NULL);
|
||||||
goto error;
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
recurse = (cur->type != XML_ENTITY_REF_NODE) &&
|
recurse = (cur->type != XML_ENTITY_REF_NODE) &&
|
||||||
(cur->children != NULL);
|
(cur->children != NULL);
|
||||||
@ -1112,32 +1144,36 @@ xmlXIncludeMergeEntity(void *payload, void *vdata,
|
|||||||
case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
|
case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ret = xmlAddDocEntity(doc, ent->name, ent->etype, ent->ExternalID,
|
prev = xmlGetDocEntity(doc, ent->name);
|
||||||
ent->SystemID, ent->content);
|
if (prev == NULL) {
|
||||||
if (ret != NULL) {
|
ret = xmlAddDocEntity(doc, ent->name, ent->etype, ent->ExternalID,
|
||||||
if (ent->URI != NULL)
|
ent->SystemID, ent->content);
|
||||||
|
if (ret == NULL) {
|
||||||
|
xmlXIncludeErrMemory(ctxt, NULL, NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (ent->URI != NULL) {
|
||||||
ret->URI = xmlStrdup(ent->URI);
|
ret->URI = xmlStrdup(ent->URI);
|
||||||
|
if (ret->URI == 0)
|
||||||
|
xmlXIncludeErrMemory(ctxt, NULL, NULL);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
prev = xmlGetDocEntity(doc, ent->name);
|
if (ent->etype != prev->etype)
|
||||||
if (prev != NULL) {
|
goto error;
|
||||||
if (ent->etype != prev->etype)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
if ((ent->SystemID != NULL) && (prev->SystemID != NULL)) {
|
if ((ent->SystemID != NULL) && (prev->SystemID != NULL)) {
|
||||||
if (!xmlStrEqual(ent->SystemID, prev->SystemID))
|
if (!xmlStrEqual(ent->SystemID, prev->SystemID))
|
||||||
goto error;
|
goto error;
|
||||||
} else if ((ent->ExternalID != NULL) &&
|
} else if ((ent->ExternalID != NULL) &&
|
||||||
(prev->ExternalID != NULL)) {
|
(prev->ExternalID != NULL)) {
|
||||||
if (!xmlStrEqual(ent->ExternalID, prev->ExternalID))
|
if (!xmlStrEqual(ent->ExternalID, prev->ExternalID))
|
||||||
goto error;
|
goto error;
|
||||||
} else if ((ent->content != NULL) && (prev->content != NULL)) {
|
} else if ((ent->content != NULL) && (prev->content != NULL)) {
|
||||||
if (!xmlStrEqual(ent->content, prev->content))
|
if (!xmlStrEqual(ent->content, prev->content))
|
||||||
goto error;
|
goto error;
|
||||||
} else {
|
} else {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
error:
|
error:
|
||||||
@ -1245,7 +1281,10 @@ xmlXIncludeLoadDoc(xmlXIncludeCtxtPtr ctxt, const xmlChar *url,
|
|||||||
/*
|
/*
|
||||||
* Check the URL and remove any fragment identifier
|
* Check the URL and remove any fragment identifier
|
||||||
*/
|
*/
|
||||||
uri = xmlParseURI((const char *)url);
|
if (xmlParseURISafe((const char *)url, &uri) < 0) {
|
||||||
|
xmlXIncludeErrMemory(ctxt, NULL, NULL);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
if (uri == NULL) {
|
if (uri == NULL) {
|
||||||
xmlXIncludeErr(ctxt, ref->elem, XML_XINCLUDE_HREF_URI,
|
xmlXIncludeErr(ctxt, ref->elem, XML_XINCLUDE_HREF_URI,
|
||||||
"invalid value URI %s\n", url);
|
"invalid value URI %s\n", url);
|
||||||
@ -1258,12 +1297,14 @@ xmlXIncludeLoadDoc(xmlXIncludeCtxtPtr ctxt, const xmlChar *url,
|
|||||||
if (ref->fragment != NULL) {
|
if (ref->fragment != NULL) {
|
||||||
if (fragment != NULL) xmlFree(fragment);
|
if (fragment != NULL) xmlFree(fragment);
|
||||||
fragment = xmlStrdup(ref->fragment);
|
fragment = xmlStrdup(ref->fragment);
|
||||||
|
if (fragment == NULL) {
|
||||||
|
xmlXIncludeErrMemory(ctxt, ref->elem, NULL);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
URL = xmlSaveUri(uri);
|
URL = xmlSaveUri(uri);
|
||||||
xmlFreeURI(uri);
|
|
||||||
if (URL == NULL) {
|
if (URL == NULL) {
|
||||||
xmlXIncludeErr(ctxt, ref->elem, XML_XINCLUDE_HREF_URI,
|
xmlXIncludeErrMemory(ctxt, NULL, NULL);
|
||||||
"invalid value URI %s\n", url);
|
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1333,11 +1374,16 @@ xmlXIncludeLoadDoc(xmlXIncludeCtxtPtr ctxt, const xmlChar *url,
|
|||||||
ctxt->urlMax = newSize;
|
ctxt->urlMax = newSize;
|
||||||
ctxt->urlTab = tmp;
|
ctxt->urlTab = tmp;
|
||||||
}
|
}
|
||||||
cacheNr = ctxt->urlNr++;
|
cache = &ctxt->urlTab[ctxt->urlNr];
|
||||||
cache = &ctxt->urlTab[cacheNr];
|
|
||||||
cache->doc = doc;
|
cache->doc = doc;
|
||||||
cache->url = xmlStrdup(URL);
|
cache->url = xmlStrdup(URL);
|
||||||
|
if (cache->url == NULL) {
|
||||||
|
xmlXIncludeErrMemory(ctxt, ref->elem, NULL);
|
||||||
|
xmlFreeDoc(doc);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
cache->expanding = 0;
|
cache->expanding = 0;
|
||||||
|
cacheNr = ctxt->urlNr++;
|
||||||
|
|
||||||
if (doc == NULL)
|
if (doc == NULL)
|
||||||
goto error;
|
goto error;
|
||||||
@ -1347,10 +1393,14 @@ xmlXIncludeLoadDoc(xmlXIncludeCtxtPtr ctxt, const xmlChar *url,
|
|||||||
* To check for this, we compare the URL with that of the doc
|
* To check for this, we compare the URL with that of the doc
|
||||||
* and change it if they disagree (bug 146988).
|
* and change it if they disagree (bug 146988).
|
||||||
*/
|
*/
|
||||||
if (!xmlStrEqual(URL, doc->URL)) {
|
if ((doc->URL != NULL) && (!xmlStrEqual(URL, doc->URL))) {
|
||||||
xmlFree(URL);
|
xmlFree(URL);
|
||||||
URL = xmlStrdup(doc->URL);
|
URL = xmlStrdup(doc->URL);
|
||||||
}
|
if (URL == NULL) {
|
||||||
|
xmlXIncludeErrMemory(ctxt, ref->elem, NULL);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make sure we have all entities fixed up
|
* Make sure we have all entities fixed up
|
||||||
@ -1382,6 +1432,9 @@ loaded:
|
|||||||
* Add the top children list as the replacement copy.
|
* Add the top children list as the replacement copy.
|
||||||
*/
|
*/
|
||||||
ref->inc = xmlDocCopyNode(xmlDocGetRootElement(doc), ctxt->doc, 1);
|
ref->inc = xmlDocCopyNode(xmlDocGetRootElement(doc), ctxt->doc, 1);
|
||||||
|
if (ref->inc == NULL) {
|
||||||
|
xmlXIncludeErrMemory(ctxt, ref->elem, NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#ifdef LIBXML_XPTR_ENABLED
|
#ifdef LIBXML_XPTR_ENABLED
|
||||||
else {
|
else {
|
||||||
@ -1390,7 +1443,6 @@ loaded:
|
|||||||
* as the replacement copy.
|
* as the replacement copy.
|
||||||
*/
|
*/
|
||||||
xmlXPathObjectPtr xptr;
|
xmlXPathObjectPtr xptr;
|
||||||
xmlXPathContextPtr xptrctxt;
|
|
||||||
xmlNodeSetPtr set;
|
xmlNodeSetPtr set;
|
||||||
|
|
||||||
if (ctxt->isStream && doc == ctxt->doc) {
|
if (ctxt->isStream && doc == ctxt->doc) {
|
||||||
@ -1400,18 +1452,24 @@ loaded:
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
xptrctxt = xmlXPtrNewContext(doc, NULL, NULL);
|
if (ctxt->xpctxt == NULL) {
|
||||||
if (xptrctxt == NULL) {
|
ctxt->xpctxt = xmlXPtrNewContext(doc, NULL, NULL);
|
||||||
xmlXIncludeErr(ctxt, ref->elem, XML_XINCLUDE_XPTR_FAILED,
|
if (ctxt->xpctxt == NULL) {
|
||||||
"could not create XPointer context\n", NULL);
|
xmlXIncludeErrMemory(ctxt, ref->elem, NULL);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
xptr = xmlXPtrEval(fragment, xptrctxt);
|
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
||||||
|
ctxt->xpctxt->opLimit = 100000;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
xptr = xmlXPtrEval(fragment, ctxt->xpctxt);
|
||||||
if (xptr == NULL) {
|
if (xptr == NULL) {
|
||||||
xmlXIncludeErr(ctxt, ref->elem, XML_XINCLUDE_XPTR_FAILED,
|
if (ctxt->xpctxt->lastError.code == XML_ERR_NO_MEMORY)
|
||||||
"XPointer evaluation failed: #%s\n",
|
xmlXIncludeErrMemory(ctxt, ref->elem, NULL);
|
||||||
fragment);
|
else
|
||||||
xmlXPathFreeContext(xptrctxt);
|
xmlXIncludeErr(ctxt, ref->elem, XML_XINCLUDE_XPTR_FAILED,
|
||||||
|
"XPointer evaluation failed: #%s\n",
|
||||||
|
fragment);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
switch (xptr->type) {
|
switch (xptr->type) {
|
||||||
@ -1428,13 +1486,11 @@ loaded:
|
|||||||
"XPointer is not a range: #%s\n",
|
"XPointer is not a range: #%s\n",
|
||||||
fragment);
|
fragment);
|
||||||
xmlXPathFreeObject(xptr);
|
xmlXPathFreeObject(xptr);
|
||||||
xmlXPathFreeContext(xptrctxt);
|
|
||||||
goto error;
|
goto error;
|
||||||
case XPATH_NODESET:
|
case XPATH_NODESET:
|
||||||
if ((xptr->nodesetval == NULL) ||
|
if ((xptr->nodesetval == NULL) ||
|
||||||
(xptr->nodesetval->nodeNr <= 0)) {
|
(xptr->nodesetval->nodeNr <= 0)) {
|
||||||
xmlXPathFreeObject(xptr);
|
xmlXPathFreeObject(xptr);
|
||||||
xmlXPathFreeContext(xptrctxt);
|
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1496,7 +1552,6 @@ loaded:
|
|||||||
}
|
}
|
||||||
ref->inc = xmlXIncludeCopyXPointer(ctxt, xptr);
|
ref->inc = xmlXIncludeCopyXPointer(ctxt, xptr);
|
||||||
xmlXPathFreeObject(xptr);
|
xmlXPathFreeObject(xptr);
|
||||||
xmlXPathFreeContext(xptrctxt);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1520,8 +1575,9 @@ loaded:
|
|||||||
* No xml:base on the xinclude node, so we check whether the
|
* No xml:base on the xinclude node, so we check whether the
|
||||||
* URI base is different than (relative to) the context base
|
* URI base is different than (relative to) the context base
|
||||||
*/
|
*/
|
||||||
curBase = xmlBuildRelativeURI(URL, ctxt->base);
|
if (xmlBuildRelativeURISafe(URL, ctxt->base, &curBase) < 0) {
|
||||||
if (curBase == NULL) { /* Error return */
|
xmlXIncludeErrMemory(ctxt, ref->elem, NULL);
|
||||||
|
} else if (curBase == NULL) {
|
||||||
xmlXIncludeErr(ctxt, ref->elem, XML_XINCLUDE_HREF_URI,
|
xmlXIncludeErr(ctxt, ref->elem, XML_XINCLUDE_HREF_URI,
|
||||||
"trying to build relative URI from %s\n", URL);
|
"trying to build relative URI from %s\n", URL);
|
||||||
} else {
|
} else {
|
||||||
@ -1537,10 +1593,15 @@ loaded:
|
|||||||
while (node != NULL) {
|
while (node != NULL) {
|
||||||
/* Only work on element nodes */
|
/* Only work on element nodes */
|
||||||
if (node->type == XML_ELEMENT_NODE) {
|
if (node->type == XML_ELEMENT_NODE) {
|
||||||
curBase = xmlNodeGetBase(node->doc, node);
|
int res = 0;
|
||||||
|
|
||||||
|
if (xmlNodeGetBaseSafe(node->doc, node, &curBase) < 0) {
|
||||||
|
xmlXIncludeErrMemory(ctxt, NULL, NULL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
/* If no current base, set it */
|
/* If no current base, set it */
|
||||||
if (curBase == NULL) {
|
if (curBase == NULL) {
|
||||||
xmlNodeSetBase(node, base);
|
res = xmlNodeSetBase(node, base);
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* If the current base is the same as the
|
* If the current base is the same as the
|
||||||
@ -1548,7 +1609,7 @@ loaded:
|
|||||||
* the specified xml:base or the relative URI
|
* the specified xml:base or the relative URI
|
||||||
*/
|
*/
|
||||||
if (xmlStrEqual(curBase, node->doc->URL)) {
|
if (xmlStrEqual(curBase, node->doc->URL)) {
|
||||||
xmlNodeSetBase(node, base);
|
res = xmlNodeSetBase(node, base);
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* If the element already has an xml:base
|
* If the element already has an xml:base
|
||||||
@ -1560,15 +1621,17 @@ loaded:
|
|||||||
XML_XML_NAMESPACE);
|
XML_XML_NAMESPACE);
|
||||||
if (xmlBase != NULL) {
|
if (xmlBase != NULL) {
|
||||||
xmlChar *relBase;
|
xmlChar *relBase;
|
||||||
relBase = xmlBuildURI(xmlBase, base);
|
res = xmlBuildURISafe(xmlBase, base, &relBase);
|
||||||
if (relBase == NULL) { /* error */
|
if (res < 0) {
|
||||||
|
xmlXIncludeErrMemory(ctxt, NULL, NULL);
|
||||||
|
} else if (relBase == NULL) {
|
||||||
xmlXIncludeErr(ctxt,
|
xmlXIncludeErr(ctxt,
|
||||||
ref->elem,
|
ref->elem,
|
||||||
XML_XINCLUDE_HREF_URI,
|
XML_XINCLUDE_HREF_URI,
|
||||||
"trying to rebuild base from %s\n",
|
"trying to rebuild base from %s\n",
|
||||||
xmlBase);
|
xmlBase);
|
||||||
} else {
|
} else {
|
||||||
xmlNodeSetBase(node, relBase);
|
res = xmlNodeSetBase(node, relBase);
|
||||||
xmlFree(relBase);
|
xmlFree(relBase);
|
||||||
}
|
}
|
||||||
xmlFree(xmlBase);
|
xmlFree(xmlBase);
|
||||||
@ -1576,6 +1639,8 @@ loaded:
|
|||||||
}
|
}
|
||||||
xmlFree(curBase);
|
xmlFree(curBase);
|
||||||
}
|
}
|
||||||
|
if (res < 0)
|
||||||
|
xmlXIncludeErrMemory(ctxt, NULL, NULL);
|
||||||
}
|
}
|
||||||
node = node->next;
|
node = node->next;
|
||||||
}
|
}
|
||||||
@ -1585,6 +1650,7 @@ loaded:
|
|||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
xmlFreeURI(uri);
|
||||||
xmlFree(URL);
|
xmlFree(URL);
|
||||||
xmlFree(fragment);
|
xmlFree(fragment);
|
||||||
return(ret);
|
return(ret);
|
||||||
@ -1610,10 +1676,11 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url,
|
|||||||
int i;
|
int i;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
xmlChar *encoding = NULL;
|
xmlChar *encoding = NULL;
|
||||||
xmlCharEncoding enc = (xmlCharEncoding) 0;
|
xmlCharEncodingHandlerPtr handler = NULL;
|
||||||
xmlParserCtxtPtr pctxt = NULL;
|
xmlParserCtxtPtr pctxt = NULL;
|
||||||
xmlParserInputPtr inputStream = NULL;
|
xmlParserInputPtr inputStream = NULL;
|
||||||
int len;
|
int len;
|
||||||
|
int res;
|
||||||
const xmlChar *content;
|
const xmlChar *content;
|
||||||
|
|
||||||
|
|
||||||
@ -1624,10 +1691,13 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url,
|
|||||||
/*
|
/*
|
||||||
* Check the URL and remove any fragment identifier
|
* Check the URL and remove any fragment identifier
|
||||||
*/
|
*/
|
||||||
uri = xmlParseURI((const char *)url);
|
res = xmlParseURISafe((const char *)url, &uri);
|
||||||
if (uri == NULL) {
|
if (uri == NULL) {
|
||||||
xmlXIncludeErr(ctxt, ref->elem, XML_XINCLUDE_HREF_URI,
|
if (res < 0)
|
||||||
"invalid value URI %s\n", url);
|
xmlXIncludeErrMemory(ctxt, NULL, NULL);
|
||||||
|
else
|
||||||
|
xmlXIncludeErr(ctxt, ref->elem, XML_XINCLUDE_HREF_URI,
|
||||||
|
"invalid value URI %s\n", url);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
if (uri->fragment != NULL) {
|
if (uri->fragment != NULL) {
|
||||||
@ -1638,8 +1708,7 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url,
|
|||||||
}
|
}
|
||||||
URL = xmlSaveUri(uri);
|
URL = xmlSaveUri(uri);
|
||||||
if (URL == NULL) {
|
if (URL == NULL) {
|
||||||
xmlXIncludeErr(ctxt, ref->elem, XML_XINCLUDE_HREF_URI,
|
xmlXIncludeErrMemory(ctxt, NULL, NULL);
|
||||||
"invalid value URI %s\n", url);
|
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1659,6 +1728,8 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url,
|
|||||||
for (i = 0; i < ctxt->txtNr; i++) {
|
for (i = 0; i < ctxt->txtNr; i++) {
|
||||||
if (xmlStrEqual(URL, ctxt->txtTab[i].url)) {
|
if (xmlStrEqual(URL, ctxt->txtTab[i].url)) {
|
||||||
node = xmlNewDocText(ctxt->doc, ctxt->txtTab[i].text);
|
node = xmlNewDocText(ctxt->doc, ctxt->txtTab[i].text);
|
||||||
|
if (node == NULL)
|
||||||
|
xmlXIncludeErrMemory(ctxt, NULL, NULL);
|
||||||
goto loaded;
|
goto loaded;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1667,36 +1738,50 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url,
|
|||||||
* Try to get the encoding if available
|
* Try to get the encoding if available
|
||||||
*/
|
*/
|
||||||
if (ref->elem != NULL) {
|
if (ref->elem != NULL) {
|
||||||
encoding = xmlGetProp(ref->elem, XINCLUDE_PARSE_ENCODING);
|
encoding = xmlXIncludeGetProp(ctxt, ref->elem, XINCLUDE_PARSE_ENCODING);
|
||||||
}
|
}
|
||||||
if (encoding != NULL) {
|
if (encoding != NULL) {
|
||||||
/*
|
res = xmlOpenCharEncodingHandler((const char *) encoding, &handler);
|
||||||
* TODO: we should not have to remap to the xmlCharEncoding
|
|
||||||
* predefined set, a better interface than
|
if (res != 0) {
|
||||||
* xmlParserInputBufferCreateFilename should allow any
|
if (res == XML_ERR_NO_MEMORY) {
|
||||||
* encoding supported by iconv
|
xmlXIncludeErrMemory(ctxt, NULL, NULL);
|
||||||
*/
|
} else if (res == XML_ERR_UNSUPPORTED_ENCODING) {
|
||||||
enc = xmlParseCharEncoding((const char *) encoding);
|
xmlXIncludeErr(ctxt, ref->elem, XML_XINCLUDE_UNKNOWN_ENCODING,
|
||||||
if (enc == XML_CHAR_ENCODING_ERROR) {
|
"encoding %s not supported\n", encoding);
|
||||||
xmlXIncludeErr(ctxt, ref->elem, XML_XINCLUDE_UNKNOWN_ENCODING,
|
goto error;
|
||||||
"encoding %s not supported\n", encoding);
|
} else {
|
||||||
goto error;
|
xmlXIncludeErr(ctxt, ref->elem, res,
|
||||||
}
|
"unexpected error from iconv or ICU\n", NULL);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Load it.
|
* Load it.
|
||||||
*/
|
*/
|
||||||
pctxt = xmlNewParserCtxt();
|
pctxt = xmlNewParserCtxt();
|
||||||
|
if (pctxt == NULL) {
|
||||||
|
xmlXIncludeErrMemory(ctxt, NULL, NULL);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
inputStream = xmlLoadExternalEntity((const char*)URL, NULL, pctxt);
|
inputStream = xmlLoadExternalEntity((const char*)URL, NULL, pctxt);
|
||||||
if(inputStream == NULL)
|
if (inputStream == NULL) {
|
||||||
|
if (pctxt->errNo == XML_ERR_NO_MEMORY)
|
||||||
|
xmlXIncludeErrMemory(ctxt, NULL, NULL);
|
||||||
|
else
|
||||||
|
xmlXIncludeErr(ctxt, NULL, pctxt->errNo, "load error", NULL);
|
||||||
goto error;
|
goto error;
|
||||||
|
}
|
||||||
buf = inputStream->buf;
|
buf = inputStream->buf;
|
||||||
if (buf == NULL)
|
if (buf == NULL)
|
||||||
goto error;
|
goto error;
|
||||||
if (buf->encoder)
|
if (buf->encoder)
|
||||||
xmlCharEncCloseFunc(buf->encoder);
|
xmlCharEncCloseFunc(buf->encoder);
|
||||||
buf->encoder = xmlGetCharEncodingHandler(enc);
|
buf->encoder = handler;
|
||||||
|
handler = NULL;
|
||||||
|
|
||||||
node = xmlNewDocText(ctxt->doc, NULL);
|
node = xmlNewDocText(ctxt->doc, NULL);
|
||||||
if (node == NULL) {
|
if (node == NULL) {
|
||||||
xmlXIncludeErrMemory(ctxt, ref->elem, NULL);
|
xmlXIncludeErrMemory(ctxt, ref->elem, NULL);
|
||||||
@ -1706,8 +1791,16 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url,
|
|||||||
/*
|
/*
|
||||||
* Scan all chars from the resource and add the to the node
|
* Scan all chars from the resource and add the to the node
|
||||||
*/
|
*/
|
||||||
while (xmlParserInputBufferRead(buf, 4096) > 0)
|
do {
|
||||||
;
|
res = xmlParserInputBufferRead(buf, 4096);
|
||||||
|
} while (res > 0);
|
||||||
|
if (res < 0) {
|
||||||
|
if (buf->error == XML_ERR_NO_MEMORY)
|
||||||
|
xmlXIncludeErrMemory(ctxt, NULL, NULL);
|
||||||
|
else
|
||||||
|
xmlXIncludeErr(ctxt, NULL, buf->error, "read error", NULL);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
content = xmlBufContent(buf->buffer);
|
content = xmlBufContent(buf->buffer);
|
||||||
len = xmlBufLength(buf->buffer);
|
len = xmlBufLength(buf->buffer);
|
||||||
@ -1726,7 +1819,8 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url,
|
|||||||
i += l;
|
i += l;
|
||||||
}
|
}
|
||||||
|
|
||||||
xmlNodeAddContentLen(node, content, len);
|
if (xmlNodeAddContentLen(node, content, len) < 0)
|
||||||
|
xmlXIncludeErrMemory(ctxt, NULL, NULL);
|
||||||
|
|
||||||
if (ctxt->txtNr >= ctxt->txtMax) {
|
if (ctxt->txtNr >= ctxt->txtMax) {
|
||||||
xmlXIncludeTxt *tmp;
|
xmlXIncludeTxt *tmp;
|
||||||
@ -1746,7 +1840,17 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url,
|
|||||||
ctxt->txtTab = tmp;
|
ctxt->txtTab = tmp;
|
||||||
}
|
}
|
||||||
ctxt->txtTab[ctxt->txtNr].text = xmlStrdup(node->content);
|
ctxt->txtTab[ctxt->txtNr].text = xmlStrdup(node->content);
|
||||||
|
if ((node->content != NULL) &&
|
||||||
|
(ctxt->txtTab[ctxt->txtNr].text == NULL)) {
|
||||||
|
xmlXIncludeErrMemory(ctxt, ref->elem, NULL);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
ctxt->txtTab[ctxt->txtNr].url = xmlStrdup(URL);
|
ctxt->txtTab[ctxt->txtNr].url = xmlStrdup(URL);
|
||||||
|
if (ctxt->txtTab[ctxt->txtNr].url == NULL) {
|
||||||
|
xmlXIncludeErrMemory(ctxt, ref->elem, NULL);
|
||||||
|
xmlFree(ctxt->txtTab[ctxt->txtNr].text);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
ctxt->txtNr++;
|
ctxt->txtNr++;
|
||||||
|
|
||||||
loaded:
|
loaded:
|
||||||
@ -1761,6 +1865,7 @@ error:
|
|||||||
xmlFreeNode(node);
|
xmlFreeNode(node);
|
||||||
xmlFreeInputStream(inputStream);
|
xmlFreeInputStream(inputStream);
|
||||||
xmlFreeParserCtxt(pctxt);
|
xmlFreeParserCtxt(pctxt);
|
||||||
|
xmlCharEncCloseFunc(handler);
|
||||||
xmlFree(encoding);
|
xmlFree(encoding);
|
||||||
xmlFreeURI(uri);
|
xmlFreeURI(uri);
|
||||||
xmlFree(URL);
|
xmlFree(URL);
|
||||||
@ -1896,12 +2001,10 @@ xmlXIncludeExpandNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node) {
|
|||||||
static int
|
static int
|
||||||
xmlXIncludeLoadNode(xmlXIncludeCtxtPtr ctxt, xmlXIncludeRefPtr ref) {
|
xmlXIncludeLoadNode(xmlXIncludeCtxtPtr ctxt, xmlXIncludeRefPtr ref) {
|
||||||
xmlNodePtr cur;
|
xmlNodePtr cur;
|
||||||
xmlChar *href;
|
|
||||||
xmlChar *parse;
|
|
||||||
xmlChar *base;
|
xmlChar *base;
|
||||||
xmlChar *oldBase;
|
xmlChar *oldBase;
|
||||||
xmlChar *URI;
|
xmlChar *URI;
|
||||||
int xml = 1; /* default Issue 64 */
|
int xml;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if ((ctxt == NULL) || (ref == NULL))
|
if ((ctxt == NULL) || (ref == NULL))
|
||||||
@ -1910,64 +2013,13 @@ xmlXIncludeLoadNode(xmlXIncludeCtxtPtr ctxt, xmlXIncludeRefPtr ref) {
|
|||||||
if (cur == NULL)
|
if (cur == NULL)
|
||||||
return(-1);
|
return(-1);
|
||||||
|
|
||||||
/*
|
if (xmlNodeGetBaseSafe(ctxt->doc, cur, &base) < 0) {
|
||||||
* read the attributes
|
xmlXIncludeErrMemory(ctxt, NULL, NULL);
|
||||||
*/
|
return(-1);
|
||||||
href = xmlXIncludeGetProp(ctxt, cur, XINCLUDE_HREF);
|
|
||||||
if (href == NULL) {
|
|
||||||
href = xmlStrdup(BAD_CAST ""); /* @@@@ href is now optional */
|
|
||||||
if (href == NULL)
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
parse = xmlXIncludeGetProp(ctxt, cur, XINCLUDE_PARSE);
|
|
||||||
if (parse != NULL) {
|
|
||||||
if (xmlStrEqual(parse, XINCLUDE_PARSE_XML))
|
|
||||||
xml = 1;
|
|
||||||
else if (xmlStrEqual(parse, XINCLUDE_PARSE_TEXT))
|
|
||||||
xml = 0;
|
|
||||||
else {
|
|
||||||
xmlXIncludeErr(ctxt, cur, XML_XINCLUDE_PARSE_VALUE,
|
|
||||||
"invalid value %s for 'parse'\n", parse);
|
|
||||||
if (href != NULL)
|
|
||||||
xmlFree(href);
|
|
||||||
if (parse != NULL)
|
|
||||||
xmlFree(parse);
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* compute the URI
|
|
||||||
*/
|
|
||||||
base = xmlNodeGetBase(ctxt->doc, cur);
|
|
||||||
if (base == NULL) {
|
|
||||||
URI = xmlBuildURI(href, ctxt->doc->URL);
|
|
||||||
} else {
|
|
||||||
URI = xmlBuildURI(href, base);
|
|
||||||
}
|
}
|
||||||
|
URI = xmlXIncludeBuildURI(ctxt, cur, base, &xml);
|
||||||
if (URI == NULL) {
|
if (URI == NULL) {
|
||||||
xmlChar *escbase;
|
xmlFree(base);
|
||||||
xmlChar *eschref;
|
|
||||||
/*
|
|
||||||
* Some escaping may be needed
|
|
||||||
*/
|
|
||||||
escbase = xmlURIEscape(base);
|
|
||||||
eschref = xmlURIEscape(href);
|
|
||||||
URI = xmlBuildURI(eschref, escbase);
|
|
||||||
if (escbase != NULL)
|
|
||||||
xmlFree(escbase);
|
|
||||||
if (eschref != NULL)
|
|
||||||
xmlFree(eschref);
|
|
||||||
}
|
|
||||||
if (URI == NULL) {
|
|
||||||
xmlXIncludeErr(ctxt, cur, XML_XINCLUDE_HREF_URI,
|
|
||||||
"failed build URL\n", NULL);
|
|
||||||
if (parse != NULL)
|
|
||||||
xmlFree(parse);
|
|
||||||
if (href != NULL)
|
|
||||||
xmlFree(href);
|
|
||||||
if (base != NULL)
|
|
||||||
xmlFree(base);
|
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2019,10 +2071,6 @@ xmlXIncludeLoadNode(xmlXIncludeCtxtPtr ctxt, xmlXIncludeRefPtr ref) {
|
|||||||
*/
|
*/
|
||||||
if (URI != NULL)
|
if (URI != NULL)
|
||||||
xmlFree(URI);
|
xmlFree(URI);
|
||||||
if (parse != NULL)
|
|
||||||
xmlFree(parse);
|
|
||||||
if (href != NULL)
|
|
||||||
xmlFree(href);
|
|
||||||
if (base != NULL)
|
if (base != NULL)
|
||||||
xmlFree(base);
|
xmlFree(base);
|
||||||
return(0);
|
return(0);
|
||||||
@ -2106,8 +2154,7 @@ xmlXIncludeIncludeNode(xmlXIncludeCtxtPtr ctxt, xmlXIncludeRefPtr ref) {
|
|||||||
}
|
}
|
||||||
end = xmlNewDocNode(cur->doc, cur->ns, cur->name, NULL);
|
end = xmlNewDocNode(cur->doc, cur->ns, cur->name, NULL);
|
||||||
if (end == NULL) {
|
if (end == NULL) {
|
||||||
xmlXIncludeErr(ctxt, ref->elem, XML_XINCLUDE_BUILD_FAILED,
|
xmlXIncludeErrMemory(ctxt, NULL, NULL);
|
||||||
"failed to build node\n", NULL);
|
|
||||||
xmlFreeNodeList(list);
|
xmlFreeNodeList(list);
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
@ -2222,11 +2269,6 @@ xmlXIncludeDoProcess(xmlXIncludeCtxtPtr ctxt, xmlNodePtr tree) {
|
|||||||
int ret = 0;
|
int ret = 0;
|
||||||
int i, start;
|
int i, start;
|
||||||
|
|
||||||
if ((tree == NULL) || (tree->type == XML_NAMESPACE_DECL))
|
|
||||||
return(-1);
|
|
||||||
if (ctxt == NULL)
|
|
||||||
return(-1);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* First phase: lookup the elements in the document
|
* First phase: lookup the elements in the document
|
||||||
*/
|
*/
|
||||||
@ -2296,6 +2338,56 @@ xmlXIncludeDoProcess(xmlXIncludeCtxtPtr ctxt, xmlNodePtr tree) {
|
|||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlXIncludeDoProcessRoot:
|
||||||
|
* @ctxt: the XInclude processing context
|
||||||
|
* @tree: the top of the tree to process
|
||||||
|
*
|
||||||
|
* Implement the XInclude substitution on the XML document @doc
|
||||||
|
*
|
||||||
|
* Returns 0 if no substitution were done, -1 if some processing failed
|
||||||
|
* or the number of substitutions done.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
xmlXIncludeDoProcessRoot(xmlXIncludeCtxtPtr ctxt, xmlNodePtr tree) {
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if ((tree == NULL) || (tree->type == XML_NAMESPACE_DECL))
|
||||||
|
return(-1);
|
||||||
|
if (ctxt == NULL)
|
||||||
|
return(-1);
|
||||||
|
|
||||||
|
if ((tree->doc != NULL) && (tree->doc->URL != NULL)) {
|
||||||
|
ctxt->base = xmlStrdup((xmlChar *)tree->doc->URL);
|
||||||
|
if (ctxt->base == NULL) {
|
||||||
|
xmlXIncludeErrMemory(ctxt, tree, NULL);
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = xmlXIncludeDoProcess(ctxt, tree);
|
||||||
|
|
||||||
|
if (ctxt->base != NULL) {
|
||||||
|
xmlFree(ctxt->base);
|
||||||
|
ctxt->base = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlXIncludeGetLastError:
|
||||||
|
* @ctxt: an XInclude processing context
|
||||||
|
*
|
||||||
|
* Returns the last error code.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
xmlXIncludeGetLastError(xmlXIncludeCtxtPtr ctxt) {
|
||||||
|
if (ctxt == NULL)
|
||||||
|
return(XML_ERR_INTERNAL_ERROR);
|
||||||
|
return(ctxt->errNo);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* xmlXIncludeSetFlags:
|
* xmlXIncludeSetFlags:
|
||||||
* @ctxt: an XInclude processing context
|
* @ctxt: an XInclude processing context
|
||||||
@ -2356,9 +2448,8 @@ xmlXIncludeProcessTreeFlagsData(xmlNodePtr tree, int flags, void *data) {
|
|||||||
if (ctxt == NULL)
|
if (ctxt == NULL)
|
||||||
return(-1);
|
return(-1);
|
||||||
ctxt->_private = data;
|
ctxt->_private = data;
|
||||||
ctxt->base = xmlStrdup((xmlChar *)tree->doc->URL);
|
|
||||||
xmlXIncludeSetFlags(ctxt, flags);
|
xmlXIncludeSetFlags(ctxt, flags);
|
||||||
ret = xmlXIncludeDoProcess(ctxt, tree);
|
ret = xmlXIncludeDoProcessRoot(ctxt, tree);
|
||||||
if ((ret >= 0) && (ctxt->nbErrors > 0))
|
if ((ret >= 0) && (ctxt->nbErrors > 0))
|
||||||
ret = -1;
|
ret = -1;
|
||||||
|
|
||||||
@ -2440,9 +2531,8 @@ xmlXIncludeProcessTreeFlags(xmlNodePtr tree, int flags) {
|
|||||||
ctxt = xmlXIncludeNewContext(tree->doc);
|
ctxt = xmlXIncludeNewContext(tree->doc);
|
||||||
if (ctxt == NULL)
|
if (ctxt == NULL)
|
||||||
return(-1);
|
return(-1);
|
||||||
ctxt->base = xmlNodeGetBase(tree->doc, tree);
|
|
||||||
xmlXIncludeSetFlags(ctxt, flags);
|
xmlXIncludeSetFlags(ctxt, flags);
|
||||||
ret = xmlXIncludeDoProcess(ctxt, tree);
|
ret = xmlXIncludeDoProcessRoot(ctxt, tree);
|
||||||
if ((ret >= 0) && (ctxt->nbErrors > 0))
|
if ((ret >= 0) && (ctxt->nbErrors > 0))
|
||||||
ret = -1;
|
ret = -1;
|
||||||
|
|
||||||
@ -2482,7 +2572,7 @@ xmlXIncludeProcessNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node) {
|
|||||||
if ((node == NULL) || (node->type == XML_NAMESPACE_DECL) ||
|
if ((node == NULL) || (node->type == XML_NAMESPACE_DECL) ||
|
||||||
(node->doc == NULL) || (ctxt == NULL))
|
(node->doc == NULL) || (ctxt == NULL))
|
||||||
return(-1);
|
return(-1);
|
||||||
ret = xmlXIncludeDoProcess(ctxt, node);
|
ret = xmlXIncludeDoProcessRoot(ctxt, node);
|
||||||
if ((ret >= 0) && (ctxt->nbErrors > 0))
|
if ((ret >= 0) && (ctxt->nbErrors > 0))
|
||||||
ret = -1;
|
ret = -1;
|
||||||
return(ret);
|
return(ret);
|
||||||
|
Reference in New Issue
Block a user