summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Veillard <veillard@src.gnome.org>2001-07-04 19:49:14 +0000
committerDaniel Veillard <veillard@src.gnome.org>2001-07-04 19:49:14 +0000
commit62f313ba0cce40d98c42e366a9692f8f11181d7c (patch)
treeaa0c736404bf882b6610d4a7fdacb83be1e10ba5
parentf420ac55f8ddf2137f0b0a99e5639ea0e3a08fe4 (diff)
downloadlibxml2-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--ChangeLog8
-rw-r--r--SAX.c3
-rw-r--r--entities.c2
-rw-r--r--parser.c63
4 files changed, 64 insertions, 12 deletions
diff --git a/ChangeLog b/ChangeLog
index b00fb4f2..9b9d703c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
diff --git a/SAX.c b/SAX.c
index 72b82e46..a1079289 100644
--- a/SAX.c
+++ b/SAX.c
@@ -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.
diff --git a/entities.c b/entities.c
index 94f1f6ff..4ecb98c9 100644
--- a/entities.c
+++ b/entities.c
@@ -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);
diff --git a/parser.c b/parser.c
index 8d34e723..bac83573 100644
--- a/parser.c
+++ b/parser.c
@@ -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