[libxml2] Cache presence of '<' in entities content



commit cff2546f13503ac028e4c1f63c7b6d85f2f2d777
Author: Daniel Veillard <veillard redhat com>
Date:   Mon Mar 11 15:57:55 2013 +0800

    Cache presence of '<' in entities content
    
    slightly modify how ent->checked is used, and use the lowest bit to
    keep the information

 SAX2.c                    |    4 +++-
 include/libxml/entities.h |    3 ++-
 parser.c                  |   30 ++++++++++++++++++------------
 3 files changed, 23 insertions(+), 14 deletions(-)
---
diff --git a/SAX2.c b/SAX2.c
index ce7a5d6..c7ecd7f 100644
--- a/SAX2.c
+++ b/SAX2.c
@@ -605,7 +605,9 @@ xmlSAX2GetEntity(void *ctx, const xmlChar *name)
        }
        ret->owner = 1;
        if (ret->checked == 0) {
-           ret->checked = ctxt->nbentities - oldnbent + 1;
+           ret->checked = (ctxt->nbentities - oldnbent + 1) * 2;
+           if ((ret->content != NULL) && (xmlStrchr(ret->content, '<')))
+               ret->checked |= 1;
        }
     }
     return(ret);
diff --git a/include/libxml/entities.h b/include/libxml/entities.h
index cefb97f..1e91189 100644
--- a/include/libxml/entities.h
+++ b/include/libxml/entities.h
@@ -58,7 +58,8 @@ struct _xmlEntity {
     int                    owner;      /* does the entity own the childrens */
     int                         checked;       /* was the entity content checked */
                                        /* this is also used to count entites
-                                        * references done from that entity */
+                                        * references done from that entity
+                                        * and if it contains '<' */
 };
 
 /*
diff --git a/parser.c b/parser.c
index 362186b..2304e57 100644
--- a/parser.c
+++ b/parser.c
@@ -170,7 +170,7 @@ xmlParserEntityCheck(xmlParserCtxtPtr ctxt, size_t size,
         /*
          * use the number of parsed entities in the replacement
          */
-        size = ent->checked;
+        size = ent->checked / 2;
 
         /*
          * The amount of data parsed counting entities size only once
@@ -2736,7 +2736,7 @@ xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
                (ctxt->lastError.code == XML_ERR_INTERNAL_ERROR))
                goto int_error;
            if (ent != NULL)
-               ctxt->nbentities += ent->checked;
+               ctxt->nbentities += ent->checked / 2;
            if ((ent != NULL) &&
                (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
                if (ent->content != NULL) {
@@ -2787,7 +2787,7 @@ xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
            if (ctxt->lastError.code == XML_ERR_ENTITY_LOOP)
                goto int_error;
            if (ent != NULL)
-               ctxt->nbentities += ent->checked;
+               ctxt->nbentities += ent->checked / 2;
            if (ent != NULL) {
                 if (ent->content == NULL) {
                    xmlLoadEntityContent(ctxt, ent);
@@ -4050,8 +4050,10 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
                        rep = xmlStringDecodeEntities(ctxt, ent->content,
                                                  XML_SUBSTITUTE_REF, 0, 0, 0);
 
-                       ent->checked = ctxt->nbentities - oldnbent + 1;
+                       ent->checked = (ctxt->nbentities - oldnbent + 1) * 2;
                        if (rep != NULL) {
+                           if (xmlStrchr(rep, '<'))
+                               ent->checked |= 1;
                            xmlFree(rep);
                            rep = NULL;
                        }
@@ -7217,7 +7219,9 @@ xmlParseReference(xmlParserCtxtPtr ctxt) {
         * Store the number of entities needing parsing for this entity
         * content and do checkings
         */
-       ent->checked = ctxt->nbentities - oldnbent + 1;
+       ent->checked = (ctxt->nbentities - oldnbent + 1) * 2;
+       if ((ent->content != NULL) && (xmlStrchr(ent->content, '<')))
+           ent->checked |= 1;
        if (ret == XML_ERR_ENTITY_LOOP) {
            xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
            xmlFreeNodeList(list);
@@ -7282,9 +7286,9 @@ xmlParseReference(xmlParserCtxtPtr ctxt) {
            list = NULL;
        }
        if (ent->checked == 0)
-           ent->checked = 1;
+           ent->checked = 2;
     } else if (ent->checked != 1) {
-       ctxt->nbentities += ent->checked;
+       ctxt->nbentities += ent->checked / 2;
     }
 
     /*
@@ -7645,11 +7649,13 @@ xmlParseEntityRef(xmlParserCtxtPtr ctxt) {
      * not contain a <.
      */
     else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
-            (ent != NULL) && (ent->content != NULL) &&
-            (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) &&
-            (xmlStrchr(ent->content, '<'))) {
-       xmlFatalErrMsgStr(ctxt, XML_ERR_LT_IN_ATTRIBUTE,
-    "'<' in entity '%s' is not allowed in attributes values\n", name);
+            (ent != NULL) && 
+            (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY)) {
+       if ((ent->checked & 1) || ((ent->checked == 0) &&
+            (ent->content != NULL) &&(xmlStrchr(ent->content, '<')))) {
+           xmlFatalErrMsgStr(ctxt, XML_ERR_LT_IN_ATTRIBUTE,
+       "'<' in entity '%s' is not allowed in attributes values\n", name);
+        }
     }
 
     /*


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]