mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2025-07-13 09:01:53 +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:
@ -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
3
SAX.c
@ -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.
|
||||||
|
@ -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);
|
||||||
|
51
parser.c
51
parser.c
@ -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;
|
||||||
|
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) {
|
while (list != NULL) {
|
||||||
list->parent = (xmlNodePtr) ent;
|
list->parent = (xmlNodePtr) ent;
|
||||||
if (list->next == NULL)
|
if (list->next == NULL)
|
||||||
ent->last = list;
|
ent->last = list;
|
||||||
list = list->next;
|
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
|
||||||
|
Reference in New Issue
Block a user