1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2025-08-01 10:06:59 +03:00

Large sync between my W3C base and Gnome's one:

- parser.[ch]: added xmlGetFeaturesList() xmlGetFeature() and xmlAddFeature()
- tree.[ch]: added xmlAddChildList()
- xmllint.c: MAP_FAILED macro test
- parser.h: added xmlParseCtxtExternalEntity()
- valid.c: applied bug fixes removed warning
- tree.c: added CDATA block to elements content
- testSAX.c: cleanup of output
- testHTML.c: added SAX testing
- encoding.c: better error recovery
- SAX.c, parser.c: fixed one of the external entity processing of the OASis testsuite
- Makefile.am: added HTML SAX regression tests
- configure.in: bumped to 2.2.2
- test/HTML/ result/HTML: added a few of HTML tests, and added the SAX results

Daniel
This commit is contained in:
Daniel Veillard
2000-08-12 21:12:04 +00:00
parent 7ebb1eebda
commit 87b9539573
42 changed files with 6571 additions and 124 deletions

548
parser.c
View File

@ -62,10 +62,11 @@ void xmlParserHandleReference(xmlParserCtxtPtr ctxt);
void xmlParserHandlePEReference(xmlParserCtxtPtr ctxt);
xmlEntityPtr xmlParseStringPEReference(xmlParserCtxtPtr ctxt,
const xmlChar **str);
/*
* Version handling
*/
/************************************************************************
* *
* Version and Features handling *
* *
************************************************************************/
const char *xmlParserVersion = LIBXML_VERSION_STRING;
/*
@ -93,6 +94,293 @@ xmlCheckVersion(int version) {
}
const char *xmlFeaturesList[] = {
"validate",
"keep blanks",
"disable SAX",
"fetch external entities",
"substitute entities",
"gather line info",
"user data",
"is html",
"is standalone",
"stop parser",
"document",
"is well formed",
"is valid",
"SAX block",
"SAX function internalSubset",
"SAX function isStandalone",
"SAX function hasInternalSubset",
"SAX function hasExternalSubset",
"SAX function resolveEntity",
"SAX function getEntity",
"SAX function entityDecl",
"SAX function notationDecl",
"SAX function attributeDecl",
"SAX function elementDecl",
"SAX function unparsedEntityDecl",
"SAX function setDocumentLocator",
"SAX function startDocument",
"SAX function endDocument",
"SAX function startElement",
"SAX function endElement",
"SAX function reference",
"SAX function characters",
"SAX function ignorableWhitespace",
"SAX function processingInstruction",
"SAX function comment",
"SAX function warning",
"SAX function error",
"SAX function fatalError",
"SAX function getParameterEntity",
"SAX function cdataBlock",
"SAX function externalSubset",
};
/*
* xmlGetFeaturesList:
* @len: the length of the features name array (input/output)
* @result: an array of string to be filled with the features name.
*
* Copy at most *@len feature names into the @result array
*
* Returns -1 in case or error, or the total number of features,
* len is updated with the number of strings copied,
* strings must not be deallocated
*/
int
xmlGetFeaturesList(int *len, const char **result) {
int ret, i;
ret = sizeof(xmlFeaturesList)/sizeof(xmlFeaturesList[0]);
if ((len == NULL) || (result == NULL))
return(ret);
if ((*len < 0) || (*len >= 1000))
return(-1);
if (*len > ret)
*len = ret;
for (i = 0;i < *len;i++)
result[i] = xmlFeaturesList[i];
return(ret);
}
/*
* xmlGetFeature:
* @ctxt: an XML/HTML parser context
* @name: the feature name
* @result: location to store the result
*
* Read the current value of one feature of this parser instance
*
* Returns -1 in case or error, 0 otherwise
*/
int
xmlGetFeature(xmlParserCtxtPtr ctxt, const char *name, void *result) {
if ((ctxt == NULL) || (name == NULL) || (result == NULL))
return(-1);
if (!strcmp(name, "validate")) {
*((int *) result) = ctxt->validate;
} else if (!strcmp(name, "keep blanks")) {
*((int *) result) = ctxt->keepBlanks;
} else if (!strcmp(name, "disable SAX")) {
*((int *) result) = ctxt->disableSAX;
} else if (!strcmp(name, "fetch external entities")) {
*((int *) result) = ctxt->validate;
} else if (!strcmp(name, "substitute entities")) {
*((int *) result) = ctxt->replaceEntities;
} else if (!strcmp(name, "gather line info")) {
*((int *) result) = ctxt->record_info;
} else if (!strcmp(name, "user data")) {
*((void **)result) = ctxt->userData;
} else if (!strcmp(name, "is html")) {
*((int *) result) = ctxt->html;
} else if (!strcmp(name, "is standalone")) {
*((int *) result) = ctxt->standalone;
} else if (!strcmp(name, "document")) {
*((xmlDocPtr *) result) = ctxt->myDoc;
} else if (!strcmp(name, "is well formed")) {
*((int *) result) = ctxt->wellFormed;
} else if (!strcmp(name, "is valid")) {
*((int *) result) = ctxt->valid;
} else if (!strcmp(name, "SAX block")) {
*((xmlSAXHandlerPtr *) result) = ctxt->sax;
} else if (!strcmp(name, "SAX function internalSubset")) {
*((internalSubsetSAXFunc *) result) = ctxt->sax->internalSubset;
} else if (!strcmp(name, "SAX function isStandalone")) {
*((isStandaloneSAXFunc *) result) = ctxt->sax->isStandalone;
} else if (!strcmp(name, "SAX function hasInternalSubset")) {
*((hasInternalSubsetSAXFunc *) result) = ctxt->sax->hasInternalSubset;
} else if (!strcmp(name, "SAX function hasExternalSubset")) {
*((hasExternalSubsetSAXFunc *) result) = ctxt->sax->hasExternalSubset;
} else if (!strcmp(name, "SAX function resolveEntity")) {
*((resolveEntitySAXFunc *) result) = ctxt->sax->resolveEntity;
} else if (!strcmp(name, "SAX function getEntity")) {
*((getEntitySAXFunc *) result) = ctxt->sax->getEntity;
} else if (!strcmp(name, "SAX function entityDecl")) {
*((entityDeclSAXFunc *) result) = ctxt->sax->entityDecl;
} else if (!strcmp(name, "SAX function notationDecl")) {
*((notationDeclSAXFunc *) result) = ctxt->sax->notationDecl;
} else if (!strcmp(name, "SAX function attributeDecl")) {
*((attributeDeclSAXFunc *) result) = ctxt->sax->attributeDecl;
} else if (!strcmp(name, "SAX function elementDecl")) {
*((elementDeclSAXFunc *) result) = ctxt->sax->elementDecl;
} else if (!strcmp(name, "SAX function unparsedEntityDecl")) {
*((unparsedEntityDeclSAXFunc *) result) = ctxt->sax->unparsedEntityDecl;
} else if (!strcmp(name, "SAX function setDocumentLocator")) {
*((setDocumentLocatorSAXFunc *) result) = ctxt->sax->setDocumentLocator;
} else if (!strcmp(name, "SAX function startDocument")) {
*((startDocumentSAXFunc *) result) = ctxt->sax->startDocument;
} else if (!strcmp(name, "SAX function endDocument")) {
*((endDocumentSAXFunc *) result) = ctxt->sax->endDocument;
} else if (!strcmp(name, "SAX function startElement")) {
*((startElementSAXFunc *) result) = ctxt->sax->startElement;
} else if (!strcmp(name, "SAX function endElement")) {
*((endElementSAXFunc *) result) = ctxt->sax->endElement;
} else if (!strcmp(name, "SAX function reference")) {
*((referenceSAXFunc *) result) = ctxt->sax->reference;
} else if (!strcmp(name, "SAX function characters")) {
*((charactersSAXFunc *) result) = ctxt->sax->characters;
} else if (!strcmp(name, "SAX function ignorableWhitespace")) {
*((ignorableWhitespaceSAXFunc *) result) = ctxt->sax->ignorableWhitespace;
} else if (!strcmp(name, "SAX function processingInstruction")) {
*((processingInstructionSAXFunc *) result) = ctxt->sax->processingInstruction;
} else if (!strcmp(name, "SAX function comment")) {
*((commentSAXFunc *) result) = ctxt->sax->comment;
} else if (!strcmp(name, "SAX function warning")) {
*((warningSAXFunc *) result) = ctxt->sax->warning;
} else if (!strcmp(name, "SAX function error")) {
*((errorSAXFunc *) result) = ctxt->sax->error;
} else if (!strcmp(name, "SAX function fatalError")) {
*((fatalErrorSAXFunc *) result) = ctxt->sax->fatalError;
} else if (!strcmp(name, "SAX function getParameterEntity")) {
*((getParameterEntitySAXFunc *) result) = ctxt->sax->getParameterEntity;
} else if (!strcmp(name, "SAX function cdataBlock")) {
*((cdataBlockSAXFunc *) result) = ctxt->sax->cdataBlock;
} else if (!strcmp(name, "SAX function externalSubset")) {
*((externalSubsetSAXFunc *) result) = ctxt->sax->externalSubset;
} else {
return(-1);
}
return(0);
}
/*
* xmlSetFeature:
* @ctxt: an XML/HTML parser context
* @name: the feature name
* @value: pointer to the location of the new value
*
* Change the current value of one feature of this parser instance
*
* Returns -1 in case or error, 0 otherwise
*/
int
xmlSetFeature(xmlParserCtxtPtr ctxt, const char *name, void *value) {
if ((ctxt == NULL) || (name == NULL) || (value == NULL))
return(-1);
if (!strcmp(name, "validate")) {
ctxt->validate = *((int *) value);
} else if (!strcmp(name, "keep blanks")) {
ctxt->keepBlanks = *((int *) value);
} else if (!strcmp(name, "disable SAX")) {
ctxt->disableSAX = *((int *) value);
} else if (!strcmp(name, "fetch external entities")) {
int newvalid = *((int *) value);
if ((!ctxt->validate) && (newvalid != 0)) {
if (ctxt->vctxt.warning == NULL)
ctxt->vctxt.warning = xmlParserValidityWarning;
if (ctxt->vctxt.error == NULL)
ctxt->vctxt.error = xmlParserValidityError;
/* Allocate the Node stack */
ctxt->vctxt.nodeTab = (xmlNodePtr *)
xmlMalloc(4 * sizeof(xmlNodePtr));
ctxt->vctxt.nodeNr = 0;
ctxt->vctxt.nodeMax = 4;
ctxt->vctxt.node = NULL;
}
ctxt->validate = newvalid;
} else if (!strcmp(name, "substitute entities")) {
ctxt->replaceEntities = *((int *) value);
} else if (!strcmp(name, "gather line info")) {
ctxt->record_info = *((int *) value);
} else if (!strcmp(name, "user data")) {
ctxt->userData = *((void **)value);
} else if (!strcmp(name, "is html")) {
ctxt->html = *((int *) value);
} else if (!strcmp(name, "is standalone")) {
ctxt->standalone = *((int *) value);
} else if (!strcmp(name, "document")) {
ctxt->myDoc = *((xmlDocPtr *) value);
} else if (!strcmp(name, "is well formed")) {
ctxt->wellFormed = *((int *) value);
} else if (!strcmp(name, "is valid")) {
ctxt->valid = *((int *) value);
} else if (!strcmp(name, "SAX block")) {
ctxt->sax = *((xmlSAXHandlerPtr *) value);
} else if (!strcmp(name, "SAX function internalSubset")) {
ctxt->sax->internalSubset = *((internalSubsetSAXFunc *) value);
} else if (!strcmp(name, "SAX function isStandalone")) {
ctxt->sax->isStandalone = *((isStandaloneSAXFunc *) value);
} else if (!strcmp(name, "SAX function hasInternalSubset")) {
ctxt->sax->hasInternalSubset = *((hasInternalSubsetSAXFunc *) value);
} else if (!strcmp(name, "SAX function hasExternalSubset")) {
ctxt->sax->hasExternalSubset = *((hasExternalSubsetSAXFunc *) value);
} else if (!strcmp(name, "SAX function resolveEntity")) {
ctxt->sax->resolveEntity = *((resolveEntitySAXFunc *) value);
} else if (!strcmp(name, "SAX function getEntity")) {
ctxt->sax->getEntity = *((getEntitySAXFunc *) value);
} else if (!strcmp(name, "SAX function entityDecl")) {
ctxt->sax->entityDecl = *((entityDeclSAXFunc *) value);
} else if (!strcmp(name, "SAX function notationDecl")) {
ctxt->sax->notationDecl = *((notationDeclSAXFunc *) value);
} else if (!strcmp(name, "SAX function attributeDecl")) {
ctxt->sax->attributeDecl = *((attributeDeclSAXFunc *) value);
} else if (!strcmp(name, "SAX function elementDecl")) {
ctxt->sax->elementDecl = *((elementDeclSAXFunc *) value);
} else if (!strcmp(name, "SAX function unparsedEntityDecl")) {
ctxt->sax->unparsedEntityDecl = *((unparsedEntityDeclSAXFunc *) value);
} else if (!strcmp(name, "SAX function setDocumentLocator")) {
ctxt->sax->setDocumentLocator = *((setDocumentLocatorSAXFunc *) value);
} else if (!strcmp(name, "SAX function startDocument")) {
ctxt->sax->startDocument = *((startDocumentSAXFunc *) value);
} else if (!strcmp(name, "SAX function endDocument")) {
ctxt->sax->endDocument = *((endDocumentSAXFunc *) value);
} else if (!strcmp(name, "SAX function startElement")) {
ctxt->sax->startElement = *((startElementSAXFunc *) value);
} else if (!strcmp(name, "SAX function endElement")) {
ctxt->sax->endElement = *((endElementSAXFunc *) value);
} else if (!strcmp(name, "SAX function reference")) {
ctxt->sax->reference = *((referenceSAXFunc *) value);
} else if (!strcmp(name, "SAX function characters")) {
ctxt->sax->characters = *((charactersSAXFunc *) value);
} else if (!strcmp(name, "SAX function ignorableWhitespace")) {
ctxt->sax->ignorableWhitespace = *((ignorableWhitespaceSAXFunc *) value);
} else if (!strcmp(name, "SAX function processingInstruction")) {
ctxt->sax->processingInstruction = *((processingInstructionSAXFunc *) value);
} else if (!strcmp(name, "SAX function comment")) {
ctxt->sax->comment = *((commentSAXFunc *) value);
} else if (!strcmp(name, "SAX function warning")) {
ctxt->sax->warning = *((warningSAXFunc *) value);
} else if (!strcmp(name, "SAX function error")) {
ctxt->sax->error = *((errorSAXFunc *) value);
} else if (!strcmp(name, "SAX function fatalError")) {
ctxt->sax->fatalError = *((fatalErrorSAXFunc *) value);
} else if (!strcmp(name, "SAX function getParameterEntity")) {
ctxt->sax->getParameterEntity = *((getParameterEntitySAXFunc *) value);
} else if (!strcmp(name, "SAX function cdataBlock")) {
ctxt->sax->cdataBlock = *((cdataBlockSAXFunc *) value);
} else if (!strcmp(name, "SAX function externalSubset")) {
ctxt->sax->externalSubset = *((externalSubsetSAXFunc *) value);
} else {
return(-1);
}
return(0);
}
/************************************************************************
* *
* Input handling functions for progressive parsing *
@ -1958,6 +2246,10 @@ xmlParserHandlePEReference(xmlParserCtxtPtr ctxt) {
* ... The declaration of a parameter entity must precede
* any reference to it...
*/
if ((ctxt->validate) && (ctxt->vctxt.error != NULL)) {
ctxt->vctxt.error(ctxt->vctxt.userData,
"PEReference: %%%s; not found\n", name);
} else
if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
ctxt->sax->warning(ctxt->userData,
"PEReference: %%%s; not found\n", name);
@ -2155,6 +2447,9 @@ xmlStringDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int what,
int c,l;
int nbchars = 0;
if (str == NULL)
return(NULL);
if (ctxt->depth > 40) {
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData,
@ -2381,6 +2676,7 @@ xmlSwitchEncoding(xmlParserCtxtPtr ctxt, xmlCharEncoding enc)
ctxt->charset = XML_CHAR_ENCODING_UTF8;
return(0);
case XML_CHAR_ENCODING_UTF8:
case XML_CHAR_ENCODING_ASCII:
/* default encoding, no conversion should be needed */
ctxt->charset = XML_CHAR_ENCODING_UTF8;
return(0);
@ -2552,6 +2848,7 @@ xmlSwitchToEncoding(xmlParserCtxtPtr ctxt, xmlCharEncodingHandlerPtr handler)
}
ctxt->input->base =
ctxt->input->cur = ctxt->input->buf->buffer->content;
}
return(0);
} else {
@ -3886,7 +4183,8 @@ xmlParseAttValue(xmlParserCtxtPtr ctxt) {
* This may look absurd but is needed to detect
* entities problems
*/
if (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) {
if ((ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) &&
(ent->content != NULL)) {
xmlChar *rep;
rep = xmlStringDecodeEntities(ctxt, ent->content,
XML_SUBSTITUTE_REF, 0, 0, 0);
@ -5657,7 +5955,8 @@ xmlParseElementChildrenContentDecl(xmlParserCtxtPtr ctxt) {
ctxt->disableSAX = 1;
if ((op != NULL) && (op != ret))
xmlFreeElementContent(op);
if ((last != NULL) && (last != ret))
if ((last != NULL) && (last != ret) &&
(last != ret->c1) && (last != ret->c2))
xmlFreeElementContent(last);
if (ret != NULL)
xmlFreeElementContent(ret);
@ -5693,9 +5992,10 @@ xmlParseElementChildrenContentDecl(xmlParserCtxtPtr ctxt) {
ctxt->errNo = XML_ERR_SEPARATOR_REQUIRED;
ctxt->wellFormed = 0;
ctxt->disableSAX = 1;
if ((op != NULL) && (op != ret))
if ((op != NULL) && (op != ret) && (op != last))
xmlFreeElementContent(op);
if ((last != NULL) && (last != ret))
if ((last != NULL) && (last != ret) &&
(last != ret->c1) && (last != ret->c2))
xmlFreeElementContent(last);
if (ret != NULL)
xmlFreeElementContent(ret);
@ -5707,7 +6007,8 @@ xmlParseElementChildrenContentDecl(xmlParserCtxtPtr ctxt) {
if (op == NULL) {
if ((op != NULL) && (op != ret))
xmlFreeElementContent(op);
if ((last != NULL) && (last != ret))
if ((last != NULL) && (last != ret) &&
(last != ret->c1) && (last != ret->c2))
xmlFreeElementContent(last);
if (ret != NULL)
xmlFreeElementContent(ret);
@ -5731,7 +6032,8 @@ xmlParseElementChildrenContentDecl(xmlParserCtxtPtr ctxt) {
ctxt->errNo = XML_ERR_ELEMCONTENT_NOT_FINISHED;
if ((op != NULL) && (op != ret))
xmlFreeElementContent(op);
if ((last != NULL) && (last != ret))
if ((last != NULL) && (last != ret) &&
(last != ret->c1) && (last != ret->c2))
xmlFreeElementContent(last);
if (ret != NULL)
xmlFreeElementContent(ret);
@ -5757,7 +6059,8 @@ xmlParseElementChildrenContentDecl(xmlParserCtxtPtr ctxt) {
ctxt->disableSAX = 1;
if ((op != NULL) && (op != ret))
xmlFreeElementContent(op);
if ((last != NULL) && (last != ret))
if ((last != NULL) && (last != ret) &&
(last != ret->c1) && (last != ret->c2))
xmlFreeElementContent(last);
if (ret != NULL)
xmlFreeElementContent(ret);
@ -7999,6 +8302,13 @@ xmlParseElement(xmlParserCtxtPtr ctxt) {
#endif
xmlFree(oldname);
}
if ( ret != NULL && ctxt->record_info ) {
node_info.end_pos = ctxt->input->consumed +
(CUR_PTR - ctxt->input->base);
node_info.end_line = ctxt->input->line;
node_info.node = ret;
xmlParserAddNodeInfo(ctxt, &node_info);
}
return;
}
if (RAW == '>') {
@ -9919,7 +10229,6 @@ xmlSAXParseDTD(xmlSAXHandlerPtr sax, const xmlChar *ExternalID,
/*
* Set-up the SAX context
*/
if (ctxt == NULL) return(NULL);
if (sax != NULL) {
if (ctxt->sax != NULL)
xmlFree(ctxt->sax);
@ -10066,6 +10375,165 @@ xmlSAXParseBalancedChunk(xmlParserCtxtPtr ctx, xmlSAXHandlerPtr sax,
return(ret);
}
/**
* xmlParseCtxtExternalEntity:
* @ctx: the existing parsing context
* @URL: the URL for the entity to load
* @ID: the System ID for the entity to load
* @list: the return value for the set of parsed nodes
*
* Parse an external general entity within an existing parsing context
* An external general parsed entity is well-formed if it matches the
* production labeled extParsedEnt.
*
* [78] extParsedEnt ::= TextDecl? content
*
* Returns 0 if the entity is well formed, -1 in case of args problem and
* the parser error code otherwise
*/
int
xmlParseCtxtExternalEntity(xmlParserCtxtPtr ctx, const xmlChar *URL,
const xmlChar *ID, xmlNodePtr *list) {
xmlParserCtxtPtr ctxt;
xmlDocPtr newDoc;
xmlSAXHandlerPtr oldsax = NULL;
int ret = 0;
if (ctx->depth > 40) {
return(XML_ERR_ENTITY_LOOP);
}
if (list != NULL)
*list = NULL;
if ((URL == NULL) && (ID == NULL))
return(-1);
if (ctx->myDoc == NULL) /* @@ relax but check for dereferences */
return(-1);
ctxt = xmlCreateEntityParserCtxt(URL, ID, ctx->myDoc->URL);
if (ctxt == NULL) return(-1);
ctxt->userData = ctxt;
oldsax = ctxt->sax;
ctxt->sax = ctx->sax;
newDoc = xmlNewDoc(BAD_CAST "1.0");
if (newDoc == NULL) {
xmlFreeParserCtxt(ctxt);
return(-1);
}
if (ctx->myDoc != NULL) {
newDoc->intSubset = ctx->myDoc->intSubset;
newDoc->extSubset = ctx->myDoc->extSubset;
}
if (ctx->myDoc->URL != NULL) {
newDoc->URL = xmlStrdup(ctx->myDoc->URL);
}
newDoc->children = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
if (newDoc->children == NULL) {
ctxt->sax = oldsax;
xmlFreeParserCtxt(ctxt);
newDoc->intSubset = NULL;
newDoc->extSubset = NULL;
xmlFreeDoc(newDoc);
return(-1);
}
nodePush(ctxt, newDoc->children);
if (ctx->myDoc == NULL) {
ctxt->myDoc = newDoc;
} else {
ctxt->myDoc = ctx->myDoc;
newDoc->children->doc = ctx->myDoc;
}
/*
* Parse a possible text declaration first
*/
GROW;
if ((RAW == '<') && (NXT(1) == '?') &&
(NXT(2) == 'x') && (NXT(3) == 'm') &&
(NXT(4) == 'l') && (IS_BLANK(NXT(5)))) {
xmlParseTextDecl(ctxt);
}
/*
* Doing validity checking on chunk doesn't make sense
*/
ctxt->instate = XML_PARSER_CONTENT;
ctxt->validate = ctx->validate;
ctxt->depth = ctx->depth + 1;
ctxt->replaceEntities = ctx->replaceEntities;
if (ctxt->validate) {
ctxt->vctxt.error = ctx->vctxt.error;
ctxt->vctxt.warning = ctx->vctxt.warning;
/* Allocate the Node stack */
ctxt->vctxt.nodeTab = (xmlNodePtr *) xmlMalloc(4 * sizeof(xmlNodePtr));
ctxt->vctxt.nodeNr = 0;
ctxt->vctxt.nodeMax = 4;
ctxt->vctxt.node = NULL;
} else {
ctxt->vctxt.error = NULL;
ctxt->vctxt.warning = NULL;
}
xmlParseContent(ctxt);
if ((RAW == '<') && (NXT(1) == '/')) {
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData,
"chunk is not well balanced\n");
ctxt->wellFormed = 0;
ctxt->disableSAX = 1;
ctxt->errNo = XML_ERR_NOT_WELL_BALANCED;
} else if (RAW != 0) {
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData,
"extra content at the end of well balanced chunk\n");
ctxt->wellFormed = 0;
ctxt->disableSAX = 1;
ctxt->errNo = XML_ERR_EXTRA_CONTENT;
}
if (ctxt->node != newDoc->children) {
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData,
"chunk is not well balanced\n");
ctxt->wellFormed = 0;
ctxt->disableSAX = 1;
ctxt->errNo = XML_ERR_NOT_WELL_BALANCED;
}
if (!ctxt->wellFormed) {
if (ctxt->errNo == 0)
ret = 1;
else
ret = ctxt->errNo;
} else {
if (list != NULL) {
xmlNodePtr cur;
/*
* Return the newly created nodeset after unlinking it from
* they pseudo parent.
*/
cur = newDoc->children->children;
*list = cur;
while (cur != NULL) {
cur->parent = NULL;
cur = cur->next;
}
newDoc->children->children = NULL;
}
ret = 0;
}
ctxt->sax = oldsax;
xmlFreeParserCtxt(ctxt);
newDoc->intSubset = NULL;
newDoc->extSubset = NULL;
xmlFreeDoc(newDoc);
return(ret);
}
/**
* xmlParseExternalEntity:
* @doc: the document the chunk pertains to
@ -10104,6 +10572,8 @@ xmlParseExternalEntity(xmlDocPtr doc, xmlSAXHandlerPtr sax, void *user_data,
*list = NULL;
if ((URL == NULL) && (ID == NULL))
return(-1);
if (doc == NULL) /* @@ relax but check for dereferences */
return(-1);
ctxt = xmlCreateEntityParserCtxt(URL, ID, doc->URL);
@ -10413,25 +10883,44 @@ xmlCreateEntityParserCtxt(const xmlChar *URL, const xmlChar *ID,
xmlParserCtxtPtr ctxt;
xmlParserInputPtr inputStream;
char *directory = NULL;
xmlChar *uri;
ctxt = xmlNewParserCtxt();
if (ctxt == NULL) {
return(NULL);
}
inputStream = xmlLoadExternalEntity((char *)URL, (char *)ID, ctxt);
if (inputStream == NULL) {
xmlFreeParserCtxt(ctxt);
return(NULL);
uri = xmlBuildURI(URL, base);
if (uri == NULL) {
inputStream = xmlLoadExternalEntity((char *)URL, (char *)ID, ctxt);
if (inputStream == NULL) {
xmlFreeParserCtxt(ctxt);
return(NULL);
}
inputPush(ctxt, inputStream);
if ((ctxt->directory == NULL) && (directory == NULL))
directory = xmlParserGetDirectory((char *)URL);
if ((ctxt->directory == NULL) && (directory != NULL))
ctxt->directory = directory;
} else {
inputStream = xmlLoadExternalEntity((char *)uri, (char *)ID, ctxt);
if (inputStream == NULL) {
xmlFreeParserCtxt(ctxt);
return(NULL);
}
inputPush(ctxt, inputStream);
if ((ctxt->directory == NULL) && (directory == NULL))
directory = xmlParserGetDirectory((char *)uri);
if ((ctxt->directory == NULL) && (directory != NULL))
ctxt->directory = directory;
xmlFree(uri);
}
inputPush(ctxt, inputStream);
if ((ctxt->directory == NULL) && (directory == NULL))
directory = xmlParserGetDirectory((char *)URL);
if ((ctxt->directory == NULL) && (directory != NULL))
ctxt->directory = directory;
return(ctxt);
}
@ -10763,10 +11252,14 @@ int xmlSAXUserParseMemory(xmlSAXHandlerPtr sax, void *user_data,
char *buffer, int size) {
int ret = 0;
xmlParserCtxtPtr ctxt;
xmlSAXHandlerPtr oldsax = NULL;
ctxt = xmlCreateMemoryParserCtxt(buffer, size);
if (ctxt == NULL) return -1;
ctxt->sax = sax;
if (sax != NULL) {
oldsax = ctxt->sax;
ctxt->sax = sax;
}
ctxt->userData = user_data;
xmlParseDocument(ctxt);
@ -10779,8 +11272,9 @@ int xmlSAXUserParseMemory(xmlSAXHandlerPtr sax, void *user_data,
else
ret = -1;
}
if (sax != NULL)
ctxt->sax = NULL;
if (sax != NULL) {
ctxt->sax = oldsax;
}
xmlFreeParserCtxt(ctxt);
return ret;