diff options
author | Daniel Veillard <veillard@src.gnome.org> | 2001-07-04 19:49:14 +0000 |
---|---|---|
committer | Daniel Veillard <veillard@src.gnome.org> | 2001-07-04 19:49:14 +0000 |
commit | 62f313ba0cce40d98c42e366a9692f8f11181d7c (patch) | |
tree | aa0c736404bf882b6610d4a7fdacb83be1e10ba5 | |
parent | f420ac55f8ddf2137f0b0a99e5639ea0e3a08fe4 (diff) | |
download | libxml2-62f313ba0cce40d98c42e366a9692f8f11181d7c.tar.gz |
- SAX.c entities.c parser.c: changed completely the way entities
are handled when running the parser in entity substitution mode.
This fixes a bug reported by Stephan Kulow and nearly divides
by 3 the amount of memory required by libxslt to load and process
DocBook TDG.
Daniel
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | SAX.c | 3 | ||||
-rw-r--r-- | entities.c | 2 | ||||
-rw-r--r-- | parser.c | 63 |
4 files changed, 64 insertions, 12 deletions
@@ -1,3 +1,11 @@ +Wed Jul 4 21:42:24 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr> + + * SAX.c entities.c parser.c: changed completely the way entities + are handled when running the parser in entity substitution mode. + This fixes a bug reported by Stephan Kulow and nearly divides + by 3 the amount of memory required by libxslt to load and process + DocBook TDG. + Wed Jul 4 18:02:58 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr> * HTMLparser.c: fixing a too early root closing problem raised @@ -885,7 +885,8 @@ attribute(void *ctx, const xmlChar *fullname, const xmlChar *value) ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, ctxt->myDoc, ctxt->node, ret, value); } - } else if (ctxt->external != 2){ + } else if (((ctxt->replaceEntities == 0) && (ctxt->external != 2)) || + ((ctxt->replaceEntities != 0) && (ctxt->inSubset == 0))) { /* * when validating, the ID registration is done at the attribute * validation level. Otherwise we have to do specific handling here. @@ -46,7 +46,7 @@ xmlHashTablePtr xmlPredefinedEntities = NULL; static void xmlFreeEntity(xmlEntityPtr entity) { if (entity == NULL) return; - if (entity->children) + if ((entity->children) && (entity->children->parent == entity)) xmlFreeNodeList(entity->children); if (entity->name != NULL) xmlFree((char *) entity->name); @@ -5050,14 +5050,35 @@ xmlParseReference(xmlParserCtxtPtr ctxt) { (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY))&& (ent->children == NULL)) { ent->children = list; - while (list != NULL) { - list->parent = (xmlNodePtr) ent; - if (list->next == NULL) - ent->last = list; - list = list->next; + if (ctxt->replaceEntities) { + /* + * Prune it directly in the generated document + * except for single text nodes. + */ + if ((list->type == XML_TEXT_NODE) && + (list->next == NULL)) { + list->parent = (xmlNodePtr) ent; + list = NULL; + } else { + while (list != NULL) { + list->parent = (xmlNodePtr) ctxt->node; + if (list->next == NULL) + ent->last = list; + list = list->next; + } + list = ent->children; + } + } else { + while (list != NULL) { + list->parent = (xmlNodePtr) ent; + if (list->next == NULL) + ent->last = list; + list = list->next; + } } } else { xmlFreeNodeList(list); + list = NULL; } } else if (ret > 0) { ctxt->errNo = ret; @@ -5068,6 +5089,7 @@ xmlParseReference(xmlParserCtxtPtr ctxt) { ctxt->disableSAX = 1; } else if (list != NULL) { xmlFreeNodeList(list); + list = NULL; } } } @@ -5082,12 +5104,33 @@ xmlParseReference(xmlParserCtxtPtr ctxt) { if ((ctxt->node != NULL) && (ent->children != NULL)) { /* * Seems we are generating the DOM content, do - * a simple tree copy + * a simple tree copy for all references except the first + * In the first occurence list contains the replacement */ - xmlNodePtr new; - new = xmlCopyNodeList(ent->children); - - xmlAddChildList(ctxt->node, new); + if (list == NULL) { + xmlNodePtr new, cur; + cur = ent->children; + while (cur != NULL) { + new = xmlCopyNode(cur, 1); + xmlAddChild(ctxt->node, new); + if (cur == ent->last) + break; + cur = cur->next; + } + } else { + /* + * the name change is to avoid coalescing of the + * node with a prossible previous text one which + * would make ent->children a dandling pointer + */ + if (ent->children->type == XML_TEXT_NODE) + ent->children->name = xmlStrdup(BAD_CAST "nbktext"); + if ((ent->last != ent->children) && + (ent->last->type == XML_TEXT_NODE)) + ent->last->name = xmlStrdup(BAD_CAST "nbktext"); + xmlAddChildList(ctxt->node, ent->children); + } + /* * This is to avoid a nasty side effect, see * characters() in SAX.c |