Piotr Caban : msxml3: Update xmlNode reference count when nodes are merged in node_insert_before.

Alexandre Julliard julliard at wine.codeweavers.com
Tue Apr 12 06:45:26 CDT 2016


Module: wine
Branch: stable
Commit: a295338e36c12d71cddf62732ba1d1db6d4515c9
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=a295338e36c12d71cddf62732ba1d1db6d4515c9

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Mon Dec 21 11:41:10 2015 +0100

msxml3: Update xmlNode reference count when nodes are merged in node_insert_before.

Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
(cherry picked from commit 7bd995a1166d0807e830ccb8b810db4e7d65e27c)
Signed-off-by: Michael Stefaniuc <mstefani at winehq.org>

---

 dlls/msxml3/node.c | 47 ++++++++++++++++++++++++++++++++---------------
 1 file changed, 32 insertions(+), 15 deletions(-)

diff --git a/dlls/msxml3/node.c b/dlls/msxml3/node.c
index f8d7761..9c768bd 100644
--- a/dlls/msxml3/node.c
+++ b/dlls/msxml3/node.c
@@ -429,6 +429,19 @@ int xmlnode_get_inst_cnt(xmlnode *node)
     return node_get_inst_cnt(node->node);
 }
 
+/* _private field holds a number of COM instances spawned from this libxml2 node */
+static void xmlnode_add_ref(xmlNodePtr node)
+{
+    if (node->type == XML_DOCUMENT_NODE) return;
+    InterlockedIncrement((LONG*)&node->_private);
+}
+
+static void xmlnode_release(xmlNodePtr node)
+{
+    if (node->type == XML_DOCUMENT_NODE) return;
+    InterlockedDecrement((LONG*)&node->_private);
+}
+
 HRESULT node_insert_before(xmlnode *This, IXMLDOMNode *new_child, const VARIANT *ref_child,
         IXMLDOMNode **ret)
 {
@@ -489,6 +502,7 @@ HRESULT node_insert_before(xmlnode *This, IXMLDOMNode *new_child, const VARIANT
 
     if(before)
     {
+        xmlNodePtr new_node;
         xmlnode *before_node_obj = get_node_obj(before);
 
         /* refs count including subtree */
@@ -496,19 +510,35 @@ HRESULT node_insert_before(xmlnode *This, IXMLDOMNode *new_child, const VARIANT
             refcount = xmlnode_get_inst_cnt(node_obj);
 
         if (refcount) xmldoc_add_refs(before_node_obj->node->doc, refcount);
-        node_obj->node = xmlAddPrevSibling(before_node_obj->node, node_obj->node);
+        new_node = xmlAddPrevSibling(before_node_obj->node, node_obj->node);
+        if (new_node != node_obj->node)
+        {
+            if (refcount != 1)
+                FIXME("referenced xmlNode was freed, expect crashes\n");
+            xmlnode_add_ref(new_node);
+            node_obj->node = new_node;
+        }
         if (refcount) xmldoc_release_refs(doc, refcount);
         node_obj->parent = This->parent;
     }
     else
     {
+        xmlNodePtr new_node;
+
         if (doc != This->node->doc)
             refcount = xmlnode_get_inst_cnt(node_obj);
 
         if (refcount) xmldoc_add_refs(This->node->doc, refcount);
         /* xmlAddChild doesn't unlink node from previous parent */
         xmlUnlinkNode(node_obj->node);
-        node_obj->node = xmlAddChild(This->node, node_obj->node);
+        new_node = xmlAddChild(This->node, node_obj->node);
+        if (new_node != node_obj->node)
+        {
+            if (refcount != 1)
+                FIXME("referenced xmlNode was freed, expect crashes\n");
+            xmlnode_add_ref(new_node);
+            node_obj->node = new_node;
+        }
         if (refcount) xmldoc_release_refs(doc, refcount);
         node_obj->parent = This->iface;
     }
@@ -1392,19 +1422,6 @@ HRESULT node_get_base_name(xmlnode *This, BSTR *name)
     return S_OK;
 }
 
-/* _private field holds a number of COM instances spawned from this libxml2 node */
-static void xmlnode_add_ref(xmlNodePtr node)
-{
-    if (node->type == XML_DOCUMENT_NODE) return;
-    InterlockedIncrement((LONG*)&node->_private);
-}
-
-static void xmlnode_release(xmlNodePtr node)
-{
-    if (node->type == XML_DOCUMENT_NODE) return;
-    InterlockedDecrement((LONG*)&node->_private);
-}
-
 void destroy_xmlnode(xmlnode *This)
 {
     if(This->node)




More information about the wine-cvs mailing list