msxml3: Skip leading space characters when loading from BSTR.

This commit is contained in:
Nikolay Sivov 2011-12-18 01:21:09 +03:00 committed by Alexandre Julliard
parent 6589516db1
commit e736c3e983
4 changed files with 114 additions and 47 deletions

View file

@ -78,7 +78,7 @@ static const WCHAR PropertyResolveExternalsW[] = {'R','e','s','o','l','v','e','E
* tests can go here (data shared between all instances).
* We need to preserve this when reloading a document,
* and also need access to it from the libxml backend. */
typedef struct _domdoc_properties {
typedef struct {
MSXML_VERSION version;
VARIANT_BOOL preserving;
IXMLDOMSchemaCollection2* schemaCache;
@ -285,7 +285,7 @@ static xmldoc_priv * create_priv(void)
return priv;
}
static domdoc_properties * create_properties(MSXML_VERSION version)
static domdoc_properties *create_properties(MSXML_VERSION version)
{
domdoc_properties *properties = heap_alloc(sizeof(domdoc_properties));
@ -2230,18 +2230,17 @@ static HRESULT WINAPI domdoc_abort(
return E_NOTIMPL;
}
/* don't rely on data to be in BSTR format, treat it as WCHAR string */
static HRESULT WINAPI domdoc_loadXML(
IXMLDOMDocument3 *iface,
BSTR bstrXML,
BSTR data,
VARIANT_BOOL* isSuccessful )
{
domdoc *This = impl_from_IXMLDOMDocument3( iface );
xmlDocPtr xmldoc = NULL;
HRESULT hr = S_FALSE, hr2;
TRACE("(%p)->(%s %p)\n", This, debugstr_w( bstrXML ), isSuccessful );
TRACE("(%p)->(%s %p)\n", This, debugstr_w(data), isSuccessful );
assert ( &This->node );
@ -2249,9 +2248,16 @@ static HRESULT WINAPI domdoc_loadXML(
{
*isSuccessful = VARIANT_FALSE;
if ( bstrXML )
if (data)
{
xmldoc = doparse(This, (LPCSTR)bstrXML, lstrlenW(bstrXML) * sizeof(*bstrXML), XML_CHAR_ENCODING_UTF16LE);
WCHAR *ptr = data;
/* skip leading spaces if needed */
if (This->properties->version == MSXML_DEFAULT || This->properties->version == MSXML26)
while (*ptr)
if (isspaceW(*ptr)) ptr++; else break;
xmldoc = doparse(This, (char*)ptr, strlenW(ptr)*sizeof(WCHAR), XML_CHAR_ENCODING_UTF16LE);
if ( !xmldoc )
{
This->error = E_FAIL;

View file

@ -59,24 +59,24 @@ struct clsid_version_t
static const struct clsid_version_t clsid_versions_table[] =
{
{ &CLSID_DOMDocument, MSXML_DEFAULT },
{ &CLSID_DOMDocument2, MSXML_DEFAULT },
{ &CLSID_DOMDocument26, MSXML_DEFAULT },
{ &CLSID_DOMDocument30, MSXML3 },
{ &CLSID_DOMDocument40, MSXML4 },
{ &CLSID_DOMDocument60, MSXML6 },
{ &CLSID_DOMDocument2, MSXML2 },
{ &CLSID_DOMDocument26, MSXML26 },
{ &CLSID_DOMDocument30, MSXML3 },
{ &CLSID_DOMDocument40, MSXML4 },
{ &CLSID_DOMDocument60, MSXML6 },
{ &CLSID_DOMFreeThreadedDocument, MSXML_DEFAULT },
{ &CLSID_FreeThreadedDOMDocument, MSXML_DEFAULT },
{ &CLSID_FreeThreadedDOMDocument26, MSXML_DEFAULT },
{ &CLSID_FreeThreadedDOMDocument30, MSXML3 },
{ &CLSID_FreeThreadedDOMDocument40, MSXML4 },
{ &CLSID_FreeThreadedDOMDocument60, MSXML6 },
{ &CLSID_FreeThreadedDOMDocument26, MSXML26 },
{ &CLSID_FreeThreadedDOMDocument30, MSXML3 },
{ &CLSID_FreeThreadedDOMDocument40, MSXML4 },
{ &CLSID_FreeThreadedDOMDocument60, MSXML6 },
{ &CLSID_XMLSchemaCache, MSXML_DEFAULT },
{ &CLSID_XMLSchemaCache26, MSXML_DEFAULT },
{ &CLSID_XMLSchemaCache30, MSXML3 },
{ &CLSID_XMLSchemaCache40, MSXML4 },
{ &CLSID_XMLSchemaCache60, MSXML6 },
{ &CLSID_XMLSchemaCache26, MSXML26 },
{ &CLSID_XMLSchemaCache30, MSXML3 },
{ &CLSID_XMLSchemaCache40, MSXML4 },
{ &CLSID_XMLSchemaCache60, MSXML6 },
{ &CLSID_MXXMLWriter, MSXML_DEFAULT },
{ &CLSID_MXXMLWriter30, MSXML3 },

View file

@ -31,9 +31,11 @@
typedef enum {
MSXML_DEFAULT = 0,
MSXML3 = 30,
MSXML4 = 40,
MSXML6 = 60
MSXML2 = 20,
MSXML26 = 26,
MSXML3 = 30,
MSXML4 = 40,
MSXML6 = 60
} MSXML_VERSION;
/* typelibs */

View file

@ -41,6 +41,9 @@
#include "wine/test.h"
/* undef the #define in msxml2 so that we can access all versions */
#undef CLSID_DOMDocument
DEFINE_GUID(SID_SContainerDispatch, 0xb722be00, 0x4e68, 0x101b, 0xa2, 0xbc, 0x00, 0xaa, 0x00, 0x40, 0x47, 0x70);
DEFINE_GUID(SID_UnknownSID, 0x75dd09cb, 0x6c40, 0x11d5, 0x85, 0x43, 0x00, 0xc0, 0x4f, 0xa0, 0xfb, 0xa3);
DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
@ -1737,15 +1740,6 @@ static const char xpath_simple_list[] =
" <d/>"
"</root>";
static const char* leading_spaces[] = {
"\n<?xml version=\"1.0\"?><root/>",
" <?xml version=\"1.0\"?><root/>",
"\t<?xml version=\"1.0\"?><root/>",
"\r\n<?xml version=\"1.0\"?><root/>",
"\r<?xml version=\"1.0\"?><root/>",
0
};
static const char default_ns_doc[] = {
"<?xml version=\"1.0\"?>"
"<a xmlns:ns=\"nshref\" xml:lang=\"ru\" ns:b=\"b attr\" xml:c=\"c attr\" "
@ -1834,7 +1828,7 @@ static void* _create_object(const GUID *clsid, const char *name, const IID *iid,
#define _create(cls) cls, #cls
#define create_document(iid) _create_object(&_create(CLSID_DOMDocument), iid, __LINE__)
#define create_document(iid) _create_object(&_create(CLSID_DOMDocument2), iid, __LINE__)
#define create_document_version(v, iid) _create_object(&_create(CLSID_DOMDocument ## v), iid, __LINE__)
#define create_cache(iid) _create_object(&_create(CLSID_XMLSchemaCache), iid, __LINE__)
#define create_cache_version(v, iid) _create_object(&_create(CLSID_XMLSchemaCache ## v), iid, __LINE__)
@ -2012,6 +2006,38 @@ static char *list_to_string(IXMLDOMNodeList *list)
#define expect_node(node, expstr) { char str[4096]; node_to_string(node, str); ok(strcmp(str, expstr)==0, "Invalid node: %s, expected %s\n", str, expstr); }
#define expect_list_and_release(list, expstr) { char *str = list_to_string(list); ok(strcmp(str, expstr)==0, "Invalid node list: %s, expected %s\n", str, expstr); if (list) IXMLDOMNodeList_Release(list); }
struct docload_ret_t {
VARIANT_BOOL b;
HRESULT hr;
};
struct leading_spaces_t {
const CLSID *clsid;
const char *name;
struct docload_ret_t ret[2]; /* 0 - ::load(), 1 - ::loadXML() */
};
static const struct leading_spaces_t leading_spaces_classdata[] = {
{ &CLSID_DOMDocument, "CLSID_DOMDocument", {{VARIANT_FALSE, S_FALSE }, {VARIANT_TRUE, S_OK } }},
{ &CLSID_DOMDocument2, "CLSID_DOMDocument2", {{VARIANT_FALSE, S_FALSE }, {VARIANT_FALSE, S_FALSE } }},
{ &CLSID_DOMDocument26, "CLSID_DOMDocument26", {{VARIANT_FALSE, S_FALSE }, {VARIANT_TRUE, S_OK } }},
{ &CLSID_DOMDocument30, "CLSID_DOMDocument30", {{VARIANT_FALSE, S_FALSE }, {VARIANT_FALSE, S_FALSE } }},
{ &CLSID_DOMDocument40, "CLSID_DOMDocument40", {{VARIANT_FALSE, S_FALSE }, {VARIANT_FALSE, S_FALSE } }},
{ &CLSID_DOMDocument60, "CLSID_DOMDocument60", {{VARIANT_FALSE, S_FALSE }, {VARIANT_FALSE, S_FALSE } }},
{ NULL }
};
static const char* leading_spaces_xmldata[] = {
"\n<?xml version=\"1.0\" encoding=\"UTF-16\" ?><root/>",
" <?xml version=\"1.0\"?><root/>",
"\n<?xml version=\"1.0\"?><root/>",
"\t<?xml version=\"1.0\"?><root/>",
"\r\n<?xml version=\"1.0\"?><root/>",
"\r<?xml version=\"1.0\"?><root/>",
"\r\r\r\r\t\t \n\n <?xml version=\"1.0\"?><root/>",
0
};
static void test_domdoc( void )
{
HRESULT r, hr;
@ -2024,13 +2050,59 @@ static void test_domdoc( void )
IXMLDOMAttribute *node_attr = NULL;
IXMLDOMNode *nodeChild = NULL;
IXMLDOMProcessingInstruction *nodePI = NULL;
const struct leading_spaces_t *class_ptr;
const char **data_ptr;
VARIANT_BOOL b;
VARIANT var;
BSTR str;
LONG code, ref;
LONG nLength = 0;
WCHAR buff[100];
const char **ptr;
int index;
/* Load document with leading spaces
*
* Test all CLSIDs with all test data XML strings
*/
class_ptr = leading_spaces_classdata;
index = 0;
while (class_ptr->clsid)
{
HRESULT hr;
int i;
hr = CoCreateInstance(class_ptr->clsid, NULL, CLSCTX_INPROC_SERVER,
&IID_IXMLDOMDocument, (void**)&doc);
if (hr != S_OK) {
win_skip("%d: failed to create class instance for %s\n", index, class_ptr->name);
class_ptr++;
index++;
continue;
}
data_ptr = leading_spaces_xmldata;
i = 0;
while (*data_ptr) {
BSTR data = _bstr_(*data_ptr);
b = 0xc;
V_VT(&var) = VT_BSTR;
V_BSTR(&var) = data;
hr = IXMLDOMDocument_load(doc, var, &b);
EXPECT_HR(hr, class_ptr->ret[0].hr);
ok(b == class_ptr->ret[0].b, "%d:%d, got %d, expected %d\n", index, i, b, class_ptr->ret[0].b);
b = 0xc;
hr = IXMLDOMDocument_loadXML(doc, data, &b);
EXPECT_HR(hr, class_ptr->ret[1].hr);
ok(b == class_ptr->ret[1].b, "%d:%d, got %d, expected %d\n", index, i, b, class_ptr->ret[1].b);
data_ptr++;
i++;
}
class_ptr++;
index++;
}
doc = create_document(&IID_IXMLDOMDocument);
if (!doc) return;
@ -2050,19 +2122,6 @@ if (0)
EXPECT_HR(hr, S_FALSE);
ok( b == VARIANT_FALSE, "failed to load XML string\n");
/* load document with leading spaces */
ptr = leading_spaces;
while (*ptr)
{
b = VARIANT_TRUE;
V_VT(&var) = VT_BSTR;
V_BSTR(&var) = _bstr_(*ptr);
hr = IXMLDOMDocument_load( doc, var, &b);
EXPECT_HR(hr, S_FALSE);
ok( b == VARIANT_FALSE, "got %x\n", b);
ptr++;
}
/* try to load a document from a nonexistent file */
b = VARIANT_TRUE;
str = SysAllocString( nonexistent_fileW );