From fe1f692d91498b221e32b55313a30d4fe7da316e Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Thu, 27 Oct 2011 20:30:45 +0400 Subject: [PATCH] msxml3: Block attempt to modify namespace definition with setAttribute(). --- dlls/msxml3/element.c | 20 +++++++- dlls/msxml3/tests/domdoc.c | 99 +++++++++++++++++++++++++++++++++----- 2 files changed, 106 insertions(+), 13 deletions(-) diff --git a/dlls/msxml3/element.c b/dlls/msxml3/element.c index 6cd3a6df847..834f39b7c02 100644 --- a/dlls/msxml3/element.c +++ b/dlls/msxml3/element.c @@ -1097,8 +1097,8 @@ static HRESULT WINAPI domelem_setAttribute( BSTR name, VARIANT value) { domelem *This = impl_from_IXMLDOMElement( iface ); + xmlChar *xml_name, *xml_value, *local, *prefix; xmlNodePtr element; - xmlChar *xml_name, *xml_value; HRESULT hr; VARIANT var; @@ -1119,7 +1119,23 @@ static HRESULT WINAPI domelem_setAttribute( xml_name = xmlchar_from_wchar( name ); xml_value = xmlchar_from_wchar( V_BSTR(&var) ); - if(!xmlSetNsProp(element, NULL, xml_name, xml_value)) + if ((local = xmlSplitQName2(xml_name, &prefix))) + { + static const xmlChar* xmlnsA = (const xmlChar*)"xmlns"; + xmlNsPtr ns = NULL; + + /* it's not allowed to modify existing namespace definition */ + if (xmlStrEqual(prefix, xmlnsA)) + ns = xmlSearchNs(element->doc, element, local); + + xmlFree(prefix); + xmlFree(local); + + if (ns) + return xmlStrEqual(ns->href, xml_value) ? S_OK : E_INVALIDARG; + } + + if (!xmlSetNsProp(element, NULL, xml_name, xml_value)) hr = E_FAIL; heap_free(xml_value); diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c index 0acfa25c34f..62ccb4e7be2 100644 --- a/dlls/msxml3/tests/domdoc.c +++ b/dlls/msxml3/tests/domdoc.c @@ -6995,19 +6995,22 @@ static void test_testTransforms(void) static void test_Namespaces(void) { + static const CHAR szNamespacesXML[] = + "\n" + "" + " " + " " + " " + ""; + IXMLDOMDocument *doc; - IXMLDOMNode *pNode; + IXMLDOMElement *elem; + IXMLDOMNode *node; IXMLDOMNode *pNode2 = NULL; VARIANT_BOOL bSucc; + VARIANT var; HRESULT hr; BSTR str; - static const CHAR szNamespacesXML[] = -"\n" -"" -" " -" " -" " -""; doc = create_document(&IID_IXMLDOMDocument); if (!doc) return; @@ -7016,11 +7019,11 @@ static void test_Namespaces(void) ok(hr == S_OK, "ret %08x\n", hr ); ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n"); - hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("//XMI.content"), &pNode ); + hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("//XMI.content"), &node ); ok(hr == S_OK, "ret %08x\n", hr ); if(hr == S_OK) { - hr = IXMLDOMNode_get_firstChild( pNode, &pNode2 ); + hr = IXMLDOMNode_get_firstChild( node, &pNode2 ); ok( hr == S_OK, "ret %08x\n", hr ); ok( pNode2 != NULL, "pNode2 == NULL\n"); @@ -7050,11 +7053,85 @@ static void test_Namespaces(void) SysFreeString(str); IXMLDOMNode_Release(pNode2); - IXMLDOMNode_Release(pNode); + IXMLDOMNode_Release(node); } IXMLDOMDocument_Release(doc); + /* create on element and try to alter namespace after that */ + doc = create_document(&IID_IXMLDOMDocument); + if (!doc) return; + + V_VT(&var) = VT_I2; + V_I2(&var) = NODE_ELEMENT; + + hr = IXMLDOMDocument_createNode(doc, var, _bstr_("ns:elem"), _bstr_("ns/uri"), &node); + EXPECT_HR(hr, S_OK); + + hr = IXMLDOMDocument_appendChild(doc, node, NULL); + EXPECT_HR(hr, S_OK); + + hr = IXMLDOMDocument_get_documentElement(doc, &elem); + EXPECT_HR(hr, S_OK); + + V_VT(&var) = VT_BSTR; + V_BSTR(&var) = _bstr_("ns/uri2"); + + hr = IXMLDOMElement_setAttribute(elem, _bstr_("xmlns:ns"), var); + EXPECT_HR(hr, E_INVALIDARG); + + V_VT(&var) = VT_BSTR; + V_BSTR(&var) = _bstr_("ns/uri"); + + hr = IXMLDOMElement_setAttribute(elem, _bstr_("xmlns:ns"), var); + EXPECT_HR(hr, S_OK); + + hr = IXMLDOMElement_get_xml(elem, &str); + EXPECT_HR(hr, S_OK); + ok(!lstrcmpW(str, _bstr_("")), "got element %s\n", wine_dbgstr_w(str)); + SysFreeString(str); + + IXMLDOMElement_Release(elem); + IXMLDOMDocument_Release(doc); + + /* create on element and try to alter namespace after that */ + doc = create_document_version(60, &IID_IXMLDOMDocument); + if (!doc) return; + + V_VT(&var) = VT_I2; + V_I2(&var) = NODE_ELEMENT; + + hr = IXMLDOMDocument_createNode(doc, var, _bstr_("ns:elem"), _bstr_("ns/uri"), &node); + EXPECT_HR(hr, S_OK); + + hr = IXMLDOMDocument_appendChild(doc, node, NULL); + EXPECT_HR(hr, S_OK); + + hr = IXMLDOMDocument_get_documentElement(doc, &elem); + EXPECT_HR(hr, S_OK); + + /* try same prefix, different uri */ + V_VT(&var) = VT_BSTR; + V_BSTR(&var) = _bstr_("ns/uri2"); + + hr = IXMLDOMElement_setAttribute(elem, _bstr_("xmlns:ns"), var); + EXPECT_HR(hr, E_INVALIDARG); + + /* try same prefix and uri */ + V_VT(&var) = VT_BSTR; + V_BSTR(&var) = _bstr_("ns/uri"); + + hr = IXMLDOMElement_setAttribute(elem, _bstr_("xmlns:ns"), var); + EXPECT_HR(hr, S_OK); + + hr = IXMLDOMElement_get_xml(elem, &str); + EXPECT_HR(hr, S_OK); + ok(!lstrcmpW(str, _bstr_("")), "got element %s\n", wine_dbgstr_w(str)); + SysFreeString(str); + + IXMLDOMElement_Release(elem); + IXMLDOMDocument_Release(doc); + free_bstrs(); }