[libxml++] Node: Make the previous fix thread-safe.



commit b4479ba898b5ecc32926c14652242c84abd566c8
Author: Kjell Ahlstedt <kjell ahlstedt bredband net>
Date:   Thu Apr 19 13:16:48 2012 +0200

    Node: Make the previous fix thread-safe.
    
    * libxml++/nodes/node.cc: Delete the C++ wrapper of a deleted attribute node
    without using xmlDeregisterNodeDefault. Bug #672992 comments 9-12.

 ChangeLog              |    7 +++++++
 libxml++/nodes/node.cc |   24 ++++++++++++------------
 2 files changed, 19 insertions(+), 12 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 1a6d339..694af7f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
 2012-04-19  Kjell Ahlstedt  <kjell ahlstedt bredband net>
 
+	Node: Make the previous fix thread-safe.
+
+	* libxml++/nodes/node.cc: Delete the C++ wrapper of a deleted attribute node
+	without using xmlDeregisterNodeDefault. Bug #672992 comments 9-12.
+
+2012-04-19  Kjell Ahlstedt  <kjell ahlstedt bredband net>
+
 	Node: Fix memory problems in import_node().
 
 	* libxml++/nodes/node.[h|cc]: Return added_node instead of imported_node,
diff --git a/libxml++/nodes/node.cc b/libxml++/nodes/node.cc
index b08d81d..e34a0be 100644
--- a/libxml++/nodes/node.cc
+++ b/libxml++/nodes/node.cc
@@ -231,22 +231,22 @@ Node* Node::import_node(const Node* node, bool recursive)
     throw exception("Unable to import node");
   }
 
-  // If the copied node is an attribute node, and there is an attribute with
-  // the same name, the old attribute is destroyed (freed). If it's an attribute,
-  // Node::free_wrappers() is registered as a callback that will delete the
-  // C++ wrapper before the C object is deleted.
-  xmlDeregisterNodeFunc old_callback = 0;
-  const bool register_callback = imported_node->type == XML_ATTRIBUTE_NODE;
-  if (register_callback)
-    old_callback = xmlDeregisterNodeDefault(Node::free_wrappers);
+  if (imported_node->type == XML_ATTRIBUTE_NODE && impl_->type == XML_ELEMENT_NODE)
+  {
+    xmlAttr* old_attr = xmlHasNsProp(impl_, imported_node->name,
+      imported_node->ns ? imported_node->ns->href : 0);
+    if (old_attr && old_attr->type != XML_ATTRIBUTE_DECL)
+    {
+      // *this has an attribute with the same name as the imported attribute.
+      // xmlAddChild() will delete the existing attribute.
+      // Delete the C++ wrapper before the call to xmlAddChild().
+      Node::free_wrappers(reinterpret_cast<xmlNode*>(old_attr));
+    }
+  }
 
   //Add the node:
   xmlNode* added_node = xmlAddChild(this->cobj(), imported_node);
 
-  // Remove the free_wrappers() callback and reinsert old callback function, if any.
-  if (register_callback)
-    xmlDeregisterNodeDefault(old_callback);
-
   if (!added_node)
   {
     Node::free_wrappers(imported_node);



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