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

[xml] Patch for xmlAddChild



Hello,

The xmlAddChild documentation says: "If there is an attribute with equal name, it is first destroyed." However, when the attribute which is replaced is the only attribute, libxml crashes. I believe this is because the code assumes there are attributes left after the original attribute is destroyed: it reads parent->properties to find the last attribute in the list, but parent->properties is set to NULL when the only property is destroyed by xmlUnlinkNode.
I think the attached patch should fix this. Could someone take a look at it?

Thanks,
Kris Breuker
--- tree.c	Mon Sep  1 09:17:20 2008
+++ tree_patched.c	Wed Dec 31 12:31:10 2008
@@ -3309,25 +3309,27 @@
     if (cur->type == XML_ATTRIBUTE_NODE) {
 		if (parent->type != XML_ELEMENT_NODE)
 			return(NULL);
-	if (parent->properties == NULL) {
-	    parent->properties = (xmlAttrPtr) cur;
-	} else {
+	if (parent->properties != NULL) {
 	    /* check if an attribute with the same name exists */
-	    xmlAttrPtr lastattr;
+	    xmlAttrPtr oldattr;
 
 	    if (cur->ns == NULL)
-		lastattr = xmlHasNsProp(parent, cur->name, NULL);
+		oldattr = xmlHasNsProp(parent, cur->name, NULL);
 	    else
-		lastattr = xmlHasNsProp(parent, cur->name, cur->ns->href);
-	    if ((lastattr != NULL) && (lastattr != (xmlAttrPtr) cur) && (lastattr->type != XML_ATTRIBUTE_DECL)) {
+		oldattr = xmlHasNsProp(parent, cur->name, cur->ns->href);
+	    if ((oldattr != NULL) && (oldattr != (xmlAttrPtr) cur) && (oldattr->type != XML_ATTRIBUTE_DECL)) {
 		/* different instance, destroy it (attributes must be unique) */
-			xmlUnlinkNode((xmlNodePtr) lastattr);
-		xmlFreeProp(lastattr);
+			xmlUnlinkNode((xmlNodePtr) oldattr);
+		xmlFreeProp(oldattr);
 	    }
-		if (lastattr == (xmlAttrPtr) cur)
+		if (oldattr == (xmlAttrPtr) cur)
 			return(cur);
+	}
+	if (parent->properties == NULL) {
+	    parent->properties = (xmlAttrPtr) cur;
+	} else {
 	    /* find the end */
-	    lastattr = parent->properties;
+	    xmlAttrPtr lastattr = parent->properties;
 	    while (lastattr->next != NULL) {
 		lastattr = lastattr->next;
 	    }


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