From d04fd1d067c375f8536576531690f3309f836d08 Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Thu, 3 Mar 2011 03:50:04 +0300 Subject: [PATCH] msxml3: Fail on certain node types in insertBefore() for attributes, remove broken tests. --- dlls/msxml3/attribute.c | 25 ++++- dlls/msxml3/tests/domdoc.c | 245 +++++++++++++++++++++++++++------------------ 2 files changed, 167 insertions(+), 103 deletions(-) diff --git a/dlls/msxml3/attribute.c b/dlls/msxml3/attribute.c index 170f6326471..a6196a120b3 100644 --- a/dlls/msxml3/attribute.c +++ b/dlls/msxml3/attribute.c @@ -309,13 +309,32 @@ static HRESULT WINAPI domattr_get_attributes( static HRESULT WINAPI domattr_insertBefore( IXMLDOMAttribute *iface, IXMLDOMNode* newNode, VARIANT refChild, - IXMLDOMNode** outOldNode) + IXMLDOMNode** old_node) { domattr *This = impl_from_IXMLDOMAttribute( iface ); + DOMNodeType type; + HRESULT hr; + + FIXME("(%p)->(%p %s %p) needs test\n", This, newNode, debugstr_variant(&refChild), old_node); - FIXME("(%p)->(%p %s %p) needs test\n", This, newNode, debugstr_variant(&refChild), outOldNode); + if (!newNode) return E_INVALIDARG; - return node_insert_before(&This->node, newNode, &refChild, outOldNode); + hr = IXMLDOMNode_get_nodeType(newNode, &type); + if (hr != S_OK) return hr; + + TRACE("new node type %d\n", type); + switch (type) + { + case NODE_ATTRIBUTE: + case NODE_CDATA_SECTION: + case NODE_COMMENT: + case NODE_ELEMENT: + case NODE_PROCESSING_INSTRUCTION: + if (old_node) *old_node = NULL; + return E_FAIL; + default: + return node_insert_before(&This->node, newNode, &refChild, old_node); + } } static HRESULT WINAPI domattr_replaceChild( diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c index c8529330771..c1548603c2d 100644 --- a/dlls/msxml3/tests/domdoc.c +++ b/dlls/msxml3/tests/domdoc.c @@ -2476,13 +2476,18 @@ static void test_create(void) IXMLDOMNode_Release( unk ); V_VT(&var) = VT_EMPTY; + child = NULL; r = IXMLDOMNode_insertBefore( root, (IXMLDOMNode*)unk, var, &child ); ok( r == S_OK, "returns %08x\n", r ); ok( unk == (IUnknown*)child, "%p %p\n", unk, child ); + + ref = IXMLDOMNode_AddRef( unk ); + todo_wine ok(ref == 5, "ref = %d\n", ref); + IXMLDOMNode_Release( unk ); + IXMLDOMNode_Release( child ); IUnknown_Release( unk ); - V_VT(&var) = VT_NULL; V_DISPATCH(&var) = (IDispatch*)node; r = IXMLDOMNode_insertBefore( root, node, var, &child ); @@ -2490,7 +2495,6 @@ static void test_create(void) ok( node == child, "%p %p\n", node, child ); IXMLDOMNode_Release( child ); - V_VT(&var) = VT_NULL; V_DISPATCH(&var) = (IDispatch*)node; r = IXMLDOMNode_insertBefore( root, node, var, NULL ); @@ -7215,6 +7219,7 @@ static void test_setAttributeNode(void) HRESULT hr; VARIANT v; BSTR str; + ULONG ref1, ref2; doc = create_document(&IID_IXMLDOMDocument); if (!doc) return; @@ -7236,11 +7241,19 @@ static void test_setAttributeNode(void) hr = IXMLDOMDocument_createAttribute(doc, _bstr_("attr"), &attr); ok( hr == S_OK, "got 0x%08x\n", hr); + ref1 = IXMLDOMElement_AddRef(elem); + IXMLDOMElement_Release(elem); + ret_attr = (void*)0xdeadbeef; hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr); ok( hr == S_OK, "got 0x%08x\n", hr); ok( ret_attr == NULL, "got %p\n", ret_attr); + /* no reference added */ + ref2 = IXMLDOMElement_AddRef(elem); + IXMLDOMElement_Release(elem); + ok(ref2 == ref1, "got %d, expected %d\n", ref2, ref1); + b = VARIANT_FALSE; hr = IXMLDOMElement_hasChildNodes(elem, &b); ok( hr == S_OK, "got 0x%08x\n", hr); @@ -7283,137 +7296,63 @@ static void test_setAttributeNode(void) todo_wine ok( hr == E_FAIL, "got 0x%08x\n", hr); IXMLDOMElement_Release(elem); - IXMLDOMDocument_Release(doc2); IXMLDOMAttribute_Release(attr); - IXMLDOMDocument_Release(doc); - - hr = CoCreateInstance( &CLSID_DOMDocument40, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&doc ); - if (hr != S_OK) - { - win_skip("DOMDocument40 is not available (0x%08x)\n", hr); - return; - } - - /* try attribute with xmlns name */ - V_VT(&v) = VT_I4; - V_I4(&v) = NODE_ELEMENT; - hr = IXMLDOMDocument_createNode(doc, v, _bstr_("test"), _bstr_("http://winehq.org/default"), (IXMLDOMNode**)&elem); + /* create element, add attribute, see if it's copied or linked */ + hr = IXMLDOMDocument_createElement(doc, _bstr_("test"), &elem); ok( hr == S_OK, "got 0x%08x\n", hr); - V_VT(&v) = VT_I4; - V_I4(&v) = NODE_ATTRIBUTE; - attr = NULL; - hr = IXMLDOMDocument_createNode(doc, v, _bstr_("xmlns"), NULL, (IXMLDOMNode**)&attr); + hr = IXMLDOMDocument_createAttribute(doc, _bstr_("attr"), &attr); ok(hr == S_OK, "got 0x%08x\n", hr); ok(attr != NULL, "got %p\n", attr); + ref1 = IXMLDOMAttribute_AddRef(attr); + IXMLDOMAttribute_Release(attr); + V_VT(&v) = VT_BSTR; - V_BSTR(&v) = _bstr_("http://winehq.org/default"); + V_BSTR(&v) = _bstr_("attrvalue1"); hr = IXMLDOMAttribute_put_nodeValue(attr, v); ok( hr == S_OK, "got 0x%08x\n", hr); - ret_attr = (void*)0xdeadbeef; - hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr); - ok(hr == DISP_E_UNKNOWNNAME, "got 0x%08x\n", hr); - ok(ret_attr == (void*)0xdeadbeef, "got %p\n", ret_attr); - - /* no child node added actually */ - b = VARIANT_TRUE; - hr = IXMLDOMElement_hasChildNodes(elem, &b); - ok( hr == S_FALSE, "got 0x%08x\n", hr); - ok(b == VARIANT_FALSE, "got %d\n", b); - - /* a single namespace definition as output */ - hr = IXMLDOMElement_get_xml(elem, &str); + str = NULL; + hr = IXMLDOMAttribute_get_xml(attr, &str); ok( hr == S_OK, "got 0x%08x\n", hr); - ok( lstrcmpW(str, _bstr_("")) == 0, + ok( lstrcmpW(str, _bstr_("attr=\"attrvalue1\"")) == 0, "got %s\n", wine_dbgstr_w(str)); SysFreeString(str); - /* alter value isn't possible after creation? */ - V_VT(&v) = VT_BSTR; - V_BSTR(&v) = _bstr_("http://winehq.org/default1"); - hr = IXMLDOMAttribute_put_nodeValue(attr, v); - ok( hr == S_OK, "got 0x%08x\n", hr); - - IXMLDOMElement_Release(elem); - IXMLDOMAttribute_Release(attr); - - /* try to alter it with different attribute value */ - V_VT(&v) = VT_I4; - V_I4(&v) = NODE_ELEMENT; - - hr = IXMLDOMDocument_createNode(doc, v, _bstr_("test"), _bstr_("http://winehq.org/default"), (IXMLDOMNode**)&elem); - ok( hr == S_OK, "got 0x%08x\n", hr); - - V_VT(&v) = VT_I4; - V_I4(&v) = NODE_ATTRIBUTE; - - hr = IXMLDOMDocument_createNode(doc, v, _bstr_("xmlns"), NULL, (IXMLDOMNode**)&attr); - ok( hr == S_OK, "got 0x%08x\n", hr); - - V_VT(&v) = VT_BSTR; - V_BSTR(&v) = _bstr_("http://winehq.org/default1"); - hr = IXMLDOMAttribute_put_nodeValue(attr, v); - ok( hr == S_OK, "got 0x%08x\n", hr); - ret_attr = (void*)0xdeadbeef; hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr); - ok( hr == DISP_E_UNKNOWNNAME, "got 0x%08x\n", hr); - ok(ret_attr == (void*)0xdeadbeef, "got %p\n", ret_attr); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(ret_attr == NULL, "got %p\n", ret_attr); - /* no child node added actually */ - b = VARIANT_TRUE; - hr = IXMLDOMElement_hasChildNodes(elem, &b); - ok( hr == S_FALSE, "got 0x%08x\n", hr); - ok(b == VARIANT_FALSE, "got %d\n", b); + /* attribute reference increased */ + ref2 = IXMLDOMAttribute_AddRef(attr); + IXMLDOMAttribute_Release(attr); + ok(ref1 == ref2, "got %d, expected %d\n", ref2, ref1); - /* initial value preserved */ hr = IXMLDOMElement_get_xml(elem, &str); ok( hr == S_OK, "got 0x%08x\n", hr); - ok( lstrcmpW(str, _bstr_("")) == 0, + ok( lstrcmpW(str, _bstr_("")) == 0, "got %s\n", wine_dbgstr_w(str)); SysFreeString(str); - IXMLDOMElement_Release(elem); - IXMLDOMAttribute_Release(attr); - - /* now create without default namespace and add it as attribute */ - V_VT(&v) = VT_I4; - V_I4(&v) = NODE_ELEMENT; - - hr = IXMLDOMDocument_createNode(doc, v, _bstr_("test"), NULL, (IXMLDOMNode**)&elem); - ok( hr == S_OK, "got 0x%08x\n", hr); - - V_VT(&v) = VT_I4; - V_I4(&v) = NODE_ATTRIBUTE; - - hr = IXMLDOMDocument_createNode(doc, v, _bstr_("xmlns"), NULL, (IXMLDOMNode**)&attr); - ok( hr == S_OK, "got 0x%08x\n", hr); - V_VT(&v) = VT_BSTR; - V_BSTR(&v) = _bstr_("http://winehq.org/default"); + V_BSTR(&v) = _bstr_("attrvalue2"); hr = IXMLDOMAttribute_put_nodeValue(attr, v); ok( hr == S_OK, "got 0x%08x\n", hr); - ret_attr = (void*)0xdeadbeef; - hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr); - ok(hr == DISP_E_UNKNOWNNAME, "got 0x%08x\n", hr); - ok(ret_attr == (void*)0xdeadbeef, "got %p\n", ret_attr); - - /* no child node added */ - b = VARIANT_TRUE; - hr = IXMLDOMElement_hasChildNodes(elem, &b); - ok( hr == S_FALSE, "got 0x%08x\n", hr); - ok(b == VARIANT_FALSE, "got %d\n", b); + hr = IXMLDOMElement_get_xml(elem, &str); + ok( hr == S_OK, "got 0x%08x\n", hr); + todo_wine ok( lstrcmpW(str, _bstr_("")) == 0, + "got %s\n", wine_dbgstr_w(str)); + SysFreeString(str); IXMLDOMElement_Release(elem); IXMLDOMAttribute_Release(attr); - + IXMLDOMDocument_Release(doc2); IXMLDOMDocument_Release(doc); - free_bstrs(); } static void test_put_dataType(void) @@ -8033,6 +7972,111 @@ todo_wine { free_bstrs(); } +static void test_insertBefore(void) +{ + IXMLDOMDocument *doc; + IXMLDOMAttribute *attr; + IXMLDOMNode *node, *newnode; + HRESULT hr; + VARIANT v; + + doc = create_document(&IID_IXMLDOMDocument); + + /* insertBefore behaviour for attribute node */ + V_VT(&v) = VT_I4; + V_I4(&v) = NODE_ATTRIBUTE; + + attr = NULL; + hr = IXMLDOMDocument_createNode(doc, v, _bstr_("attr"), NULL, (IXMLDOMNode**)&attr); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(attr != NULL, "got %p\n", attr); + + /* attribute to attribute */ + V_VT(&v) = VT_I4; + V_I4(&v) = NODE_ATTRIBUTE; + newnode = NULL; + hr = IXMLDOMDocument_createNode(doc, v, _bstr_("attr2"), NULL, &newnode); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(newnode != NULL, "got %p\n", newnode); + + V_VT(&v) = VT_NULL; + node = (void*)0xdeadbeef; + hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node); + ok(hr == E_FAIL, "got 0x%08x\n", hr); + ok(node == NULL, "got %p\n", node); + + V_VT(&v) = VT_UNKNOWN; + V_UNKNOWN(&v) = (IUnknown*)attr; + node = (void*)0xdeadbeef; + hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node); + todo_wine ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + ok(node == NULL, "got %p\n", node); + IXMLDOMNode_Release(newnode); + + /* cdata to attribute */ + V_VT(&v) = VT_I4; + V_I4(&v) = NODE_CDATA_SECTION; + newnode = NULL; + hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(newnode != NULL, "got %p\n", newnode); + + V_VT(&v) = VT_NULL; + node = (void*)0xdeadbeef; + hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node); + ok(hr == E_FAIL, "got 0x%08x\n", hr); + ok(node == NULL, "got %p\n", node); + IXMLDOMNode_Release(newnode); + + /* comment to attribute */ + V_VT(&v) = VT_I4; + V_I4(&v) = NODE_COMMENT; + newnode = NULL; + hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(newnode != NULL, "got %p\n", newnode); + + V_VT(&v) = VT_NULL; + node = (void*)0xdeadbeef; + hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node); + ok(hr == E_FAIL, "got 0x%08x\n", hr); + ok(node == NULL, "got %p\n", node); + IXMLDOMNode_Release(newnode); + + /* element to attribute */ + V_VT(&v) = VT_I4; + V_I4(&v) = NODE_ELEMENT; + newnode = NULL; + hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(newnode != NULL, "got %p\n", newnode); + + V_VT(&v) = VT_NULL; + node = (void*)0xdeadbeef; + hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node); + ok(hr == E_FAIL, "got 0x%08x\n", hr); + ok(node == NULL, "got %p\n", node); + IXMLDOMNode_Release(newnode); + + /* pi to attribute */ + V_VT(&v) = VT_I4; + V_I4(&v) = NODE_PROCESSING_INSTRUCTION; + newnode = NULL; + hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(newnode != NULL, "got %p\n", newnode); + + V_VT(&v) = VT_NULL; + node = (void*)0xdeadbeef; + hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node); + ok(hr == E_FAIL, "got 0x%08x\n", hr); + ok(node == NULL, "got %p\n", node); + IXMLDOMNode_Release(newnode); + + IXMLDOMDocument_Release(doc); + free_bstrs(); +} + START_TEST(domdoc) { IXMLDOMDocument *doc; @@ -8097,6 +8141,7 @@ START_TEST(domdoc) test_createProcessingInstruction(); test_put_nodeTypedValue(); test_get_xml(); + test_insertBefore(); test_xsltemplate(); CoUninitialize(); -- 2.11.4.GIT