libxml2 r3669 - trunk



Author: veillard
Date: Fri Jan 11 05:27:32 2008
New Revision: 3669
URL: http://svn.gnome.org/viewvc/libxml2?rev=3669&view=rev

Log:
* parser.c: handle a erroneous parsing of attributes in 
  case said attribute has been redeclared in the DTD with a
  different type
* hash.c: fix the hash scanner to not crash if a first element
  from the hash list is been removed in the callback
Daniel


Modified:
   trunk/ChangeLog
   trunk/hash.c
   trunk/parser.c

Modified: trunk/hash.c
==============================================================================
--- trunk/hash.c	(original)
+++ trunk/hash.c	Fri Jan 11 05:27:32 2008
@@ -828,7 +828,7 @@
  */
 void
 xmlHashScanFull(xmlHashTablePtr table, xmlHashScannerFull f, void *data) {
-    int i;
+    int i, nb;
     xmlHashEntryPtr iter;
     xmlHashEntryPtr next;
 
@@ -844,10 +844,21 @@
 	    iter = &(table->table[i]);
 	    while (iter) {
 		next = iter->next;
+                nb = table->nbElems;
 		if ((f != NULL) && (iter->payload != NULL))
 		    f(iter->payload, data, iter->name,
 		      iter->name2, iter->name3);
-		iter = next;
+                if (nb != table->nbElems) {
+                    /* table was modified by the callback, be careful */
+                    if (iter == &(table->table[i])) {
+                        if (table->table[i].valid == 0)
+                            iter = NULL;
+                        if (table->table[i].next != next)
+			    iter = &(table->table[i]);
+                    } else
+		        iter = next;
+                } else
+		    iter = next;
 	    }
 	}
     }

Modified: trunk/parser.c
==============================================================================
--- trunk/parser.c	(original)
+++ trunk/parser.c	Fri Jan 11 05:27:32 2008
@@ -957,7 +957,7 @@
  * @fullattr:  the attribute fullname
  * @type:  the attribute type
  *
- * Register that this attribute is not CDATA
+ * Register this attribute type
  */
 static void
 xmlAddSpecialAttr(xmlParserCtxtPtr ctxt,
@@ -971,6 +971,9 @@
 	    goto mem_error;
     }
 
+    if (xmlHashLookup2(ctxt->attsSpecial, fullname, fullattr) != NULL)
+        return;
+
     xmlHashAddEntry2(ctxt->attsSpecial, fullname, fullattr,
                      (void *) (long) type);
     return;
@@ -981,6 +984,45 @@
 }
 
 /**
+ * xmlCleanSpecialAttrCallback:
+ *
+ * Removes CDATA attributes from the special attribute table
+ */
+static void
+xmlCleanSpecialAttrCallback(void *payload, void *data,
+                            const xmlChar *fullname, const xmlChar *fullattr,
+                            const xmlChar *unused ATTRIBUTE_UNUSED) {
+    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) data;
+
+    if (((int) payload) == XML_ATTRIBUTE_CDATA) {
+        xmlHashRemoveEntry2(ctxt->attsSpecial, fullname, fullattr, NULL);
+    }
+}
+
+/**
+ * xmlCleanSpecialAttr:
+ * @ctxt:  an XML parser context
+ *
+ * Trim the list of attributes defined to remove all those of type
+ * CDATA as they are not special. This call should be done when finishing
+ * to parse the DTD and before starting to parse the document root.
+ */
+static void
+xmlCleanSpecialAttr(xmlParserCtxtPtr ctxt)
+{
+    if (ctxt->attsSpecial == NULL)
+        return;
+
+    xmlHashScanFull(ctxt->attsSpecial, xmlCleanSpecialAttrCallback, ctxt);
+
+    if (xmlHashSize(ctxt->attsSpecial) == 0) {
+        xmlHashFree(ctxt->attsSpecial, NULL);
+        ctxt->attsSpecial = NULL;
+    }
+    return;
+}
+
+/**
  * xmlCheckLanguageID:
  * @lang:  pointer to the string value
  *
@@ -5006,7 +5048,7 @@
 		(def != XML_ATTRIBUTE_REQUIRED)) {
 		xmlAddDefAttrs(ctxt, elemName, attrName, defaultValue);
 	    }
-	    if ((ctxt->sax2) && (type != XML_ATTRIBUTE_CDATA)) {
+	    if (ctxt->sax2) {
 		xmlAddSpecialAttr(ctxt, elemName, attrName, type);
 	    }
 	    if (defaultValue != NULL)
@@ -9245,6 +9287,7 @@
 	                              ctxt->extSubSystem, ctxt->extSubURI);
 	ctxt->inSubset = 0;
 
+        xmlCleanSpecialAttr(ctxt);
 
 	ctxt->instate = XML_PARSER_PROLOG;
 	xmlParseMisc(ctxt);
@@ -10208,6 +10251,7 @@
 				    ctxt->intSubName, ctxt->extSubSystem,
 				    ctxt->extSubURI);
 			ctxt->inSubset = 0;
+			xmlCleanSpecialAttr(ctxt);
 			ctxt->instate = XML_PARSER_PROLOG;
 #ifdef DEBUG_PUSH
 			xmlGenericError(xmlGenericErrorContext,
@@ -10435,6 +10479,7 @@
 		    ctxt->sax->externalSubset(ctxt->userData, ctxt->intSubName,
 			    ctxt->extSubSystem, ctxt->extSubURI);
 		ctxt->inSubset = 0;
+		xmlCleanSpecialAttr(ctxt);
 		ctxt->instate = XML_PARSER_PROLOG;
 		ctxt->checkIndex = 0;
 #ifdef DEBUG_PUSH



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