Jacek Caban : msxml3: Store xmlnode reference in xmlnodemap object.

Alexandre Julliard julliard at wine.codeweavers.com
Thu Mar 17 10:02:13 CDT 2016


Module: wine
Branch: master
Commit: 8c810372bc8bee1acffea3229f5a42a21d8ce1d7
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=8c810372bc8bee1acffea3229f5a42a21d8ce1d7

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Wed Mar 16 13:52:57 2016 +0100

msxml3: Store xmlnode reference in xmlnodemap object.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/msxml3/msxml_private.h |  2 ++
 dlls/msxml3/node.c          |  4 ++--
 dlls/msxml3/nodemap.c       |  2 ++
 dlls/msxml3/tests/domdoc.c  | 37 ++++++++++++++++++++++++++++++++++++-
 4 files changed, 42 insertions(+), 3 deletions(-)

diff --git a/dlls/msxml3/msxml_private.h b/dlls/msxml3/msxml_private.h
index 56be916..b6d8b5d 100644
--- a/dlls/msxml3/msxml_private.h
+++ b/dlls/msxml3/msxml_private.h
@@ -296,6 +296,8 @@ extern LONG xmldoc_add_ref( xmlDocPtr doc ) DECLSPEC_HIDDEN;
 extern LONG xmldoc_release( xmlDocPtr doc ) DECLSPEC_HIDDEN;
 extern LONG xmldoc_add_refs( xmlDocPtr doc, LONG refs ) DECLSPEC_HIDDEN;
 extern LONG xmldoc_release_refs ( xmlDocPtr doc, LONG refs ) DECLSPEC_HIDDEN;
+extern void xmlnode_add_ref(xmlNodePtr node) DECLSPEC_HIDDEN;
+extern void xmlnode_release(xmlNodePtr node) DECLSPEC_HIDDEN;
 extern int xmlnode_get_inst_cnt( xmlnode *node ) DECLSPEC_HIDDEN;
 extern HRESULT xmldoc_add_orphan( xmlDocPtr doc, xmlNodePtr node ) DECLSPEC_HIDDEN;
 extern HRESULT xmldoc_remove_orphan( xmlDocPtr doc, xmlNodePtr node ) DECLSPEC_HIDDEN;
diff --git a/dlls/msxml3/node.c b/dlls/msxml3/node.c
index 0bc40ff..d39ed57 100644
--- a/dlls/msxml3/node.c
+++ b/dlls/msxml3/node.c
@@ -431,13 +431,13 @@ int xmlnode_get_inst_cnt(xmlnode *node)
 
 /* _private field holds a number of COM instances spawned from this libxml2 node
  * most significant bits are used to store information about ignorrable whitespace nodes */
-static void xmlnode_add_ref(xmlNodePtr node)
+void xmlnode_add_ref(xmlNodePtr node)
 {
     if (node->type == XML_DOCUMENT_NODE) return;
     InterlockedIncrement((LONG*)&node->_private);
 }
 
-static void xmlnode_release(xmlNodePtr node)
+void xmlnode_release(xmlNodePtr node)
 {
     if (node->type == XML_DOCUMENT_NODE) return;
     InterlockedDecrement((LONG*)&node->_private);
diff --git a/dlls/msxml3/nodemap.c b/dlls/msxml3/nodemap.c
index 2ad6f12..a9fef47 100644
--- a/dlls/msxml3/nodemap.c
+++ b/dlls/msxml3/nodemap.c
@@ -140,6 +140,7 @@ static ULONG WINAPI xmlnodemap_Release(
     TRACE("(%p)->(%d)\n", This, ref);
     if ( ref == 0 )
     {
+        xmlnode_release( This->node );
         xmldoc_release( This->node->doc );
         if (This->enumvariant) IEnumVARIANT_Release(This->enumvariant);
         heap_free( This );
@@ -450,6 +451,7 @@ IXMLDOMNamedNodeMap *create_nodemap(xmlNodePtr node, const struct nodemap_funcs
 
     init_dispex(&This->dispex, (IUnknown*)&This->IXMLDOMNamedNodeMap_iface, &xmlnodemap_dispex);
 
+    xmlnode_add_ref(node);
     xmldoc_add_ref(node->doc);
 
     return &This->IXMLDOMNamedNodeMap_iface;
diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c
index 788b39f..de28a70 100644
--- a/dlls/msxml3/tests/domdoc.c
+++ b/dlls/msxml3/tests/domdoc.c
@@ -9259,10 +9259,12 @@ static void test_get_attributes(void)
 {
     const get_attributes_t *entry = get_attributes;
     IXMLDOMNamedNodeMap *map;
-    IXMLDOMDocument *doc;
+    IXMLDOMDocument *doc, *doc2;
     IXMLDOMNode *node, *node2;
+    IXMLDOMElement *elem;
     VARIANT_BOOL b;
     HRESULT hr;
+    VARIANT v;
     BSTR str;
     LONG length;
 
@@ -9434,6 +9436,39 @@ static void test_get_attributes(void)
 
     IXMLDOMNamedNodeMap_Release(map);
 
+    /* append created element a different document, map still works */
+    hr = IXMLDOMDocument_createElement(doc, _bstr_("test"), &elem);
+    ok(hr == S_OK, "createElement failed: %08x\n", hr);
+
+    V_VT(&v) = VT_I4;
+    V_I4(&v) = 1;
+    hr = IXMLDOMElement_setAttribute(elem, _bstr_("testattr"), v);
+    ok(hr == S_OK, "setAttribute failed: %08x\n", hr);
+
+    hr = IXMLDOMElement_get_attributes(elem, &map);
+    ok(hr == S_OK, "get_attributes failed: %08x\n", hr);
+
+    length = 0;
+    hr = IXMLDOMNamedNodeMap_get_length(map, &length);
+    ok(hr == S_OK, "got %08x\n", hr);
+    ok(length == 1, "got %d\n", length);
+
+    doc2 = create_document(&IID_IXMLDOMDocument);
+
+    hr = IXMLDOMDocument_appendChild(doc2, (IXMLDOMNode*)elem, &node);
+    ok(hr == S_OK, "appendChild failed: %08x\n", hr);
+    ok(node == (IXMLDOMNode*)elem, "node != elem\n");
+    IXMLDOMNode_Release(node);
+    IXMLDOMElement_Release(elem);
+    IXMLDOMDocument_Release(doc2);
+
+    length = 0;
+    hr = IXMLDOMNamedNodeMap_get_length(map, &length);
+    ok(hr == S_OK, "got %08x\n", hr);
+    ok(length == 1, "got %d\n", length);
+
+    IXMLDOMNamedNodeMap_Release(map);
+
     while (entry->type)
     {
         VARIANT var;




More information about the wine-cvs mailing list