Nikolay Sivov : msxml3: Block attempt to modify namespace definition with setAttribute().
Alexandre Julliard
julliard at winehq.org
Thu Oct 27 13:30:13 CDT 2011
Module: wine
Branch: master
Commit: fe1f692d91498b221e32b55313a30d4fe7da316e
URL: http://source.winehq.org/git/wine.git/?a=commit;h=fe1f692d91498b221e32b55313a30d4fe7da316e
Author: Nikolay Sivov <nsivov at 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\">"
+ " <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\">"
-" <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();
}
More information about the wine-cvs
mailing list