Commit 0f658d9d authored by Nikolay Sivov's avatar Nikolay Sivov Committed by Alexandre Julliard

msxml3: Leading space chars are allowed in SelectionNamespaces value string.

parent c6c5c690
......@@ -2767,14 +2767,11 @@ static HRESULT WINAPI domdoc_setProperty(
}
else if (lstrcmpiW(p, PropertySelectionNamespacesW) == 0)
{
xmlChar *nsStr = (xmlChar*)This->properties->selectNsStr;
struct list *pNsList;
VARIANT varStr;
HRESULT hr;
BSTR bstr;
xmlChar *pTokBegin, *pTokEnd, *pTokInner;
xmlChar *nsStr = (xmlChar*)This->properties->selectNsStr;
xmlXPathContextPtr ctx;
struct list *pNsList;
select_ns_entry* pNsEntry = NULL;
V_VT(&varStr) = VT_EMPTY;
if (V_VT(&var) != VT_BSTR)
......@@ -2793,20 +2790,30 @@ static HRESULT WINAPI domdoc_setProperty(
heap_free(nsStr);
nsStr = xmlchar_from_wchar(bstr);
TRACE("Setting SelectionNamespaces property to: %s\n", nsStr);
TRACE("property value: \"%s\"\n", debugstr_w(bstr));
This->properties->selectNsStr = nsStr;
This->properties->selectNsStr_len = xmlStrlen(nsStr);
if (bstr && *bstr)
{
xmlChar *pTokBegin, *pTokEnd, *pTokInner;
select_ns_entry* ns_entry = NULL;
xmlXPathContextPtr ctx;
ctx = xmlXPathNewContext(This->node.node->doc);
pTokBegin = nsStr;
/* skip leading spaces */
while (*pTokBegin == ' ' || *pTokBegin == '\n' ||
*pTokBegin == '\t' || *pTokBegin == '\r')
++pTokBegin;
for (; *pTokBegin; pTokBegin = pTokEnd)
{
if (pNsEntry != NULL)
memset(pNsEntry, 0, sizeof(select_ns_entry));
if (ns_entry)
memset(ns_entry, 0, sizeof(select_ns_entry));
else
pNsEntry = heap_alloc_zero(sizeof(select_ns_entry));
ns_entry = heap_alloc_zero(sizeof(select_ns_entry));
while (*pTokBegin == ' ')
++pTokBegin;
......@@ -2831,7 +2838,7 @@ static HRESULT WINAPI domdoc_setProperty(
}
else if (*pTokBegin == ':')
{
pNsEntry->prefix = ++pTokBegin;
ns_entry->prefix = ++pTokBegin;
for (pTokInner = pTokBegin; pTokInner != pTokEnd && *pTokInner != '='; ++pTokInner)
;
......@@ -2843,7 +2850,7 @@ static HRESULT WINAPI domdoc_setProperty(
continue;
}
pNsEntry->prefix_end = *pTokInner;
ns_entry->prefix_end = *pTokInner;
*pTokInner = 0;
++pTokInner;
......@@ -2851,25 +2858,25 @@ static HRESULT WINAPI domdoc_setProperty(
((*pTokInner == '\'' && *(pTokEnd-1) == '\'') ||
(*pTokInner == '"' && *(pTokEnd-1) == '"')))
{
pNsEntry->href = ++pTokInner;
pNsEntry->href_end = *(pTokEnd-1);
ns_entry->href = ++pTokInner;
ns_entry->href_end = *(pTokEnd-1);
*(pTokEnd-1) = 0;
list_add_tail(pNsList, &pNsEntry->entry);
list_add_tail(pNsList, &ns_entry->entry);
/*let libxml figure out if they're valid from here ;)*/
if (xmlXPathRegisterNs(ctx, pNsEntry->prefix, pNsEntry->href) != 0)
if (xmlXPathRegisterNs(ctx, ns_entry->prefix, ns_entry->href) != 0)
{
hr = E_FAIL;
}
pNsEntry = NULL;
ns_entry = NULL;
continue;
}
else
{
WARN("Syntax error in xmlns string: %s\n\tat token: %s\n",
wine_dbgstr_w(bstr), wine_dbgstr_an((const char*)pTokInner, pTokEnd-pTokInner));
list_add_tail(pNsList, &pNsEntry->entry);
list_add_tail(pNsList, &ns_entry->entry);
pNsEntry = NULL;
ns_entry = NULL;
hr = E_FAIL;
continue;
}
......@@ -2880,7 +2887,7 @@ static HRESULT WINAPI domdoc_setProperty(
continue;
}
}
heap_free(pNsEntry);
heap_free(ns_entry);
xmlXPathFreeContext(ctx);
}
......
......@@ -5480,8 +5480,41 @@ static void test_whitespace(void)
free_bstrs();
}
static void test_XPath(void)
typedef struct {
const GUID *clsid;
const char *name;
const char *ns;
HRESULT hr;
} selection_ns_t;
/* supposed to be tested with szExampleXML */
static const selection_ns_t selection_ns_data[] = {
{ &CLSID_DOMDocument, "CLSID_DOMDocument", "\txmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
{ &CLSID_DOMDocument, "CLSID_DOMDocument", "\n\rxmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
{ &CLSID_DOMDocument, "CLSID_DOMDocument", " xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
{ &CLSID_DOMDocument2, "CLSID_DOMDocument2", "\txmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
{ &CLSID_DOMDocument2, "CLSID_DOMDocument2", "\n\rxmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
{ &CLSID_DOMDocument2, "CLSID_DOMDocument2", " xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
{ &CLSID_DOMDocument30, "CLSID_DOMDocument30", "\txmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
{ &CLSID_DOMDocument30, "CLSID_DOMDocument30", "\n\rxmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
{ &CLSID_DOMDocument30, "CLSID_DOMDocument30", " xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
{ &CLSID_DOMDocument40, "CLSID_DOMDocument40", "\txmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
{ &CLSID_DOMDocument40, "CLSID_DOMDocument40", "\n\rxmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
{ &CLSID_DOMDocument40, "CLSID_DOMDocument40", " xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
{ &CLSID_DOMDocument60, "CLSID_DOMDocument60", "\txmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
{ &CLSID_DOMDocument60, "CLSID_DOMDocument60", "\n\rxmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
{ &CLSID_DOMDocument60, "CLSID_DOMDocument60", " xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK },
{ NULL }
};
void test_XPath(void)
{
const selection_ns_t *ptr = selection_ns_data;
VARIANT var;
VARIANT_BOOL b;
IXMLDOMDocument2 *doc;
......@@ -5498,7 +5531,8 @@ static void test_XPath(void)
doc = create_document(&IID_IXMLDOMDocument2);
if (!doc) return;
ole_check(IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b));
hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
EXPECT_HR(hr, S_OK);
ok(b == VARIANT_TRUE, "failed to load XML string\n");
/* switch to XPath */
......@@ -5711,8 +5745,47 @@ static void test_XPath(void)
IXMLDOMNode_Release(rootNode);
IXMLDOMNodeList_Release(list);
IXMLDOMDocument_Release(doc2);
IXMLDOMDocument2_Release(doc);
while (ptr->clsid)
{
hr = CoCreateInstance(ptr->clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (void**)&doc);
if (hr != S_OK)
{
win_skip("can't create instance of %s\n", ptr->name);
ptr++;
continue;
}
hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
EXPECT_HR(hr, S_OK);
ok(b == VARIANT_TRUE, "failed to load, %s\n", ptr->name);
hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XPath"));
EXPECT_HR(hr, S_OK);
V_VT(&var) = VT_BSTR;
V_BSTR(&var) = _bstr_(ptr->ns);
hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), var);
ok(hr == ptr->hr, "got 0x%08x, for %s, %s\n", hr, ptr->name, ptr->ns);
V_VT(&var) = VT_EMPTY;
hr = IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var);
EXPECT_HR(hr, S_OK);
ok(V_VT(&var) == VT_BSTR, "got wrong property type %d\n", V_VT(&var));
ok(!lstrcmpW(V_BSTR(&var), _bstr_(ptr->ns)), "got wrong value %s\n", wine_dbgstr_w(V_BSTR(&var)));
VariantClear(&var);
hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root//test:c"), &list);
EXPECT_HR(hr, S_OK);
if (hr == S_OK)
expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
IXMLDOMDocument2_Release(doc);
ptr++;
}
free_bstrs();
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment