mirror of
https://gitlab.gnome.org/GNOME/libxml2
synced 2025-03-28 21:33:13 +00:00
parser: Move cleanup of element stacks to xmlParseContent
This commit is contained in:
parent
a1ed589b4b
commit
f0dc52d09c
119
parser.c
119
parser.c
@ -9643,7 +9643,9 @@ out:
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
xmlParseContentInternal(xmlParserCtxtPtr ctxt) {
|
xmlParseContentInternal(xmlParserCtxtPtr ctxt) {
|
||||||
int nameNr = ctxt->nameNr;
|
int oldNameNr = ctxt->nameNr;
|
||||||
|
int oldSpaceNr = ctxt->spaceNr;
|
||||||
|
int oldNodeNr = ctxt->nodeNr;
|
||||||
|
|
||||||
GROW;
|
GROW;
|
||||||
while ((ctxt->input->cur < ctxt->input->end) &&
|
while ((ctxt->input->cur < ctxt->input->end) &&
|
||||||
@ -9678,7 +9680,7 @@ xmlParseContentInternal(xmlParserCtxtPtr ctxt) {
|
|||||||
*/
|
*/
|
||||||
else if (*cur == '<') {
|
else if (*cur == '<') {
|
||||||
if (NXT(1) == '/') {
|
if (NXT(1) == '/') {
|
||||||
if (ctxt->nameNr <= nameNr)
|
if (ctxt->nameNr <= oldNameNr)
|
||||||
break;
|
break;
|
||||||
xmlParseElementEnd(ctxt);
|
xmlParseElementEnd(ctxt);
|
||||||
} else {
|
} else {
|
||||||
@ -9705,6 +9707,35 @@ xmlParseContentInternal(xmlParserCtxtPtr ctxt) {
|
|||||||
SHRINK;
|
SHRINK;
|
||||||
GROW;
|
GROW;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((ctxt->nameNr > oldNameNr) &&
|
||||||
|
(ctxt->input->cur >= ctxt->input->end) &&
|
||||||
|
(ctxt->wellFormed)) {
|
||||||
|
const xmlChar *name = ctxt->nameTab[ctxt->nameNr - 1];
|
||||||
|
int line = ctxt->pushTab[ctxt->nameNr - 1].line;
|
||||||
|
xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NOT_FINISHED,
|
||||||
|
"Premature end of data in tag %s line %d\n",
|
||||||
|
name, line, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Clean up in error case
|
||||||
|
*/
|
||||||
|
|
||||||
|
while (ctxt->nodeNr > oldNodeNr)
|
||||||
|
nodePop(ctxt);
|
||||||
|
|
||||||
|
while (ctxt->nameNr > oldNameNr) {
|
||||||
|
xmlStartTag *tag = &ctxt->pushTab[ctxt->nameNr - 1];
|
||||||
|
|
||||||
|
if (tag->nsNr != 0)
|
||||||
|
xmlParserNsPop(ctxt, tag->nsNr);
|
||||||
|
|
||||||
|
namePop(ctxt);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (ctxt->spaceNr > oldSpaceNr)
|
||||||
|
spacePop(ctxt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -9718,18 +9749,7 @@ xmlParseContentInternal(xmlParserCtxtPtr ctxt) {
|
|||||||
|
|
||||||
void
|
void
|
||||||
xmlParseContent(xmlParserCtxtPtr ctxt) {
|
xmlParseContent(xmlParserCtxtPtr ctxt) {
|
||||||
int nameNr = ctxt->nameNr;
|
|
||||||
|
|
||||||
xmlParseContentInternal(ctxt);
|
xmlParseContentInternal(ctxt);
|
||||||
|
|
||||||
if ((ctxt->errNo == XML_ERR_OK) &&
|
|
||||||
(ctxt->nameNr > nameNr)) {
|
|
||||||
const xmlChar *name = ctxt->nameTab[ctxt->nameNr - 1];
|
|
||||||
int line = ctxt->pushTab[ctxt->nameNr - 1].line;
|
|
||||||
xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NOT_FINISHED,
|
|
||||||
"Premature end of data in tag %s line %d\n",
|
|
||||||
name, line, NULL);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -9756,7 +9776,7 @@ xmlParseElement(xmlParserCtxtPtr ctxt) {
|
|||||||
xmlParseContentInternal(ctxt);
|
xmlParseContentInternal(ctxt);
|
||||||
|
|
||||||
if (ctxt->input->cur >= ctxt->input->end) {
|
if (ctxt->input->cur >= ctxt->input->end) {
|
||||||
if (ctxt->errNo == XML_ERR_OK) {
|
if (ctxt->wellFormed) {
|
||||||
const xmlChar *name = ctxt->nameTab[ctxt->nameNr - 1];
|
const xmlChar *name = ctxt->nameTab[ctxt->nameNr - 1];
|
||||||
int line = ctxt->pushTab[ctxt->nameNr - 1].line;
|
int line = ctxt->pushTab[ctxt->nameNr - 1].line;
|
||||||
xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NOT_FINISHED,
|
xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NOT_FINISHED,
|
||||||
@ -11916,40 +11936,37 @@ xmlParseDTD(const xmlChar *ExternalID, const xmlChar *SystemID) {
|
|||||||
|
|
||||||
static xmlParserErrors
|
static xmlParserErrors
|
||||||
xmlCtxtParseContent(xmlParserCtxtPtr ctxt, xmlParserInputPtr input,
|
xmlCtxtParseContent(xmlParserCtxtPtr ctxt, xmlParserInputPtr input,
|
||||||
int hasTextDecl, xmlNodePtr *list) {
|
int hasTextDecl, xmlNodePtr *list, int buildTree) {
|
||||||
xmlNodePtr root = NULL;
|
xmlNodePtr root = NULL;
|
||||||
int oldNameNr, oldSpaceNr, oldNodeNr;
|
|
||||||
int oldWellFormed;
|
int oldWellFormed;
|
||||||
int oldNodeLen, oldNodeMem;
|
|
||||||
int ret = XML_ERR_NO_MEMORY;
|
int ret = XML_ERR_NO_MEMORY;
|
||||||
|
xmlChar *rootName = BAD_CAST "#root";
|
||||||
|
|
||||||
if (list != NULL)
|
if (list != NULL)
|
||||||
*list = NULL;
|
*list = NULL;
|
||||||
|
|
||||||
root = xmlNewDocNode(ctxt->myDoc, NULL, BAD_CAST "pseudoroot", NULL);
|
if (buildTree) {
|
||||||
if (root == NULL) {
|
root = xmlNewDocNode(ctxt->myDoc, NULL, rootName, NULL);
|
||||||
xmlErrMemory(ctxt);
|
if (root == NULL) {
|
||||||
goto error;
|
xmlErrMemory(ctxt);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xmlPushInput(ctxt, input) < 0)
|
if (xmlPushInput(ctxt, input) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
oldWellFormed = ctxt->wellFormed;
|
oldWellFormed = ctxt->wellFormed;
|
||||||
oldNodeLen = ctxt->nodelen;
|
|
||||||
oldNodeMem = ctxt->nodemem;
|
|
||||||
|
|
||||||
oldNameNr = ctxt->nameNr;
|
|
||||||
oldSpaceNr = ctxt->spaceNr;
|
|
||||||
oldNodeNr = ctxt->nodeNr;
|
|
||||||
|
|
||||||
ctxt->wellFormed = 1;
|
ctxt->wellFormed = 1;
|
||||||
ctxt->nodelen = 0;
|
ctxt->nodelen = 0;
|
||||||
ctxt->nodemem = 0;
|
ctxt->nodemem = 0;
|
||||||
|
|
||||||
nameNsPush(ctxt, root->name, NULL, NULL, 0, 0);
|
nameNsPush(ctxt, rootName, NULL, NULL, 0, 0);
|
||||||
spacePush(ctxt, -1);
|
spacePush(ctxt, -1);
|
||||||
nodePush(ctxt, root);
|
|
||||||
|
if (buildTree)
|
||||||
|
nodePush(ctxt, root);
|
||||||
|
|
||||||
if (hasTextDecl) {
|
if (hasTextDecl) {
|
||||||
xmlDetectEncoding(ctxt);
|
xmlDetectEncoding(ctxt);
|
||||||
@ -11976,13 +11993,15 @@ xmlCtxtParseContent(xmlParserCtxtPtr ctxt, xmlParserInputPtr input,
|
|||||||
|
|
||||||
if ((RAW == '<') && (NXT(1) == '/')) {
|
if ((RAW == '<') && (NXT(1) == '/')) {
|
||||||
xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
|
xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
|
||||||
} else if (RAW != 0) {
|
} else if ((ctxt->wellFormed) &&
|
||||||
xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
|
(ctxt->input->cur < ctxt->input->end)) {
|
||||||
|
xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
|
||||||
|
"entity not fully processed\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ctxt->wellFormed) ||
|
if ((ctxt->wellFormed) ||
|
||||||
((ctxt->recovery) && (ctxt->errNo != XML_ERR_NO_MEMORY))) {
|
((ctxt->recovery) && (ctxt->errNo != XML_ERR_NO_MEMORY))) {
|
||||||
if (list != NULL) {
|
if ((root != NULL) && (list != NULL)) {
|
||||||
xmlNodePtr cur;
|
xmlNodePtr cur;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -12004,30 +12023,13 @@ xmlCtxtParseContent(xmlParserCtxtPtr ctxt, xmlParserInputPtr input,
|
|||||||
ret = ctxt->errNo;
|
ret = ctxt->errNo;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* If the entity wasn't balanced, we have to pop items from
|
|
||||||
* several stacks.
|
|
||||||
*/
|
|
||||||
while (ctxt->nameNr > oldNameNr) {
|
|
||||||
xmlStartTag *tag = &ctxt->pushTab[ctxt->nameNr - 1];
|
|
||||||
|
|
||||||
if (tag->nsNr != 0)
|
|
||||||
xmlParserNsPop(ctxt, tag->nsNr);
|
|
||||||
|
|
||||||
namePop(ctxt);
|
|
||||||
}
|
|
||||||
|
|
||||||
while (ctxt->spaceNr > oldSpaceNr) {
|
|
||||||
spacePop(ctxt);
|
|
||||||
}
|
|
||||||
|
|
||||||
while (ctxt->nodeNr > oldNodeNr) {
|
|
||||||
nodePop(ctxt);
|
|
||||||
}
|
|
||||||
|
|
||||||
ctxt->wellFormed = oldWellFormed && ctxt->wellFormed;
|
ctxt->wellFormed = oldWellFormed && ctxt->wellFormed;
|
||||||
ctxt->nodelen = oldNodeLen;
|
|
||||||
ctxt->nodemem = oldNodeMem;
|
if (buildTree)
|
||||||
|
nodePop(ctxt);
|
||||||
|
|
||||||
|
namePop(ctxt);
|
||||||
|
spacePop(ctxt);
|
||||||
|
|
||||||
/* xmlPopInput would free the stream */
|
/* xmlPopInput would free the stream */
|
||||||
inputPop(ctxt);
|
inputPop(ctxt);
|
||||||
@ -12094,7 +12096,8 @@ xmlCtxtParseEntity(xmlParserCtxtPtr ctxt, xmlEntityPtr ent) {
|
|||||||
ctxt->nsdb = nsdb;
|
ctxt->nsdb = nsdb;
|
||||||
ent->flags |= XML_ENT_EXPANDING;
|
ent->flags |= XML_ENT_EXPANDING;
|
||||||
|
|
||||||
ret = xmlCtxtParseContent(ctxt, input, isExternal, &list);
|
ret = xmlCtxtParseContent(ctxt, input, isExternal, &list,
|
||||||
|
(ctxt->node != NULL));
|
||||||
|
|
||||||
ent->flags &= ~XML_ENT_EXPANDING;
|
ent->flags &= ~XML_ENT_EXPANDING;
|
||||||
ctxt->nsdb = oldNsdb;
|
ctxt->nsdb = oldNsdb;
|
||||||
@ -12166,7 +12169,7 @@ xmlParseCtxtExternalEntity(xmlParserCtxtPtr ctxt, const xmlChar *URL,
|
|||||||
if (input == NULL)
|
if (input == NULL)
|
||||||
return(ctxt->errNo);
|
return(ctxt->errNo);
|
||||||
|
|
||||||
ret = xmlCtxtParseContent(ctxt, input, /* hasTextDecl */ 1, list);
|
ret = xmlCtxtParseContent(ctxt, input, /* hasTextDecl */ 1, list, 1);
|
||||||
|
|
||||||
xmlFreeInputStream(input);
|
xmlFreeInputStream(input);
|
||||||
return(ret);
|
return(ret);
|
||||||
@ -12502,7 +12505,7 @@ xmlParseBalancedChunkMemoryRecover(xmlDocPtr doc, xmlSAXHandlerPtr sax,
|
|||||||
if (input == NULL)
|
if (input == NULL)
|
||||||
return(ctxt->errNo);
|
return(ctxt->errNo);
|
||||||
|
|
||||||
ret = xmlCtxtParseContent(ctxt, input, /* hasTextDecl */ 0, list);
|
ret = xmlCtxtParseContent(ctxt, input, /* hasTextDecl */ 0, list, 1);
|
||||||
|
|
||||||
xmlFreeInputStream(input);
|
xmlFreeInputStream(input);
|
||||||
xmlFreeParserCtxt(ctxt);
|
xmlFreeParserCtxt(ctxt);
|
||||||
|
@ -15,7 +15,7 @@ SAX.startElement(rnode)
|
|||||||
SAX.characters(
|
SAX.characters(
|
||||||
, 4)
|
, 4)
|
||||||
SAX.getEntity(f)
|
SAX.getEntity(f)
|
||||||
SAX.ignorableWhitespace(
|
SAX.characters(
|
||||||
, 4)
|
, 4)
|
||||||
SAX.startElement(f)
|
SAX.startElement(f)
|
||||||
SAX.characters(
|
SAX.characters(
|
||||||
|
@ -15,7 +15,7 @@ SAX.startElementNs(rnode, NULL, NULL, 0, 0, 0)
|
|||||||
SAX.characters(
|
SAX.characters(
|
||||||
, 4)
|
, 4)
|
||||||
SAX.getEntity(f)
|
SAX.getEntity(f)
|
||||||
SAX.ignorableWhitespace(
|
SAX.characters(
|
||||||
, 4)
|
, 4)
|
||||||
SAX.startElementNs(f, NULL, NULL, 0, 1, 1, att1='J...', 1)
|
SAX.startElementNs(f, NULL, NULL, 0, 1, 1, att1='J...', 1)
|
||||||
SAX.characters(
|
SAX.characters(
|
||||||
|
@ -15,7 +15,7 @@ SAX.startElementNs(rnode, NULL, NULL, 0, 0, 0)
|
|||||||
SAX.characters(
|
SAX.characters(
|
||||||
, 4)
|
, 4)
|
||||||
SAX.getEntity(f)
|
SAX.getEntity(f)
|
||||||
SAX.ignorableWhitespace(
|
SAX.characters(
|
||||||
, 4)
|
, 4)
|
||||||
SAX.startElementNs(f, NULL, NULL, 0, 1, 1, att1='J...', 1)
|
SAX.startElementNs(f, NULL, NULL, 0, 1, 1, att1='J...', 1)
|
||||||
SAX.characters(
|
SAX.characters(
|
||||||
|
@ -10,7 +10,7 @@ SAX.startElementNs(EXAMPLE, NULL, NULL, 0, 0, 0)
|
|||||||
SAX.characters(
|
SAX.characters(
|
||||||
, 3)
|
, 3)
|
||||||
SAX.getEntity(title)
|
SAX.getEntity(title)
|
||||||
SAX.ignorableWhitespace(
|
SAX.characters(
|
||||||
, 1)
|
, 1)
|
||||||
SAX.startElementNs(title, NULL, NULL, 0, 0, 0)
|
SAX.startElementNs(title, NULL, NULL, 0, 0, 0)
|
||||||
SAX.characters(my title, 8)
|
SAX.characters(my title, 8)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user