[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]