From f87aee778da3109b6065f1bdd2fb2636ce17f95a Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Mon, 14 Nov 2011 13:48:36 +0300 Subject: [PATCH] msxml3: Properly handle qualified names in getAttributeNode(). --- dlls/msxml3/element.c | 55 +++++++++++++++++-------- dlls/msxml3/tests/domdoc.c | 82 ++++++++++++++++++++++++++++---------- 2 files changed, 98 insertions(+), 39 deletions(-) diff --git a/dlls/msxml3/element.c b/dlls/msxml3/element.c index 0863a1629d2..57fef4c484f 100644 --- a/dlls/msxml3/element.c +++ b/dlls/msxml3/element.c @@ -1171,40 +1171,61 @@ static HRESULT WINAPI domelem_getAttributeNode( BSTR p, IXMLDOMAttribute** attributeNode ) { domelem *This = impl_from_IXMLDOMElement( iface ); - xmlChar *xml_name; + xmlChar *local, *prefix, *nameA; + HRESULT hr = S_FALSE; xmlNodePtr element; xmlAttrPtr attr; - IUnknown *unk; - HRESULT hr = S_FALSE; TRACE("(%p)->(%s %p)\n", This, debugstr_w(p), attributeNode); - if(!attributeNode) + element = get_element( This ); + if (!element) return E_FAIL; + + if (attributeNode) *attributeNode = NULL; + + nameA = xmlchar_from_wchar(p); + if (!xmlValidateNameValue(nameA)) + { + heap_free(nameA); return E_FAIL; + } + + if (!attributeNode) + { + heap_free(nameA); + return S_FALSE; + } *attributeNode = NULL; - element = get_element( This ); - if ( !element ) - return E_FAIL; + local = xmlSplitQName2(nameA, &prefix); - xml_name = xmlchar_from_wchar(p); - - if(!xmlValidateNameValue(xml_name)) + if (local) { - heap_free(xml_name); - return E_FAIL; + /* try to get namespace for supplied qualified name */ + xmlNsPtr ns = xmlSearchNs(element->doc, element, prefix); + xmlFree(prefix); + + attr = xmlHasNsProp(element, local, ns ? ns->href : NULL); + xmlFree(local); + } + else + { + attr = xmlHasProp(element, nameA); + /* attribute has attached namespace and we requested non-qualified + name - it's a failure case */ + if (attr && attr->ns) attr = NULL; } - attr = xmlHasProp(element, xml_name); - if(attr) { - unk = create_attribute((xmlNodePtr)attr); + heap_free(nameA); + + if (attr) + { + IUnknown *unk = create_attribute((xmlNodePtr)attr); hr = IUnknown_QueryInterface(unk, &IID_IXMLDOMAttribute, (void**)attributeNode); IUnknown_Release(unk); } - heap_free(xml_name); - return hr; } diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c index dfad107be90..eb1270d0456 100644 --- a/dlls/msxml3/tests/domdoc.c +++ b/dlls/msxml3/tests/domdoc.c @@ -1393,9 +1393,9 @@ static const CHAR szNonUnicodeXML[] = "\n" "\n"; -static const CHAR szExampleXML[] = +static const char szExampleXML[] = "\n" -"\n" +"\n" " \n" " A1 field\n" " B1 field\n" @@ -1752,10 +1752,10 @@ static const char default_ns_doc[] = { " d=\"d attr\" />" }; -static const WCHAR szNonExistentFile[] = { +static const WCHAR nonexistent_fileW[] = { 'c', ':', '\\', 'N', 'o', 'n', 'e', 'x', 'i', 's', 't', 'e', 'n', 't', '.', 'x', 'm', 'l', 0 }; -static const WCHAR szNonExistentAttribute[] = { +static const WCHAR nonexistent_attrW[] = { 'n','o','n','E','x','i','s','i','t','i','n','g','A','t','t','r','i','b','u','t','e',0 }; static const WCHAR szDocument[] = { @@ -2066,7 +2066,7 @@ if (0) /* try to load a document from a nonexistent file */ b = VARIANT_TRUE; - str = SysAllocString( szNonExistentFile ); + str = SysAllocString( nonexistent_fileW ); VariantInit(&var); V_VT(&var) = VT_BSTR; V_BSTR(&var) = str; @@ -2776,7 +2776,7 @@ static void test_domnode( void ) ok( !lstrcmpW( str, szlc ), "incorrect nodeName\n"); SysFreeString( str ); - str = SysAllocString( szNonExistentFile ); + str = SysAllocString( nonexistent_fileW ); V_VT(&var) = VT_I4; V_I4(&var) = 0x1234; r = IXMLDOMElement_getAttribute( element, str, &var ); @@ -2784,22 +2784,6 @@ static void test_domnode( void ) ok( V_VT(&var) == VT_NULL || V_VT(&var) == VT_EMPTY, "vt = %x\n", V_VT(&var)); VariantClear(&var); - r = IXMLDOMElement_getAttributeNode( element, str, NULL); - ok( r == E_FAIL, "getAttributeNode ret %08x\n", r ); - - attr = (IXMLDOMAttribute*)0xdeadbeef; - r = IXMLDOMElement_getAttributeNode( element, str, &attr); - ok( r == E_FAIL, "getAttributeNode ret %08x\n", r ); - ok( attr == NULL, "getAttributeNode ret %p, expected NULL\n", attr ); - SysFreeString( str ); - - attr = (IXMLDOMAttribute*)0xdeadbeef; - str = SysAllocString( szNonExistentAttribute ); - r = IXMLDOMElement_getAttributeNode( element, str, &attr); - ok( r == S_FALSE, "getAttributeNode ret %08x\n", r ); - ok( attr == NULL, "getAttributeNode ret %p, expected NULL\n", attr ); - SysFreeString( str ); - str = SysAllocString( szdl ); V_VT(&var) = VT_I4; V_I4(&var) = 0x1234; @@ -10662,6 +10646,59 @@ static void test_parseerror(void) IXMLDOMDocument_Release(doc); } +static void test_getAttributeNode(void) +{ + IXMLDOMAttribute *attr; + IXMLDOMDocument *doc; + IXMLDOMElement *elem; + VARIANT_BOOL v; + HRESULT hr; + BSTR str; + + doc = create_document(&IID_IXMLDOMDocument); + + hr = IXMLDOMDocument_loadXML(doc, _bstr_(szExampleXML), &v); + EXPECT_HR(hr, S_OK); + + hr = IXMLDOMDocument_get_documentElement(doc, &elem); + EXPECT_HR(hr, S_OK); + + str = SysAllocString(nonexistent_fileW); + hr = IXMLDOMElement_getAttributeNode(elem, str, NULL); + EXPECT_HR(hr, E_FAIL); + + attr = (IXMLDOMAttribute*)0xdeadbeef; + hr = IXMLDOMElement_getAttributeNode(elem, str, &attr); + EXPECT_HR(hr, E_FAIL); + ok(attr == NULL, "got %p\n", attr); + SysFreeString(str); + + str = SysAllocString(nonexistent_attrW); + hr = IXMLDOMElement_getAttributeNode(elem, str, NULL); + EXPECT_HR(hr, S_FALSE); + + attr = (IXMLDOMAttribute*)0xdeadbeef; + hr = IXMLDOMElement_getAttributeNode(elem, str, &attr); + EXPECT_HR(hr, S_FALSE); + ok(attr == NULL, "got %p\n", attr); + SysFreeString(str); + + hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("foo:b"), &attr); + EXPECT_HR(hr, S_OK); + IXMLDOMAttribute_Release(attr); + + hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("b"), &attr); + EXPECT_HR(hr, S_FALSE); + + hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("a"), &attr); + EXPECT_HR(hr, S_OK); + IXMLDOMAttribute_Release(attr); + + IXMLDOMElement_Release(elem); + IXMLDOMDocument_Release(doc); + free_bstrs(); +} + START_TEST(domdoc) { IXMLDOMDocument *doc; @@ -10735,6 +10772,7 @@ START_TEST(domdoc) test_load(); test_dispex(); test_parseerror(); + test_getAttributeNode(); test_xsltemplate();