summaryrefslogtreecommitdiff
path: root/parser.c
diff options
context:
space:
mode:
authorMike Hommey <mh@glandium.org>2004-10-28 09:07:41 +0000
committerMike Hommey <mh@glandium.org>2004-10-28 09:07:41 +0000
commit9705f1a5e858108d21a0128556f42b25d16833cd (patch)
treef819e7482d433f8bf5da005695c79189dd5ce527 /parser.c
parent0732be88d054db33fa0ca479eab9988c8e6be42e (diff)
downloadlibxml2-upstream/2.6.15.tar.gz
Load /tmp/tmp.SgII7T/libxml2-2.6.15 intoupstream/2.6.15
packages/libxml2/branches/upstream/current.
Diffstat (limited to 'parser.c')
-rw-r--r--parser.c99
1 files changed, 76 insertions, 23 deletions
diff --git a/parser.c b/parser.c
index 4710270..b5ecd2e 100644
--- a/parser.c
+++ b/parser.c
@@ -5609,6 +5609,19 @@ xmlParseReference(xmlParserCtxtPtr ctxt) {
ctxt->sax->reference(ctxt->userData, ent->name);
return;
} else if (ctxt->replaceEntities) {
+ /*
+ * There is a problem on the handling of _private for entities
+ * (bug 155816): Should we copy the content of the field from
+ * the entity (possibly overwriting some value set by the user
+ * when a copy is created), should we leave it alone, or should
+ * we try to take care of different situations? The problem
+ * is exacerbated by the usage of this field by the xmlReader.
+ * To fix this bug, we look at _private on the created node
+ * and, if it's NULL, we copy in whatever was in the entity.
+ * If it's not NULL we leave it alone. This is somewhat of a
+ * hack - maybe we should have further tests to determine
+ * what to do.
+ */
if ((ctxt->node != NULL) && (ent->children != NULL)) {
/*
* Seems we are generating the DOM content, do
@@ -5630,9 +5643,10 @@ xmlParseReference(xmlParserCtxtPtr ctxt) {
cur = ent->children;
while (cur != NULL) {
- nw = xmlCopyNode(cur, 1);
+ nw = xmlDocCopyNode(cur, ctxt->myDoc, 1);
if (nw != NULL) {
- nw->_private = cur->_private;
+ if (nw->_private == NULL)
+ nw->_private = cur->_private;
if (firstChild == NULL){
firstChild = nw;
}
@@ -5673,9 +5687,10 @@ xmlParseReference(xmlParserCtxtPtr ctxt) {
next = cur->next;
cur->next = NULL;
cur->parent = NULL;
- nw = xmlCopyNode(cur, 1);
+ nw = xmlDocCopyNode(cur, ctxt->myDoc, 1);
if (nw != NULL) {
- nw->_private = cur->_private;
+ if (nw->_private == NULL)
+ nw->_private = cur->_private;
if (firstChild == NULL){
firstChild = cur;
}
@@ -5692,16 +5707,20 @@ xmlParseReference(xmlParserCtxtPtr ctxt) {
xmlAddEntityReference(ent, firstChild, nw);
#endif /* LIBXML_LEGACY_ENABLED */
} else {
+ const xmlChar *nbktext;
+
/*
* the name change is to avoid coalescing of the
* node with a possible previous text one which
* would make ent->children a dangling pointer
*/
+ nbktext = xmlDictLookup(ctxt->dict, BAD_CAST "nbktext",
+ -1);
if (ent->children->type == XML_TEXT_NODE)
- ent->children->name = xmlStrdup(BAD_CAST "nbktext");
+ ent->children->name = nbktext;
if ((ent->last != ent->children) &&
(ent->last->type == XML_TEXT_NODE))
- ent->last->name = xmlStrdup(BAD_CAST "nbktext");
+ ent->last->name = nbktext;
xmlAddChildList(ctxt->node, ent->children);
}
@@ -9918,6 +9937,7 @@ xmlCreatePushParserCtxt(xmlSAXHandlerPtr sax, void *user_data,
xmlFreeParserInputBuffer(buf);
return(NULL);
}
+ ctxt->dictNames = 1;
ctxt->pushTab = (void **) xmlMalloc(ctxt->nameMax * 3 * sizeof(xmlChar *));
if (ctxt->pushTab == NULL) {
xmlErrMemory(ctxt, NULL);
@@ -10219,7 +10239,7 @@ xmlSAXParseDTD(xmlSAXHandlerPtr sax, const xmlChar *ExternalID,
* Canonicalise the system ID
*/
systemIdCanonic = xmlCanonicPath(SystemID);
- if (systemIdCanonic == NULL) {
+ if ((SystemID != NULL) && (systemIdCanonic == NULL)) {
xmlFreeParserCtxt(ctxt);
return(NULL);
}
@@ -10336,6 +10356,7 @@ xmlParseCtxtExternalEntity(xmlParserCtxtPtr ctx, const xmlChar *URL,
const xmlChar *ID, xmlNodePtr *lst) {
xmlParserCtxtPtr ctxt;
xmlDocPtr newDoc;
+ xmlNodePtr newRoot;
xmlSAXHandlerPtr oldsax = NULL;
int ret = 0;
xmlChar start[4];
@@ -10365,6 +10386,10 @@ xmlParseCtxtExternalEntity(xmlParserCtxtPtr ctx, const xmlChar *URL,
xmlFreeParserCtxt(ctxt);
return(-1);
}
+ if (ctx->myDoc->dict) {
+ newDoc->dict = ctx->myDoc->dict;
+ xmlDictReference(newDoc->dict);
+ }
if (ctx->myDoc != NULL) {
newDoc->intSubset = ctx->myDoc->intSubset;
newDoc->extSubset = ctx->myDoc->extSubset;
@@ -10372,8 +10397,8 @@ xmlParseCtxtExternalEntity(xmlParserCtxtPtr ctx, const xmlChar *URL,
if (ctx->myDoc->URL != NULL) {
newDoc->URL = xmlStrdup(ctx->myDoc->URL);
}
- newDoc->children = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
- if (newDoc->children == NULL) {
+ newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
+ if (newRoot == NULL) {
ctxt->sax = oldsax;
xmlFreeParserCtxt(ctxt);
newDoc->intSubset = NULL;
@@ -10381,6 +10406,7 @@ xmlParseCtxtExternalEntity(xmlParserCtxtPtr ctx, const xmlChar *URL,
xmlFreeDoc(newDoc);
return(-1);
}
+ xmlAddChild((xmlNodePtr) newDoc, newRoot);
nodePush(ctxt, newDoc->children);
if (ctx->myDoc == NULL) {
ctxt->myDoc = newDoc;
@@ -10515,6 +10541,7 @@ xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt,
const xmlChar *ID, xmlNodePtr *list) {
xmlParserCtxtPtr ctxt;
xmlDocPtr newDoc;
+ xmlNodePtr newRoot;
xmlSAXHandlerPtr oldsax = NULL;
xmlParserErrors ret = XML_ERR_OK;
xmlChar start[4];
@@ -10574,12 +10601,17 @@ xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt,
if (doc != NULL) {
newDoc->intSubset = doc->intSubset;
newDoc->extSubset = doc->extSubset;
+ newDoc->dict = doc->dict;
+ } else if (oldctxt != NULL) {
+ newDoc->dict = oldctxt->dict;
}
+ xmlDictReference(newDoc->dict);
+
if (doc->URL != NULL) {
newDoc->URL = xmlStrdup(doc->URL);
}
- newDoc->children = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
- if (newDoc->children == NULL) {
+ newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
+ if (newRoot == NULL) {
if (sax != NULL)
ctxt->sax = oldsax;
ctxt->node_seq.maximum = 0;
@@ -10591,12 +10623,13 @@ xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt,
xmlFreeDoc(newDoc);
return(XML_ERR_INTERNAL_ERROR);
}
+ xmlAddChild((xmlNodePtr) newDoc, newRoot);
nodePush(ctxt, newDoc->children);
if (doc == NULL) {
ctxt->myDoc = newDoc;
} else {
ctxt->myDoc = doc;
- newDoc->children->doc = doc;
+ newRoot->doc = doc;
}
/*
@@ -10758,8 +10791,10 @@ xmlParseBalancedChunkMemoryInternal(xmlParserCtxtPtr oldctxt,
const xmlChar *string, void *user_data, xmlNodePtr *lst) {
xmlParserCtxtPtr ctxt;
xmlDocPtr newDoc = NULL;
+ xmlNodePtr newRoot;
xmlSAXHandlerPtr oldsax = NULL;
xmlNodePtr content = NULL;
+ xmlNodePtr last = NULL;
int size;
xmlParserErrors ret = XML_ERR_OK;
@@ -10802,21 +10837,27 @@ xmlParseBalancedChunkMemoryInternal(xmlParserCtxtPtr oldctxt,
xmlFreeParserCtxt(ctxt);
return(XML_ERR_INTERNAL_ERROR);
}
+ newDoc->dict = ctxt->dict;
+ xmlDictReference(newDoc->dict);
ctxt->myDoc = newDoc;
} else {
ctxt->myDoc = oldctxt->myDoc;
content = ctxt->myDoc->children;
+ last = ctxt->myDoc->last;
}
- ctxt->myDoc->children = xmlNewDocNode(ctxt->myDoc, NULL,
- BAD_CAST "pseudoroot", NULL);
- if (ctxt->myDoc->children == NULL) {
+ newRoot = xmlNewDocNode(ctxt->myDoc, NULL, BAD_CAST "pseudoroot", NULL);
+ if (newRoot == NULL) {
ctxt->sax = oldsax;
ctxt->dict = NULL;
xmlFreeParserCtxt(ctxt);
- if (newDoc != NULL)
+ if (newDoc != NULL) {
xmlFreeDoc(newDoc);
+ }
return(XML_ERR_INTERNAL_ERROR);
}
+ ctxt->myDoc->children = NULL;
+ ctxt->myDoc->last = NULL;
+ xmlAddChild((xmlNodePtr) ctxt->myDoc, newRoot);
nodePush(ctxt, ctxt->myDoc->children);
ctxt->instate = XML_PARSER_CONTENT;
ctxt->depth = oldctxt->depth + 1;
@@ -10877,6 +10918,7 @@ xmlParseBalancedChunkMemoryInternal(xmlParserCtxtPtr oldctxt,
if (ctxt->myDoc != NULL) {
xmlFreeNode(ctxt->myDoc->children);
ctxt->myDoc->children = content;
+ ctxt->myDoc->last = last;
}
ctxt->sax = oldsax;
@@ -10884,8 +10926,9 @@ xmlParseBalancedChunkMemoryInternal(xmlParserCtxtPtr oldctxt,
ctxt->attsDefault = NULL;
ctxt->attsSpecial = NULL;
xmlFreeParserCtxt(ctxt);
- if (newDoc != NULL)
+ if (newDoc != NULL) {
xmlFreeDoc(newDoc);
+ }
return(ret);
}
@@ -10974,13 +11017,20 @@ xmlParseInNodeContext(xmlNodePtr node, const char *data, int datalen,
return(XML_ERR_NO_MEMORY);
}
xmlAddChild(node, fake);
-
- xmlCtxtUseOptions(ctxt, options);
+
+ /*
+ * Use input doc's dict if present, else assure XML_PARSE_NODICT is set.
+ * We need a dictionary for xmlDetectSAX2, so if there's no doc dict
+ * we must wait until the last moment to free the original one.
+ */
if (doc->dict != NULL) {
- if (ctxt->dict != NULL)
+ if (ctxt->dict != NULL)
xmlDictFree(ctxt->dict);
ctxt->dict = doc->dict;
- }
+ } else
+ options |= XML_PARSE_NODICT;
+
+ xmlCtxtUseOptions(ctxt, options);
xmlDetectSAX2(ctxt);
ctxt->myDoc = doc;
@@ -11070,8 +11120,9 @@ xmlParseInNodeContext(xmlNodePtr node, const char *data, int datalen,
xmlFreeNodeList(*lst);
*lst = NULL;
}
-
- ctxt->dict = NULL;
+
+ if (doc->dict != NULL)
+ ctxt->dict = NULL;
xmlFreeParserCtxt(ctxt);
return(ret);
@@ -11142,6 +11193,8 @@ xmlParseBalancedChunkMemoryRecover(xmlDocPtr doc, xmlSAXHandlerPtr sax,
xmlFreeParserCtxt(ctxt);
return(-1);
}
+ newDoc->dict = ctxt->dict;
+ xmlDictReference(newDoc->dict);
if (doc != NULL) {
newDoc->intSubset = doc->intSubset;
newDoc->extSubset = doc->extSubset;