diff options
Diffstat (limited to 'parser.c')
-rw-r--r-- | parser.c | 99 |
1 files changed, 76 insertions, 23 deletions
@@ -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; |