Module: wine Branch: master Commit: 02cd5a008f011fcd8a58b8346fb536d576227ffb URL: http://source.winehq.org/git/wine.git/?a=commit;h=02cd5a008f011fcd8a58b8346f...
Author: Nikolay Sivov nsivov@codeweavers.com Date: Sat Nov 12 17:14:11 2011 +0300
msxml3: Fix getNamedItem() for qualified node names.
---
dlls/msxml3/nodemap.c | 42 +++++++++++++++- dlls/msxml3/tests/domdoc.c | 110 +++++++++++++++++++++++++++++++++++++------ 2 files changed, 133 insertions(+), 19 deletions(-)
diff --git a/dlls/msxml3/nodemap.c b/dlls/msxml3/nodemap.c index ebc2bd5..47adcd9 100644 --- a/dlls/msxml3/nodemap.c +++ b/dlls/msxml3/nodemap.c @@ -199,11 +199,47 @@ static HRESULT WINAPI xmlnodemap_Invoke( static HRESULT WINAPI xmlnodemap_getNamedItem( IXMLDOMNamedNodeMap *iface, BSTR name, - IXMLDOMNode** namedItem) + IXMLDOMNode** item) { xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface ); - TRACE("(%p)->(%s %p)\n", This, debugstr_w(name), namedItem ); - return IXMLDOMNamedNodeMap_getQualifiedItem(iface, name, NULL, namedItem); + xmlChar *nameA, *local, *prefix; + BSTR uriW, localW; + xmlNsPtr ns; + HRESULT hr; + + TRACE("(%p)->(%s %p)\n", This, debugstr_w(name), item ); + + nameA = xmlchar_from_wchar(name); + local = xmlSplitQName2(nameA, &prefix); + heap_free(nameA); + + if (!local) + return IXMLDOMNamedNodeMap_getQualifiedItem(iface, name, NULL, item); + + /* try to get namespace uri for supplied qualified name */ + ns = xmlSearchNs(This->node->doc, This->node, prefix); + + xmlFree(prefix); + + if (!ns) + { + xmlFree(local); + if (item) *item = NULL; + return item ? S_FALSE : E_INVALIDARG; + } + + uriW = bstr_from_xmlChar(ns->href); + localW = bstr_from_xmlChar(local); + xmlFree(local); + + TRACE("got qualified node %s, uri=%s\n", debugstr_w(localW), debugstr_w(uriW)); + + hr = IXMLDOMNamedNodeMap_getQualifiedItem(iface, localW, uriW, item); + + SysFreeString(localW); + SysFreeString(uriW); + + return hr; }
static HRESULT WINAPI xmlnodemap_setNamedItem( diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c index affdfaa..a79da43 100644 --- a/dlls/msxml3/tests/domdoc.c +++ b/dlls/msxml3/tests/domdoc.c @@ -1746,6 +1746,12 @@ static const char* leading_spaces[] = { 0 };
+static const char default_ns_doc[] = { + "<?xml version=\"1.0\"?>" + "<a xmlns:ns="nshref" xml:lang="ru" ns:b="b attr" xml:c="c attr" " + " d="d attr" />" +}; + static const WCHAR szNonExistentFile[] = { 'c', ':', '\', 'N', 'o', 'n', 'e', 'x', 'i', 's', 't', 'e', 'n', 't', '.', 'x', 'm', 'l', 0 }; @@ -7973,63 +7979,135 @@ static void test_splitText(void) free_bstrs(); }
+typedef struct { + const char *name; + const char *uri; + HRESULT hr; +} ns_item_t; + +/* default_ns_doc used */ +static const ns_item_t qualified_item_tests[] = { + { "xml:lang", NULL, S_FALSE }, + { "xml:lang", "http://www.w3.org/XML/1998/namespace", S_FALSE }, + { "lang", "http://www.w3.org/XML/1998/namespace", S_OK }, + { "ns:b", NULL, S_FALSE }, + { "ns:b", "nshref", S_FALSE }, + { "b", "nshref", S_OK }, + { "d", NULL, S_OK }, + { NULL } +}; + +static const ns_item_t named_item_tests[] = { + { "xml:lang", NULL, S_OK }, + { "lang", NULL, S_FALSE }, + { "ns:b", NULL, S_OK }, + { "b", NULL, S_FALSE }, + { "d", NULL, S_OK }, + { NULL } +}; + static void test_getQualifiedItem(void) { - IXMLDOMDocument *doc; - IXMLDOMElement *element; IXMLDOMNode *pr_node, *node; IXMLDOMNodeList *root_list; IXMLDOMNamedNodeMap *map; + IXMLDOMElement *element; + const ns_item_t* ptr; + IXMLDOMDocument *doc; VARIANT_BOOL b; + HRESULT hr; BSTR str; LONG len; - HRESULT hr;
doc = create_document(&IID_IXMLDOMDocument); if (!doc) return;
str = SysAllocString( szComplete4 ); hr = IXMLDOMDocument_loadXML( doc, str, &b ); - ok( hr == S_OK, "loadXML failed\n"); + EXPECT_HR(hr, S_OK); ok( b == VARIANT_TRUE, "failed to load XML string\n"); SysFreeString( str );
hr = IXMLDOMDocument_get_documentElement(doc, &element); - ok( hr == S_OK, "ret %08x\n", hr); + EXPECT_HR(hr, S_OK);
hr = IXMLDOMElement_get_childNodes(element, &root_list); - ok( hr == S_OK, "ret %08x\n", hr); + EXPECT_HR(hr, S_OK);
hr = IXMLDOMNodeList_get_item(root_list, 1, &pr_node); - ok( hr == S_OK, "ret %08x\n", hr); + EXPECT_HR(hr, S_OK); IXMLDOMNodeList_Release(root_list);
hr = IXMLDOMNode_get_attributes(pr_node, &map); - ok( hr == S_OK, "ret %08x\n", hr); + EXPECT_HR(hr, S_OK); IXMLDOMNode_Release(pr_node);
+ len = 0; hr = IXMLDOMNamedNodeMap_get_length(map, &len); - ok( hr == S_OK, "ret %08x\n", hr); + EXPECT_HR(hr, S_OK); ok( len == 3, "length %d\n", len);
hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, NULL, NULL, NULL); - ok( hr == E_INVALIDARG, "ret %08x\n", hr); + EXPECT_HR(hr, E_INVALIDARG);
node = (void*)0xdeadbeef; hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, NULL, NULL, &node); - ok( hr == E_INVALIDARG, "ret %08x\n", hr); + EXPECT_HR(hr, E_INVALIDARG); ok( node == (void*)0xdeadbeef, "got %p\n", node);
hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, _bstr_("id"), NULL, NULL); - ok( hr == E_INVALIDARG, "ret %08x\n", hr); + EXPECT_HR(hr, E_INVALIDARG);
hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, _bstr_("id"), NULL, &node); - ok( hr == S_OK, "ret %08x\n", hr); + EXPECT_HR(hr, S_OK); + IXMLDOMNode_Release(node); + IXMLDOMNamedNodeMap_Release(map); + IXMLDOMElement_Release(element);
- IXMLDOMNamedNodeMap_Release( map ); - IXMLDOMElement_Release( element ); - IXMLDOMDocument_Release( doc ); + hr = IXMLDOMDocument_loadXML(doc, _bstr_(default_ns_doc), &b); + EXPECT_HR(hr, S_OK); + + hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("a"), &node); + EXPECT_HR(hr, S_OK); + + hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&element); + EXPECT_HR(hr, S_OK); + IXMLDOMNode_Release(node); + + hr = IXMLDOMElement_get_attributes(element, &map); + EXPECT_HR(hr, S_OK); + + ptr = qualified_item_tests; + while (ptr->name) + { + node = (void*)0xdeadbeef; + hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, _bstr_(ptr->name), _bstr_(ptr->uri), &node); + ok(hr == ptr->hr, "%s, %s: got 0x%08x, expected 0x%08x\n", ptr->name, ptr->uri, hr, ptr->hr); + if (hr == S_OK) + IXMLDOMNode_Release(node); + else + ok(node == NULL, "%s, %s: got %p\n", ptr->name, ptr->uri, node); + ptr++; + } + + ptr = named_item_tests; + while (ptr->name) + { + node = (void*)0xdeadbeef; + hr = IXMLDOMNamedNodeMap_getNamedItem(map, _bstr_(ptr->name), &node); + ok(hr == ptr->hr, "%s: got 0x%08x, expected 0x%08x\n", ptr->name, hr, ptr->hr); + if (hr == S_OK) + IXMLDOMNode_Release(node); + else + ok(node == NULL, "%s: got %p\n", ptr->name, node); + ptr++; + } + + IXMLDOMNamedNodeMap_Release(map); + + IXMLDOMElement_Release(element); + IXMLDOMDocument_Release(doc); free_bstrs(); }