msxml3: Respect 'namespaces' feature calling content handler callbacks.
This commit is contained in:
parent
137a21d04c
commit
f27159a59f
|
@ -302,6 +302,11 @@ static inline HRESULT get_feature_value(const saxreader *reader, saxreader_featu
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static BOOL is_namespaces_enabled(const saxreader *reader)
|
||||
{
|
||||
return (reader->version < MSXML4) || (reader->features & Namespaces);
|
||||
}
|
||||
|
||||
static inline BOOL has_content_handler(const saxlocator *locator)
|
||||
{
|
||||
return (locator->vbInterface && locator->saxreader->vbcontentHandler) ||
|
||||
|
@ -1286,42 +1291,53 @@ static void libxmlStartElementNS(
|
|||
if (has_content_handler(This))
|
||||
{
|
||||
BSTR uri;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nb_namespaces; i++)
|
||||
if (is_namespaces_enabled(This->saxreader))
|
||||
{
|
||||
if(This->vbInterface)
|
||||
hr = IVBSAXContentHandler_startPrefixMapping(
|
||||
This->saxreader->vbcontentHandler,
|
||||
&element->ns[i].prefix,
|
||||
&element->ns[i].uri);
|
||||
else
|
||||
hr = ISAXContentHandler_startPrefixMapping(
|
||||
This->saxreader->contentHandler,
|
||||
element->ns[i].prefix,
|
||||
SysStringLen(element->ns[i].prefix),
|
||||
element->ns[i].uri,
|
||||
SysStringLen(element->ns[i].uri));
|
||||
int i;
|
||||
|
||||
if (sax_callback_failed(This, hr))
|
||||
for (i = 0; i < nb_namespaces; i++)
|
||||
{
|
||||
format_error_message_from_id(This, hr);
|
||||
return;
|
||||
if (This->vbInterface)
|
||||
hr = IVBSAXContentHandler_startPrefixMapping(
|
||||
This->saxreader->vbcontentHandler,
|
||||
&element->ns[i].prefix,
|
||||
&element->ns[i].uri);
|
||||
else
|
||||
hr = ISAXContentHandler_startPrefixMapping(
|
||||
This->saxreader->contentHandler,
|
||||
element->ns[i].prefix,
|
||||
SysStringLen(element->ns[i].prefix),
|
||||
element->ns[i].uri,
|
||||
SysStringLen(element->ns[i].uri));
|
||||
|
||||
if (sax_callback_failed(This, hr))
|
||||
{
|
||||
format_error_message_from_id(This, hr);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uri = find_element_uri(This, URI);
|
||||
|
||||
hr = SAXAttributes_populate(This, nb_namespaces, namespaces, nb_attributes, attributes);
|
||||
if(hr == S_OK)
|
||||
if (hr == S_OK)
|
||||
{
|
||||
if(This->vbInterface)
|
||||
BSTR local;
|
||||
|
||||
if (is_namespaces_enabled(This->saxreader))
|
||||
local = element->local;
|
||||
else
|
||||
uri = local = NULL;
|
||||
|
||||
if (This->vbInterface)
|
||||
hr = IVBSAXContentHandler_startElement(This->saxreader->vbcontentHandler,
|
||||
&uri, &element->local, &element->qname, &This->IVBSAXAttributes_iface);
|
||||
&uri, &local, &element->qname, &This->IVBSAXAttributes_iface);
|
||||
else
|
||||
hr = ISAXContentHandler_startElement(This->saxreader->contentHandler,
|
||||
uri, SysStringLen(uri),
|
||||
element->local, SysStringLen(element->local),
|
||||
local, SysStringLen(local),
|
||||
element->qname, SysStringLen(element->qname),
|
||||
&This->ISAXAttributes_iface);
|
||||
}
|
||||
|
@ -1340,9 +1356,8 @@ static void libxmlEndElementNS(
|
|||
saxlocator *This = ctx;
|
||||
element_entry *element;
|
||||
const xmlChar *p;
|
||||
BSTR uri, local;
|
||||
HRESULT hr;
|
||||
BSTR uri;
|
||||
int i;
|
||||
|
||||
update_position(This, FALSE);
|
||||
p = This->pParserCtxt->input->cur;
|
||||
|
@ -1382,15 +1397,20 @@ static void libxmlEndElementNS(
|
|||
return;
|
||||
}
|
||||
|
||||
if(This->vbInterface)
|
||||
if (is_namespaces_enabled(This->saxreader))
|
||||
local = element->local;
|
||||
else
|
||||
uri = local = NULL;
|
||||
|
||||
if (This->vbInterface)
|
||||
hr = IVBSAXContentHandler_endElement(
|
||||
This->saxreader->vbcontentHandler,
|
||||
&uri, &element->local, &element->qname);
|
||||
&uri, &local, &element->qname);
|
||||
else
|
||||
hr = ISAXContentHandler_endElement(
|
||||
This->saxreader->contentHandler,
|
||||
uri, SysStringLen(uri),
|
||||
element->local, SysStringLen(element->local),
|
||||
local, SysStringLen(local),
|
||||
element->qname, SysStringLen(element->qname));
|
||||
|
||||
This->nb_attributes = 0;
|
||||
|
@ -1402,18 +1422,21 @@ static void libxmlEndElementNS(
|
|||
return;
|
||||
}
|
||||
|
||||
i = -1;
|
||||
while (iterate_endprefix_index(This, element, &i))
|
||||
if (is_namespaces_enabled(This->saxreader))
|
||||
{
|
||||
if(This->vbInterface)
|
||||
hr = IVBSAXContentHandler_endPrefixMapping(
|
||||
This->saxreader->vbcontentHandler, &element->ns[i].prefix);
|
||||
else
|
||||
hr = ISAXContentHandler_endPrefixMapping(
|
||||
This->saxreader->contentHandler,
|
||||
element->ns[i].prefix, SysStringLen(element->ns[i].prefix));
|
||||
int i = -1;
|
||||
while (iterate_endprefix_index(This, element, &i))
|
||||
{
|
||||
if (This->vbInterface)
|
||||
hr = IVBSAXContentHandler_endPrefixMapping(
|
||||
This->saxreader->vbcontentHandler, &element->ns[i].prefix);
|
||||
else
|
||||
hr = ISAXContentHandler_endPrefixMapping(
|
||||
This->saxreader->contentHandler,
|
||||
element->ns[i].prefix, SysStringLen(element->ns[i].prefix));
|
||||
|
||||
if (sax_callback_failed(This, hr)) break;
|
||||
if (sax_callback_failed(This, hr)) break;
|
||||
}
|
||||
}
|
||||
|
||||
if (sax_callback_failed(This, hr))
|
||||
|
@ -2820,7 +2843,7 @@ static HRESULT WINAPI saxxmlreader_putFeature(
|
|||
/* accepted cases */
|
||||
if ((feature == ExternalGeneralEntities && value == VARIANT_FALSE) ||
|
||||
(feature == ExternalParameterEntities && value == VARIANT_FALSE) ||
|
||||
(feature == Namespaces && value == VARIANT_TRUE ))
|
||||
feature == Namespaces)
|
||||
{
|
||||
return set_feature_value(This, feature, value);
|
||||
}
|
||||
|
|
|
@ -554,7 +554,7 @@ static const CHAR testXML[] =
|
|||
" <Name>Captain Ahab</Name>\n"
|
||||
"</BankAccount>\n";
|
||||
|
||||
static const CHAR szTestAttributes[] =
|
||||
static const char test_attributes[] =
|
||||
"<?xml version=\"1.0\" ?>\n"
|
||||
"<document xmlns:test=\"prefix_test\" xmlns=\"prefix\" test:arg1=\"arg1\" arg2=\"arg2\" test:ar3=\"arg3\">\n"
|
||||
"<node1 xmlns:p=\"test\" />"
|
||||
|
@ -733,6 +733,28 @@ static struct call_entry content_handler_test_attributes_alternate_4[] = {
|
|||
{ CH_ENDTEST }
|
||||
};
|
||||
|
||||
/* 'namespace' feature switched off */
|
||||
static struct attribute_entry ch_attributes_alt_no_ns[] = {
|
||||
{ "", "", "xmlns:test", "prefix_test" },
|
||||
{ "", "", "xmlns", "prefix" },
|
||||
{ "", "", "test:arg1", "arg1" },
|
||||
{ "", "", "arg2", "arg2" },
|
||||
{ "", "", "test:ar3", "arg3" },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static struct call_entry content_handler_test_attributes_alt_no_ns[] = {
|
||||
{ CH_PUTDOCUMENTLOCATOR, 1, 0, S_OK },
|
||||
{ CH_STARTDOCUMENT, 1, 22, S_OK },
|
||||
{ CH_STARTELEMENT, 2, 95, S_OK, "", "", "document", ch_attributes_alt_no_ns },
|
||||
{ CH_CHARACTERS, 3, 1, S_OK, "\n" },
|
||||
{ CH_STARTELEMENT, 3, 24, S_OK, "", "", "node1", ch_attributes2 },
|
||||
{ CH_ENDELEMENT, 3, 24, S_OK, "", "", "node1" },
|
||||
{ CH_ENDELEMENT, 3, 35, S_OK, "", "", "document" },
|
||||
{ CH_ENDDOCUMENT, 4, 0, S_OK },
|
||||
{ CH_ENDTEST }
|
||||
};
|
||||
|
||||
static struct attribute_entry ch_attributes_alt_6[] = {
|
||||
{ "prefix_test", "arg1", "test:arg1", "arg1" },
|
||||
{ "", "arg2", "arg2", "arg2" },
|
||||
|
@ -796,6 +818,7 @@ static const char xmlspace_attr[] =
|
|||
|
||||
static struct call_entry *expectCall;
|
||||
static ISAXLocator *locator;
|
||||
static ISAXXMLReader *g_reader;
|
||||
int msxml_version;
|
||||
|
||||
static void set_expected_seq(struct call_entry *expected)
|
||||
|
@ -968,11 +991,16 @@ static HRESULT WINAPI contentHandler_startElement(
|
|||
|
||||
if (len)
|
||||
{
|
||||
VARIANT_BOOL v;
|
||||
int i;
|
||||
|
||||
struct attribute_entry *attr;
|
||||
attr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len*sizeof(struct attribute_entry));
|
||||
|
||||
v = VARIANT_TRUE;
|
||||
hr = ISAXXMLReader_getFeature(g_reader, _bstr_("http://xml.org/sax/features/namespaces"), &v);
|
||||
EXPECT_HR(hr, S_OK);
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
const WCHAR *value;
|
||||
|
@ -985,8 +1013,18 @@ static HRESULT WINAPI contentHandler_startElement(
|
|||
hr = ISAXAttributes_getValue(saxattr, i, &value, &value_len);
|
||||
EXPECT_HR(hr, S_OK);
|
||||
|
||||
attr[i].uriW = SysAllocStringLen(uri, uri_len);
|
||||
attr[i].localW = SysAllocStringLen(localname, local_len);
|
||||
/* if 'namespaces' switched off uri and local name contains garbage */
|
||||
if (v == VARIANT_FALSE && msxml_version > 0)
|
||||
{
|
||||
attr[i].uriW = SysAllocStringLen(NULL, 0);
|
||||
attr[i].localW = SysAllocStringLen(NULL, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
attr[i].uriW = SysAllocStringLen(uri, uri_len);
|
||||
attr[i].localW = SysAllocStringLen(localname, local_len);
|
||||
}
|
||||
|
||||
attr[i].qnameW = SysAllocStringLen(qname, qname_len);
|
||||
attr[i].valueW = SysAllocStringLen(value, value_len);
|
||||
}
|
||||
|
@ -1720,8 +1758,8 @@ static void test_saxreader(void)
|
|||
SAFEARRAYBOUND SADim[1];
|
||||
char *ptr = NULL;
|
||||
IStream *stream;
|
||||
ULARGE_INTEGER liSize;
|
||||
LARGE_INTEGER liPos;
|
||||
ULARGE_INTEGER size;
|
||||
LARGE_INTEGER pos;
|
||||
ULONG written;
|
||||
HANDLE file;
|
||||
static const CHAR testXmlA[] = "test.xml";
|
||||
|
@ -1742,8 +1780,14 @@ static void test_saxreader(void)
|
|||
|
||||
hr = CoCreateInstance(table->clsid, NULL, CLSCTX_INPROC_SERVER, &IID_ISAXXMLReader, (void**)&reader);
|
||||
EXPECT_HR(hr, S_OK);
|
||||
g_reader = reader;
|
||||
|
||||
msxml_version = IsEqualGUID(table->clsid, &CLSID_SAXXMLReader60) ? 6 : 0;
|
||||
if (IsEqualGUID(table->clsid, &CLSID_SAXXMLReader40))
|
||||
msxml_version = 4;
|
||||
else if (IsEqualGUID(table->clsid, &CLSID_SAXXMLReader60))
|
||||
msxml_version = 6;
|
||||
else
|
||||
msxml_version = 0;
|
||||
|
||||
/* crashes on old versions */
|
||||
if (!IsEqualGUID(table->clsid, &CLSID_SAXXMLReader40) &&
|
||||
|
@ -1809,11 +1853,11 @@ static void test_saxreader(void)
|
|||
SafeArrayDestroy(sa);
|
||||
|
||||
CreateStreamOnHGlobal(NULL, TRUE, &stream);
|
||||
liSize.QuadPart = strlen(testXML);
|
||||
IStream_SetSize(stream, liSize);
|
||||
size.QuadPart = strlen(testXML);
|
||||
IStream_SetSize(stream, size);
|
||||
IStream_Write(stream, testXML, strlen(testXML), &written);
|
||||
liPos.QuadPart = 0;
|
||||
IStream_Seek(stream, liPos, STREAM_SEEK_SET, NULL);
|
||||
pos.QuadPart = 0;
|
||||
IStream_Seek(stream, pos, STREAM_SEEK_SET, NULL);
|
||||
V_VT(&var) = VT_UNKNOWN|VT_DISPATCH;
|
||||
V_UNKNOWN(&var) = (IUnknown*)stream;
|
||||
|
||||
|
@ -1825,11 +1869,11 @@ static void test_saxreader(void)
|
|||
IStream_Release(stream);
|
||||
|
||||
CreateStreamOnHGlobal(NULL, TRUE, &stream);
|
||||
liSize.QuadPart = strlen(szTestAttributes);
|
||||
IStream_SetSize(stream, liSize);
|
||||
IStream_Write(stream, szTestAttributes, strlen(szTestAttributes), &written);
|
||||
liPos.QuadPart = 0;
|
||||
IStream_Seek(stream, liPos, STREAM_SEEK_SET, NULL);
|
||||
size.QuadPart = strlen(test_attributes);
|
||||
IStream_SetSize(stream, size);
|
||||
IStream_Write(stream, test_attributes, strlen(test_attributes), &written);
|
||||
pos.QuadPart = 0;
|
||||
IStream_Seek(stream, pos, STREAM_SEEK_SET, NULL);
|
||||
V_VT(&var) = VT_UNKNOWN|VT_DISPATCH;
|
||||
V_UNKNOWN(&var) = (IUnknown*)stream;
|
||||
|
||||
|
@ -1962,6 +2006,32 @@ static void test_saxreader(void)
|
|||
else
|
||||
ok_sequence(sequences, CONTENT_HANDLER_INDEX, test_seq, "xml:space handling", FALSE);
|
||||
|
||||
/* switch off 'namespaces' feature */
|
||||
hr = ISAXXMLReader_putFeature(reader, _bstr_("http://xml.org/sax/features/namespaces"), VARIANT_FALSE);
|
||||
EXPECT_HR(hr, S_OK);
|
||||
|
||||
CreateStreamOnHGlobal(NULL, TRUE, &stream);
|
||||
size.QuadPart = strlen(test_attributes);
|
||||
IStream_SetSize(stream, size);
|
||||
IStream_Write(stream, test_attributes, strlen(test_attributes), &written);
|
||||
pos.QuadPart = 0;
|
||||
IStream_Seek(stream, pos, STREAM_SEEK_SET, NULL);
|
||||
V_VT(&var) = VT_UNKNOWN|VT_DISPATCH;
|
||||
V_UNKNOWN(&var) = (IUnknown*)stream;
|
||||
|
||||
if (IsEqualGUID(table->clsid, &CLSID_SAXXMLReader40) ||
|
||||
IsEqualGUID(table->clsid, &CLSID_SAXXMLReader60))
|
||||
{
|
||||
test_seq = content_handler_test_attributes_alt_no_ns;
|
||||
}
|
||||
else
|
||||
test_seq = content_handler_test_attributes;
|
||||
|
||||
set_expected_seq(test_seq);
|
||||
hr = ISAXXMLReader_parse(reader, var);
|
||||
EXPECT_HR(hr, S_OK);
|
||||
ok_sequence(sequences, CONTENT_HANDLER_INDEX, test_seq, "content test attributes", TRUE);
|
||||
|
||||
ISAXXMLReader_Release(reader);
|
||||
table++;
|
||||
}
|
||||
|
@ -2078,16 +2148,22 @@ struct feature_ns_entry_t {
|
|||
const GUID *guid;
|
||||
const char *clsid;
|
||||
VARIANT_BOOL value;
|
||||
VARIANT_BOOL value2; /* feature value after feature set to 0xc */
|
||||
};
|
||||
|
||||
static const struct feature_ns_entry_t feature_ns_entry_data[] = {
|
||||
{ &CLSID_SAXXMLReader, "CLSID_SAXXMLReader", VARIANT_TRUE },
|
||||
{ &CLSID_SAXXMLReader30, "CLSID_SAXXMLReader30", VARIANT_TRUE },
|
||||
{ &CLSID_SAXXMLReader40, "CLSID_SAXXMLReader40", VARIANT_TRUE },
|
||||
{ &CLSID_SAXXMLReader60, "CLSID_SAXXMLReader60", VARIANT_TRUE },
|
||||
{ &CLSID_SAXXMLReader, "CLSID_SAXXMLReader", VARIANT_TRUE, VARIANT_FALSE },
|
||||
{ &CLSID_SAXXMLReader30, "CLSID_SAXXMLReader30", VARIANT_TRUE, VARIANT_FALSE },
|
||||
{ &CLSID_SAXXMLReader40, "CLSID_SAXXMLReader40", VARIANT_TRUE, VARIANT_TRUE },
|
||||
{ &CLSID_SAXXMLReader60, "CLSID_SAXXMLReader60", VARIANT_TRUE, VARIANT_TRUE },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const char *feature_names[] = {
|
||||
"http://xml.org/sax/features/namespaces",
|
||||
0
|
||||
};
|
||||
|
||||
static void test_saxreader_features(void)
|
||||
{
|
||||
const struct feature_ns_entry_t *entry = feature_ns_entry_data;
|
||||
|
@ -2096,6 +2172,7 @@ static void test_saxreader_features(void)
|
|||
while (entry->guid)
|
||||
{
|
||||
VARIANT_BOOL value;
|
||||
const char **name;
|
||||
HRESULT hr;
|
||||
|
||||
hr = CoCreateInstance(entry->guid, NULL, CLSCTX_INPROC_SERVER, &IID_ISAXXMLReader, (void**)&reader);
|
||||
|
@ -2106,15 +2183,44 @@ static void test_saxreader_features(void)
|
|||
continue;
|
||||
}
|
||||
|
||||
value = 0xc;
|
||||
hr = ISAXXMLReader_getFeature(reader, _bstr_("http://xml.org/sax/features/namespaces"), &value);
|
||||
EXPECT_HR(hr, S_OK);
|
||||
ok(entry->value == value, "%s: got wrong default value %x, expected %x\n", entry->clsid, value, entry->value);
|
||||
name = feature_names;
|
||||
while (*name)
|
||||
{
|
||||
value = 0xc;
|
||||
hr = ISAXXMLReader_getFeature(reader, _bstr_(*name), &value);
|
||||
EXPECT_HR(hr, S_OK);
|
||||
ok(entry->value == value, "%s: got wrong default value %x, expected %x\n", entry->clsid, value, entry->value);
|
||||
|
||||
value = 0xc;
|
||||
hr = ISAXXMLReader_getFeature(reader, _bstr_("http://xml.org/sax/features/namespace-prefixes"), &value);
|
||||
EXPECT_HR(hr, S_OK);
|
||||
ok(entry->value == value, "%s: got wrong default value %x, expected %x\n", entry->clsid, value, entry->value);
|
||||
value = 0xc;
|
||||
hr = ISAXXMLReader_putFeature(reader, _bstr_(*name), value);
|
||||
EXPECT_HR(hr, S_OK);
|
||||
|
||||
value = 0xd;
|
||||
hr = ISAXXMLReader_getFeature(reader, _bstr_(*name), &value);
|
||||
EXPECT_HR(hr, S_OK);
|
||||
if (IsEqualGUID(entry->guid, &CLSID_SAXXMLReader40) ||
|
||||
IsEqualGUID(entry->guid, &CLSID_SAXXMLReader60))
|
||||
todo_wine
|
||||
ok(entry->value2 == value, "%s: got wrong value %x, expected %x\n", entry->clsid, value, entry->value2);
|
||||
else
|
||||
ok(entry->value2 == value, "%s: got wrong value %x, expected %x\n", entry->clsid, value, entry->value2);
|
||||
|
||||
hr = ISAXXMLReader_putFeature(reader, _bstr_(*name), VARIANT_FALSE);
|
||||
EXPECT_HR(hr, S_OK);
|
||||
value = 0xd;
|
||||
hr = ISAXXMLReader_getFeature(reader, _bstr_(*name), &value);
|
||||
EXPECT_HR(hr, S_OK);
|
||||
ok(value == VARIANT_FALSE, "%s: got wrong value %x, expected VARIANT_FALSE\n", entry->clsid, value);
|
||||
|
||||
hr = ISAXXMLReader_putFeature(reader, _bstr_(*name), VARIANT_TRUE);
|
||||
EXPECT_HR(hr, S_OK);
|
||||
value = 0xd;
|
||||
hr = ISAXXMLReader_getFeature(reader, _bstr_(*name), &value);
|
||||
EXPECT_HR(hr, S_OK);
|
||||
ok(value == VARIANT_TRUE, "%s: got wrong value %x, expected VARIANT_TRUE\n", entry->clsid, value);
|
||||
|
||||
name++;
|
||||
}
|
||||
|
||||
ISAXXMLReader_Release(reader);
|
||||
|
||||
|
|
Loading…
Reference in New Issue