1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2025-07-14 20:01:04 +03:00

- 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
This commit is contained in:
Daniel Veillard
2001-07-04 19:49:14 +00:00
parent f420ac55f8
commit 62f313ba0c
4 changed files with 64 additions and 12 deletions

View File

@ -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> Wed Jul 4 18:02:58 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
* HTMLparser.c: fixing a too early root closing problem raised * HTMLparser.c: fixing a too early root closing problem raised

3
SAX.c
View File

@ -885,7 +885,8 @@ attribute(void *ctx, const xmlChar *fullname, const xmlChar *value)
ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, ctxt->myDoc, ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, ctxt->myDoc,
ctxt->node, ret, value); 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 * when validating, the ID registration is done at the attribute
* validation level. Otherwise we have to do specific handling here. * validation level. Otherwise we have to do specific handling here.

View File

@ -46,7 +46,7 @@ xmlHashTablePtr xmlPredefinedEntities = NULL;
static void xmlFreeEntity(xmlEntityPtr entity) { static void xmlFreeEntity(xmlEntityPtr entity) {
if (entity == NULL) return; if (entity == NULL) return;
if (entity->children) if ((entity->children) && (entity->children->parent == entity))
xmlFreeNodeList(entity->children); xmlFreeNodeList(entity->children);
if (entity->name != NULL) if (entity->name != NULL)
xmlFree((char *) entity->name); xmlFree((char *) entity->name);

View File

@ -5050,14 +5050,35 @@ xmlParseReference(xmlParserCtxtPtr ctxt) {
(ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY))&& (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY))&&
(ent->children == NULL)) { (ent->children == NULL)) {
ent->children = list; ent->children = list;
while (list != NULL) { if (ctxt->replaceEntities) {
list->parent = (xmlNodePtr) ent; /*
if (list->next == NULL) * Prune it directly in the generated document
ent->last = list; * except for single text nodes.
list = list->next; */
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 { } else {
xmlFreeNodeList(list); xmlFreeNodeList(list);
list = NULL;
} }
} else if (ret > 0) { } else if (ret > 0) {
ctxt->errNo = ret; ctxt->errNo = ret;
@ -5068,6 +5089,7 @@ xmlParseReference(xmlParserCtxtPtr ctxt) {
ctxt->disableSAX = 1; ctxt->disableSAX = 1;
} else if (list != NULL) { } else if (list != NULL) {
xmlFreeNodeList(list); xmlFreeNodeList(list);
list = NULL;
} }
} }
} }
@ -5082,12 +5104,33 @@ xmlParseReference(xmlParserCtxtPtr ctxt) {
if ((ctxt->node != NULL) && (ent->children != NULL)) { if ((ctxt->node != NULL) && (ent->children != NULL)) {
/* /*
* Seems we are generating the DOM content, do * 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; if (list == NULL) {
new = xmlCopyNodeList(ent->children); 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);
}
xmlAddChildList(ctxt->node, new);
/* /*
* This is to avoid a nasty side effect, see * This is to avoid a nasty side effect, see
* characters() in SAX.c * characters() in SAX.c