Module: wine Branch: master Commit: 8c810372bc8bee1acffea3229f5a42a21d8ce1d7 URL: http://source.winehq.org/git/wine.git/?a=commit;h=8c810372bc8bee1acffea3229f...
Author: Jacek Caban jacek@codeweavers.com Date: Wed Mar 16 13:52:57 2016 +0100
msxml3: Store xmlnode reference in xmlnodemap object.
Signed-off-by: Jacek Caban jacek@codeweavers.com Signed-off-by: Nikolay Sivov nsivov@codeweavers.com Signed-off-by: Alexandre Julliard julliard@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;