Module: wine Branch: master Commit: fe1f692d91498b221e32b55313a30d4fe7da316e URL: http://source.winehq.org/git/wine.git/?a=commit;h=fe1f692d91498b221e32b55313...
Author: Nikolay Sivov nsivov@codeweavers.com Date: Thu Oct 27 20:30:45 2011 +0400
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 6cd3a6d..834f39b 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 0acfa25..62ccb4e 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[] = + "<?xml version=\"1.0\"?>\n" + "<XMI xmi.version="1.1" xmlns:Model="http://omg.org/mof.Model/1.3%5C%22%3E" + " <XMI.content>" + " <Model:Package name="WinePackage" />" + " </XMI.content>" + "</XMI>"; + IXMLDOMDocument *doc; - IXMLDOMNode *pNode; + IXMLDOMElement *elem; + IXMLDOMNode *node; IXMLDOMNode *pNode2 = NULL; VARIANT_BOOL bSucc; + VARIANT var; HRESULT hr; BSTR str; - static const CHAR szNamespacesXML[] = -"<?xml version=\"1.0\"?>\n" -"<XMI xmi.version="1.1" xmlns:Model="http://omg.org/mof.Model/1.3%5C%22%3E" -" <XMI.content>" -" <Model:Package name="WinePackage" />" -" </XMI.content>" -"</XMI>";
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_("<ns:elem xmlns:ns="ns/uri"/>")), "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_("<ns:elem xmlns:ns="ns/uri"/>")), "got element %s\n", wine_dbgstr_w(str)); + SysFreeString(str); + + IXMLDOMElement_Release(elem); + IXMLDOMDocument_Release(doc); + free_bstrs(); }