[PATCH 1/2] Fix reference counting behaviour for named map
Nikolay Sivov
nsivov at codeweavers.com
Thu Mar 10 12:56:51 CST 2011
---
dlls/msxml3/element.c | 6 ++--
dlls/msxml3/msxml_private.h | 2 +-
dlls/msxml3/nodemap.c | 46 ++++++++++--------------------------------
dlls/msxml3/tests/domdoc.c | 45 ++++++++++++++++++++++++++++++++++++++++-
4 files changed, 58 insertions(+), 41 deletions(-)
diff --git a/dlls/msxml3/element.c b/dlls/msxml3/element.c
index 8d81f67..4c3a9b3 100644
--- a/dlls/msxml3/element.c
+++ b/dlls/msxml3/element.c
@@ -314,13 +314,13 @@ static HRESULT WINAPI domelem_get_nextSibling(
static HRESULT WINAPI domelem_get_attributes(
IXMLDOMElement *iface,
- IXMLDOMNamedNodeMap** attributeMap)
+ IXMLDOMNamedNodeMap** map)
{
domelem *This = impl_from_IXMLDOMElement( iface );
- TRACE("(%p)->(%p)\n", This, attributeMap);
+ TRACE("(%p)->(%p)\n", This, map);
- *attributeMap = create_nodemap((IXMLDOMNode*)&This->IXMLDOMElement_iface);
+ *map = create_nodemap(This->node.node);
return S_OK;
}
diff --git a/dlls/msxml3/msxml_private.h b/dlls/msxml3/msxml_private.h
index 72de7ba..4e3b35b 100644
--- a/dlls/msxml3/msxml_private.h
+++ b/dlls/msxml3/msxml_private.h
@@ -186,7 +186,7 @@ extern IUnknown *create_pi( xmlNodePtr pi );
extern IUnknown *create_comment( xmlNodePtr comment );
extern IUnknown *create_cdata( xmlNodePtr text );
extern IXMLDOMNodeList *create_children_nodelist( xmlNodePtr );
-extern IXMLDOMNamedNodeMap *create_nodemap( IXMLDOMNode *node );
+extern IXMLDOMNamedNodeMap *create_nodemap( const xmlNodePtr );
extern IUnknown *create_doc_Implementation(void);
extern IUnknown *create_doc_fragment( xmlNodePtr fragment );
extern IUnknown *create_doc_entity_ref( xmlNodePtr entity );
diff --git a/dlls/msxml3/nodemap.c b/dlls/msxml3/nodemap.c
index 660eab6..20475ca 100644
--- a/dlls/msxml3/nodemap.c
+++ b/dlls/msxml3/nodemap.c
@@ -48,7 +48,8 @@ typedef struct _xmlnodemap
IXMLDOMNamedNodeMap IXMLDOMNamedNodeMap_iface;
ISupportErrorInfo ISupportErrorInfo_iface;
LONG ref;
- IXMLDOMNode *node;
+
+ xmlNodePtr node;
LONG iterator;
} xmlnodemap;
@@ -109,7 +110,7 @@ static ULONG WINAPI xmlnodemap_Release(
TRACE("(%p)->(%d)\n", This, ref);
if ( ref == 0 )
{
- IXMLDOMNode_Release( This->node );
+ xmldoc_release( This->node->doc );
heap_free( This );
}
@@ -217,7 +218,6 @@ static HRESULT WINAPI xmlnodemap_setNamedItem(
{
xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
xmlNodePtr nodeNew;
- xmlNodePtr node;
xmlnode *ThisNew;
TRACE("(%p)->(%p %p)\n", This, newItem, namedItem );
@@ -227,10 +227,6 @@ static HRESULT WINAPI xmlnodemap_setNamedItem(
if(namedItem) *namedItem = NULL;
- node = xmlNodePtr_from_domnode( This->node, 0 );
- if ( !node )
- return E_FAIL;
-
/* Must be an Attribute */
ThisNew = get_node_obj( newItem );
if(!ThisNew) return E_FAIL;
@@ -242,7 +238,7 @@ static HRESULT WINAPI xmlnodemap_setNamedItem(
if(xmldoc_remove_orphan(ThisNew->node->doc, ThisNew->node) != S_OK)
WARN("%p is not an orphan of %p\n", ThisNew->node, ThisNew->node->doc);
- nodeNew = xmlAddChild(node, ThisNew->node);
+ nodeNew = xmlAddChild(This->node, ThisNew->node);
if(namedItem)
*namedItem = create_node( nodeNew );
@@ -265,7 +261,6 @@ static HRESULT WINAPI xmlnodemap_get_item(
IXMLDOMNode** listItem)
{
xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
- xmlNodePtr node;
xmlAttrPtr curr;
LONG attrIndex;
@@ -276,8 +271,7 @@ static HRESULT WINAPI xmlnodemap_get_item(
if (index < 0)
return S_FALSE;
- node = xmlNodePtr_from_domnode( This->node, 0 );
- curr = node->properties;
+ curr = This->node->properties;
for (attrIndex = 0; attrIndex < index; attrIndex++) {
if (curr->next == NULL)
@@ -295,7 +289,6 @@ static HRESULT WINAPI xmlnodemap_get_length(
IXMLDOMNamedNodeMap *iface,
LONG *listLength)
{
- xmlNodePtr node;
xmlAttrPtr first;
xmlAttrPtr curr;
LONG attrCount;
@@ -307,11 +300,7 @@ static HRESULT WINAPI xmlnodemap_get_length(
if( !listLength )
return E_INVALIDARG;
- node = xmlNodePtr_from_domnode( This->node, 0 );
- if ( !node )
- return E_FAIL;
-
- first = node->properties;
+ first = This->node->properties;
if (first == NULL) {
*listLength = 0;
return S_OK;
@@ -336,7 +325,6 @@ static HRESULT WINAPI xmlnodemap_getQualifiedItem(
{
xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
xmlAttrPtr attr;
- xmlNodePtr node;
xmlChar *href;
xmlChar *name;
@@ -344,10 +332,6 @@ static HRESULT WINAPI xmlnodemap_getQualifiedItem(
if (!baseName || !qualifiedItem) return E_INVALIDARG;
- node = xmlNodePtr_from_domnode(This->node, XML_ELEMENT_NODE);
- if ( !node )
- return E_FAIL;
-
if (namespaceURI && *namespaceURI)
{
href = xmlChar_from_wchar(namespaceURI);
@@ -363,7 +347,7 @@ static HRESULT WINAPI xmlnodemap_getQualifiedItem(
return E_OUTOFMEMORY;
}
- attr = xmlHasNsProp(node, name, href);
+ attr = xmlHasNsProp(This->node, name, href);
heap_free(name);
heap_free(href);
@@ -387,7 +371,6 @@ static HRESULT WINAPI xmlnodemap_removeQualifiedItem(
{
xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
xmlAttrPtr attr;
- xmlNodePtr node;
xmlChar *name;
xmlChar *href;
@@ -395,10 +378,6 @@ static HRESULT WINAPI xmlnodemap_removeQualifiedItem(
if (!baseName) return E_INVALIDARG;
- node = xmlNodePtr_from_domnode( This->node, XML_ELEMENT_NODE );
- if ( !node )
- return E_FAIL;
-
if (namespaceURI && *namespaceURI)
{
href = xmlChar_from_wchar(namespaceURI);
@@ -414,7 +393,7 @@ static HRESULT WINAPI xmlnodemap_removeQualifiedItem(
return E_OUTOFMEMORY;
}
- attr = xmlHasNsProp( node, name, href );
+ attr = xmlHasNsProp( This->node, name, href );
heap_free(name);
heap_free(href);
@@ -445,7 +424,6 @@ static HRESULT WINAPI xmlnodemap_nextNode(
IXMLDOMNode** nextItem)
{
xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
- xmlNodePtr node;
xmlAttrPtr curr;
LONG attrIndex;
@@ -453,8 +431,7 @@ static HRESULT WINAPI xmlnodemap_nextNode(
*nextItem = NULL;
- node = xmlNodePtr_from_domnode( This->node, 0 );
- curr = node->properties;
+ curr = This->node->properties;
for (attrIndex = 0; attrIndex < This->iterator; attrIndex++) {
if (curr->next == NULL)
@@ -551,7 +528,7 @@ static const struct ISupportErrorInfoVtbl support_error_vtbl =
support_error_InterfaceSupportsErrorInfo
};
-IXMLDOMNamedNodeMap *create_nodemap( IXMLDOMNode *node )
+IXMLDOMNamedNodeMap *create_nodemap( const xmlNodePtr node )
{
xmlnodemap *nodemap;
@@ -565,8 +542,7 @@ IXMLDOMNamedNodeMap *create_nodemap( IXMLDOMNode *node )
nodemap->ref = 1;
nodemap->iterator = 0;
- IXMLDOMNode_AddRef( node );
- /* Since we AddRef a node here, we don't need to call xmldoc_add_ref() */
+ xmldoc_add_ref(node->doc);
return &nodemap->IXMLDOMNamedNodeMap_iface;
}
diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c
index 42fd22a..370c56e 100644
--- a/dlls/msxml3/tests/domdoc.c
+++ b/dlls/msxml3/tests/domdoc.c
@@ -8329,6 +8329,7 @@ static void test_get_nodeTypeString(void)
ok(!lstrcmpW(str, _bstr_(entry->string)), "got string %s, expected %s. node type %d\n",
wine_dbgstr_w(str), entry->string, entry->type);
SysFreeString(str);
+ IXMLDOMNode_Release(node);
entry++;
}
@@ -8358,14 +8359,15 @@ static void test_get_attributes(void)
const get_attributes_t *entry = get_attributes;
IXMLDOMNamedNodeMap *map;
IXMLDOMDocument *doc;
- IXMLDOMNode *node;
+ IXMLDOMNode *node, *node2;
VARIANT_BOOL b;
HRESULT hr;
BSTR str;
+ LONG length;
doc = create_document(&IID_IXMLDOMDocument);
- str = SysAllocString( szComplete3 );
+ str = SysAllocString( szComplete4 );
hr = IXMLDOMDocument_loadXML(doc, str, &b);
SysFreeString(str);
@@ -8403,6 +8405,43 @@ static void test_get_attributes(void)
IXMLDOMNode_Release(node);
+ /* last child is element */
+ EXPECT_REF(doc, 1);
+ hr = IXMLDOMDocument_get_lastChild(doc, &node);
+ ok(hr == S_OK, "got %08x\n", hr);
+ EXPECT_REF(doc, 1);
+
+ EXPECT_REF(node, 1);
+ hr = IXMLDOMNode_get_attributes(node, &map);
+ ok(hr == S_OK, "got %08x\n", hr);
+ EXPECT_REF(node, 1);
+ EXPECT_REF(doc, 1);
+
+ EXPECT_REF(map, 1);
+ hr = IXMLDOMNamedNodeMap_get_item(map, 0, &node2);
+ ok(hr == S_OK, "got %08x\n", hr);
+ EXPECT_REF(node, 1);
+ EXPECT_REF(node2, 1);
+ EXPECT_REF(map, 1);
+ EXPECT_REF(doc, 1);
+ IXMLDOMNode_Release(node2);
+
+ /* release node before map release, map still works */
+ IXMLDOMNode_Release(node);
+
+ length = 0;
+ hr = IXMLDOMNamedNodeMap_get_length(map, &length);
+ ok(hr == S_OK, "got %08x\n", hr);
+ ok(length == 1, "got %d\n", length);
+
+ node2 = NULL;
+ hr = IXMLDOMNamedNodeMap_get_item(map, 0, &node2);
+ ok(hr == S_OK, "got %08x\n", hr);
+ EXPECT_REF(node2, 1);
+ IXMLDOMNode_Release(node2);
+
+ IXMLDOMNamedNodeMap_Release(map);
+
while (entry->type)
{
VARIANT var;
@@ -8423,6 +8462,8 @@ static void test_get_attributes(void)
hr, entry->hr, entry->type);
ok(map == NULL, "got %p\n", map);
+ IXMLDOMNode_Release(node);
+
entry++;
}
--
1.5.6.5
--------------040909010802040402090002--
More information about the wine-patches
mailing list