diff --git a/dlls/msxml3/node.c b/dlls/msxml3/node.c index 9598e2913d0..7056ca3a0f2 100644 --- a/dlls/msxml3/node.c +++ b/dlls/msxml3/node.c @@ -671,6 +671,8 @@ static HRESULT WINAPI xmlnode_removeChild( { xmlnode *This = impl_from_IXMLDOMNode( iface ); xmlNode *child_node_ptr; + HRESULT hr; + IXMLDOMNode *child; TRACE("%p->(%p, %p)\n", This, childNode, oldChild); @@ -679,15 +681,22 @@ static HRESULT WINAPI xmlnode_removeChild( if(oldChild) *oldChild = NULL; - child_node_ptr = impl_from_IXMLDOMNode(childNode)->node; + hr = IXMLDOMNode_QueryInterface(childNode, &IID_IXMLDOMNode, (LPVOID)&child); + if(FAILED(hr)) + return hr; + + child_node_ptr = impl_from_IXMLDOMNode(child)->node; if(child_node_ptr->parent != This->node) { WARN("childNode %p is not a child of %p\n", childNode, iface); + IXMLDOMNode_Release(child); return E_INVALIDARG; } xmlUnlinkNode(child_node_ptr); + IXMLDOMNode_Release(child); + if(oldChild) { IXMLDOMNode_AddRef(childNode); diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c index 1645e2f140e..aeb53d723db 100644 --- a/dlls/msxml3/tests/domdoc.c +++ b/dlls/msxml3/tests/domdoc.c @@ -1791,7 +1791,7 @@ static void test_removeChild(void) BSTR str; VARIANT_BOOL b; IXMLDOMDocument *doc; - IXMLDOMElement *element; + IXMLDOMElement *element, *lc_element; IXMLDOMNode *fo_node, *ba_node, *removed_node, *temp_node, *lc_node; IXMLDOMNodeList *root_list, *fo_list; @@ -1855,7 +1855,11 @@ static void test_removeChild(void) r = IXMLDOMNodeList_get_item( root_list, 0, &lc_node ); ok( r == S_OK, "ret %08x\n", r); - r = IXMLDOMElement_removeChild( element, lc_node, NULL ); + r = IXMLDOMElement_QueryInterface( lc_node, &IID_IXMLDOMElement, (LPVOID*)&lc_element ); + ok( r == S_OK, "ret %08x\n", r); + + /* MS quirk: passing wrong interface pointer works, too */ + r = IXMLDOMElement_removeChild( element, (IXMLDOMNode*)lc_element, NULL ); ok( r == S_OK, "ret %08x\n", r); r = IXMLDOMNode_get_parentNode( lc_node, &temp_node );