diff --git a/parser.c b/parser.c index cae2b7fd..47e56b3a 100644 --- a/parser.c +++ b/parser.c @@ -12357,21 +12357,43 @@ xmlParseDTD(const xmlChar *ExternalID, const xmlChar *SystemID) { * * ************************************************************************/ -static xmlNodePtr +static xmlParserErrors xmlCtxtParseContent(xmlParserCtxtPtr ctxt, xmlParserInputPtr input, - int hasTextDecl) { + int hasTextDecl, xmlNodePtr *list) { xmlParserInputPtr oldInput; xmlNodePtr oldNode, root = NULL; int oldNameNr, oldSpaceNr, oldNodeNr; int oldWellFormed; int oldProgressive; int oldNodeLen, oldNodeMem; + xmlParserNsData *nsdb, *oldNsdb; + int ret; + + if (list != NULL) + *list = NULL; if (((ctxt->depth > 40) && ((ctxt->options & XML_PARSE_HUGE) == 0)) || (ctxt->depth > 100)) { xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_LOOP, "Maximum entity nesting depth exceeded"); - return(NULL); + return(XML_ERR_ENTITY_LOOP); + } + + root = xmlNewDocNode(ctxt->myDoc, NULL, BAD_CAST "pseudoroot", NULL); + if (root == NULL) { + xmlErrMemory(ctxt); + return(XML_ERR_NO_MEMORY); + } + + /* + * We need to reset the namespace database, so that entities don't + * pick up namespaces from the parent of a reference. + */ + nsdb = xmlParserNsCreate(); + if (nsdb == NULL) { + xmlErrMemory(ctxt); + xmlFreeNode(root); + return(XML_ERR_NO_MEMORY); } oldNode = ctxt->node; @@ -12380,17 +12402,12 @@ xmlCtxtParseContent(xmlParserCtxtPtr ctxt, xmlParserInputPtr input, oldProgressive = ctxt->progressive; oldNodeLen = ctxt->nodelen; oldNodeMem = ctxt->nodemem; + oldNsdb = ctxt->nsdb; oldNameNr = ctxt->nameNr; oldSpaceNr = ctxt->spaceNr; oldNodeNr = ctxt->nodeNr; - root = xmlNewDocNode(ctxt->myDoc, NULL, BAD_CAST "pseudoroot", NULL); - if (root == NULL) { - xmlErrMemory(ctxt); - return(NULL); - } - /* * TODO: It would be nice if we could simply push the input onto * the input stack. But there's still some code that assumes that @@ -12400,6 +12417,7 @@ xmlCtxtParseContent(xmlParserCtxtPtr ctxt, xmlParserInputPtr input, ctxt->progressive = 0; ctxt->nodelen = 0; ctxt->nodemem = 0; + ctxt->nsdb = nsdb; nameNsPush(ctxt, root->name, NULL, NULL, 0, 0); spacePush(ctxt, -1); @@ -12436,10 +12454,28 @@ xmlCtxtParseContent(xmlParserCtxtPtr ctxt, xmlParserInputPtr input, xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL); } - if ((ctxt->wellFormed == 0) && - ((ctxt->recovery == 0) || (ctxt->errNo == XML_ERR_NO_MEMORY))) { - xmlFreeNode(root); - root = NULL; + if ((ctxt->wellFormed) || + ((ctxt->recovery) && (ctxt->errNo != XML_ERR_NO_MEMORY))) { + if (list != NULL) { + xmlNodePtr cur; + + /* + * Return the newly created nodeset after unlinking it from + * its pseudo parent. + */ + cur = root->children; + *list = cur; + while (cur != NULL) { + cur->parent = NULL; + cur = cur->next; + } + root->children = NULL; + root->last = NULL; + } + + ret = XML_ERR_OK; + } else { + ret = ctxt->errNo; } /* @@ -12469,8 +12505,12 @@ xmlCtxtParseContent(xmlParserCtxtPtr ctxt, xmlParserInputPtr input, ctxt->progressive = oldProgressive; ctxt->nodelen = oldNodeLen; ctxt->nodemem = oldNodeMem; + ctxt->nsdb = oldNsdb; - return(root); + xmlParserNsFree(nsdb); + xmlFreeNode(root); + + return(ret); } /** @@ -12494,8 +12534,8 @@ int xmlParseCtxtExternalEntity(xmlParserCtxtPtr ctxt, const xmlChar *URL, const xmlChar *ID, xmlNodePtr *list) { xmlParserInputPtr input; - xmlNodePtr root; unsigned long consumed; + int ret; if (list != NULL) *list = NULL; @@ -12507,24 +12547,7 @@ xmlParseCtxtExternalEntity(xmlParserCtxtPtr ctxt, const xmlChar *URL, if (input == NULL) return(ctxt->errNo); - root = xmlCtxtParseContent(ctxt, input, 1 /* hasTextDecl */); - - if ((list != NULL) && (root != NULL)) { - xmlNodePtr cur; - - /* - * Return the newly created nodeset after unlinking it from - * their pseudo parent. - */ - cur = root->children; - *list = cur; - while (cur != NULL) { - cur->parent = NULL; - cur = cur->next; - } - root->children = NULL; - root->last = NULL; - } + ret = xmlCtxtParseContent(ctxt, input, /* hasTextDecl */ 1, list); /* * Also record the size of the entity parsed @@ -12535,10 +12558,9 @@ xmlParseCtxtExternalEntity(xmlParserCtxtPtr ctxt, const xmlChar *URL, xmlSaturatedAdd(&ctxt->sizeentities, consumed); xmlSaturatedAdd(&ctxt->sizeentcopy, consumed); - xmlFreeNode(root); xmlFreeInputStream(input); - return(ctxt->errNo); + return(ret); } #ifdef LIBXML_SAX1_ENABLED @@ -12638,8 +12660,8 @@ static xmlParserErrors xmlCtxtParseInternalEntity(xmlParserCtxtPtr ctxt, const xmlChar *string, xmlNodePtr *list) { xmlParserInputPtr input; - xmlNodePtr root; unsigned long consumed; + int ret; if (list != NULL) *list = NULL; @@ -12651,24 +12673,7 @@ xmlCtxtParseInternalEntity(xmlParserCtxtPtr ctxt, const xmlChar *string, if (input == NULL) return(ctxt->errNo); - root = xmlCtxtParseContent(ctxt, input, 0 /* hasTextDecl */); - - if ((list != NULL) && (root != NULL)) { - xmlNodePtr cur; - - /* - * Return the newly created nodeset after unlinking it from - * their pseudo parent. - */ - cur = root->children; - *list = cur; - while (cur != NULL) { - cur->parent = NULL; - cur = cur->next; - } - root->children = NULL; - root->last = NULL; - } + ret = xmlCtxtParseContent(ctxt, input, /* hasTextDecl */ 0, list); /* * Also record the size of the entity parsed @@ -12678,10 +12683,9 @@ xmlCtxtParseInternalEntity(xmlParserCtxtPtr ctxt, const xmlChar *string, xmlSaturatedAdd(&ctxt->sizeentcopy, consumed); - xmlFreeNode(root); xmlFreeInputStream(input); - return(ctxt->errNo); + return(ret); } /** diff --git a/result/ns-ent.xml b/result/errors/ns-ent.xml similarity index 100% rename from result/ns-ent.xml rename to result/errors/ns-ent.xml diff --git a/result/errors/ns-ent.xml.ent b/result/errors/ns-ent.xml.ent new file mode 100644 index 00000000..1875add9 --- /dev/null +++ b/result/errors/ns-ent.xml.ent @@ -0,0 +1,3 @@ +namespace error : Namespace prefix ns on elem is not defined + + ^ diff --git a/result/errors/ns-ent.xml.err b/result/errors/ns-ent.xml.err new file mode 100644 index 00000000..1875add9 --- /dev/null +++ b/result/errors/ns-ent.xml.err @@ -0,0 +1,3 @@ +namespace error : Namespace prefix ns on elem is not defined + + ^ diff --git a/result/errors/ns-ent.xml.str b/result/errors/ns-ent.xml.str new file mode 100644 index 00000000..1875add9 --- /dev/null +++ b/result/errors/ns-ent.xml.str @@ -0,0 +1,3 @@ +namespace error : Namespace prefix ns on elem is not defined + + ^ diff --git a/result/noent/ns-ent.xml b/result/noent/ns-ent.xml deleted file mode 100644 index 9b8d8cd4..00000000 --- a/result/noent/ns-ent.xml +++ /dev/null @@ -1,11 +0,0 @@ - -"> -"> -]> - - - - - - diff --git a/result/noent/ns-ent.xml.sax2 b/result/noent/ns-ent.xml.sax2 deleted file mode 100644 index 7fe00ae1..00000000 --- a/result/noent/ns-ent.xml.sax2 +++ /dev/null @@ -1,41 +0,0 @@ -SAX.setDocumentLocator() -SAX.startDocument() -SAX.internalSubset(doc, , ) -SAX.entityDecl(ent1, 1, (null), (null), ) -SAX.getEntity(ent1) -SAX.entityDecl(ent2, 1, (null), (null), ) -SAX.getEntity(ent2) -SAX.externalSubset(doc, , ) -SAX.startElementNs(doc, NULL, NULL, 0, 0, 0) -SAX.characters( - , 5) -SAX.startElementNs(a, NULL, 'urn:a', 1, xmlns='urn:a', 0, 0) -SAX.getEntity(ent1) -SAX.startElementNs(elem, NULL, 'urn:a', 0, 0, 0) -SAX.endElementNs(elem, NULL, 'urn:a') -SAX.endElementNs(a, NULL, 'urn:a') -SAX.characters( - , 5) -SAX.startElementNs(b, NULL, 'urn:b', 1, xmlns='urn:b', 0, 0) -SAX.getEntity(ent1) -SAX.startElementNs(elem, NULL, 'urn:b', 0, 0, 0) -SAX.endElementNs(elem, NULL, 'urn:b') -SAX.endElementNs(b, NULL, 'urn:b') -SAX.characters( - , 5) -SAX.startElementNs(a, NULL, NULL, 1, xmlns:ns='urn:a', 0, 0) -SAX.getEntity(ent2) -SAX.startElementNs(elem, ns, 'urn:a', 0, 0, 0) -SAX.endElementNs(elem, ns, 'urn:a') -SAX.endElementNs(a, NULL, NULL) -SAX.characters( - , 5) -SAX.startElementNs(b, NULL, NULL, 1, xmlns:ns='urn:b', 0, 0) -SAX.getEntity(ent2) -SAX.startElementNs(elem, ns, 'urn:b', 0, 0, 0) -SAX.endElementNs(elem, ns, 'urn:b') -SAX.endElementNs(b, NULL, NULL) -SAX.characters( -, 1) -SAX.endElementNs(doc, NULL, NULL) -SAX.endDocument() diff --git a/result/ns-ent.xml.rde b/result/ns-ent.xml.rde deleted file mode 100644 index f0eeedd4..00000000 --- a/result/ns-ent.xml.rde +++ /dev/null @@ -1,25 +0,0 @@ -0 10 doc 0 0 -0 1 doc 0 0 -1 14 #text 0 1 - -1 1 a 0 0 -2 1 default:elem 1 0 -1 15 a 0 0 -1 14 #text 0 1 - -1 1 b 0 0 -2 1 default:elem 1 0 -1 15 b 0 0 -1 14 #text 0 1 - -1 1 a 0 0 -2 1 ns:elem 1 0 -1 15 a 0 0 -1 14 #text 0 1 - -1 1 b 0 0 -2 1 ns:elem 1 0 -1 15 b 0 0 -1 14 #text 0 1 - -0 15 doc 0 0 diff --git a/result/ns-ent.xml.rdr b/result/ns-ent.xml.rdr deleted file mode 100644 index 88bcf472..00000000 --- a/result/ns-ent.xml.rdr +++ /dev/null @@ -1,25 +0,0 @@ -0 10 doc 0 0 -0 1 doc 0 0 -1 14 #text 0 1 - -1 1 a 0 0 -2 5 ent1 0 0 -1 15 a 0 0 -1 14 #text 0 1 - -1 1 b 0 0 -2 5 ent1 0 0 -1 15 b 0 0 -1 14 #text 0 1 - -1 1 a 0 0 -2 5 ent2 0 0 -1 15 a 0 0 -1 14 #text 0 1 - -1 1 b 0 0 -2 5 ent2 0 0 -1 15 b 0 0 -1 14 #text 0 1 - -0 15 doc 0 0 diff --git a/result/ns-ent.xml.sax b/result/ns-ent.xml.sax deleted file mode 100644 index 98b63fcd..00000000 --- a/result/ns-ent.xml.sax +++ /dev/null @@ -1,45 +0,0 @@ -SAX.setDocumentLocator() -SAX.startDocument() -SAX.internalSubset(doc, , ) -SAX.entityDecl(ent1, 1, (null), (null), ) -SAX.getEntity(ent1) -SAX.entityDecl(ent2, 1, (null), (null), ) -SAX.getEntity(ent2) -SAX.externalSubset(doc, , ) -SAX.startElement(doc) -SAX.characters( - , 5) -SAX.startElement(a, xmlns='urn:a') -SAX.getEntity(ent1) -SAX.startElement(elem) -SAX.endElement(elem) -SAX.reference(ent1) -SAX.endElement(a) -SAX.characters( - , 5) -SAX.startElement(b, xmlns='urn:b') -SAX.getEntity(ent1) -SAX.startElement(elem) -SAX.endElement(elem) -SAX.reference(ent1) -SAX.endElement(b) -SAX.characters( - , 5) -SAX.startElement(a, xmlns:ns='urn:a') -SAX.getEntity(ent2) -SAX.startElement(ns:elem) -SAX.endElement(ns:elem) -SAX.reference(ent2) -SAX.endElement(a) -SAX.characters( - , 5) -SAX.startElement(b, xmlns:ns='urn:b') -SAX.getEntity(ent2) -SAX.startElement(ns:elem) -SAX.endElement(ns:elem) -SAX.reference(ent2) -SAX.endElement(b) -SAX.characters( -, 1) -SAX.endElement(doc) -SAX.endDocument() diff --git a/result/ns-ent.xml.sax2 b/result/ns-ent.xml.sax2 deleted file mode 100644 index 25106c41..00000000 --- a/result/ns-ent.xml.sax2 +++ /dev/null @@ -1,45 +0,0 @@ -SAX.setDocumentLocator() -SAX.startDocument() -SAX.internalSubset(doc, , ) -SAX.entityDecl(ent1, 1, (null), (null), ) -SAX.getEntity(ent1) -SAX.entityDecl(ent2, 1, (null), (null), ) -SAX.getEntity(ent2) -SAX.externalSubset(doc, , ) -SAX.startElementNs(doc, NULL, NULL, 0, 0, 0) -SAX.characters( - , 5) -SAX.startElementNs(a, NULL, 'urn:a', 1, xmlns='urn:a', 0, 0) -SAX.getEntity(ent1) -SAX.startElementNs(elem, NULL, 'urn:a', 0, 0, 0) -SAX.endElementNs(elem, NULL, 'urn:a') -SAX.reference(ent1) -SAX.endElementNs(a, NULL, 'urn:a') -SAX.characters( - , 5) -SAX.startElementNs(b, NULL, 'urn:b', 1, xmlns='urn:b', 0, 0) -SAX.getEntity(ent1) -SAX.startElementNs(elem, NULL, 'urn:b', 0, 0, 0) -SAX.endElementNs(elem, NULL, 'urn:b') -SAX.reference(ent1) -SAX.endElementNs(b, NULL, 'urn:b') -SAX.characters( - , 5) -SAX.startElementNs(a, NULL, NULL, 1, xmlns:ns='urn:a', 0, 0) -SAX.getEntity(ent2) -SAX.startElementNs(elem, ns, 'urn:a', 0, 0, 0) -SAX.endElementNs(elem, ns, 'urn:a') -SAX.reference(ent2) -SAX.endElementNs(a, NULL, NULL) -SAX.characters( - , 5) -SAX.startElementNs(b, NULL, NULL, 1, xmlns:ns='urn:b', 0, 0) -SAX.getEntity(ent2) -SAX.startElementNs(elem, ns, 'urn:b', 0, 0, 0) -SAX.endElementNs(elem, ns, 'urn:b') -SAX.reference(ent2) -SAX.endElementNs(b, NULL, NULL) -SAX.characters( -, 1) -SAX.endElementNs(doc, NULL, NULL) -SAX.endDocument() diff --git a/test/ns-ent.xml b/test/errors/ns-ent.xml similarity index 100% rename from test/ns-ent.xml rename to test/errors/ns-ent.xml