msxml3: Fix IXMLDOMDocument::getElementsByTagName() for some special cases.

This commit is contained in:
Nikolay Sivov 2010-09-02 00:29:18 +04:00 committed by Alexandre Julliard
parent 7f5e835c14
commit 1ce8be01f2
5 changed files with 53 additions and 20 deletions

View File

@ -1361,28 +1361,42 @@ static HRESULT WINAPI domdoc_getElementsByTagName(
BSTR tagName, BSTR tagName,
IXMLDOMNodeList** resultList ) IXMLDOMNodeList** resultList )
{ {
static const WCHAR xpathformat[] =
{ '/','/','*','[','l','o','c','a','l','-','n','a','m','e','(',')','=','\'','%','s','\'',']',0 };
domdoc *This = impl_from_IXMLDOMDocument3( iface ); domdoc *This = impl_from_IXMLDOMDocument3( iface );
LPWSTR szPattern;
HRESULT hr; HRESULT hr;
TRACE("(%p)->(%s %p)\n", This, debugstr_w(tagName), resultList); TRACE("(%p)->(%s %p)\n", This, debugstr_w(tagName), resultList);
if (!tagName || !resultList) return E_INVALIDARG;
if (tagName[0] == '*' && tagName[1] == 0) if (tagName[0] == '*' && tagName[1] == 0)
{ {
szPattern = heap_alloc(sizeof(WCHAR)*4); static const WCHAR formatallW[] = {'/','/','*',0};
szPattern[0] = szPattern[1] = '/'; hr = queryresult_create((xmlNodePtr)get_doc(This), formatallW, resultList);
szPattern[2] = '*';
szPattern[3] = 0;
} }
else else
{ {
szPattern = heap_alloc(sizeof(WCHAR)*(20+lstrlenW(tagName)+1)); static const WCHAR xpathformat[] =
wsprintfW(szPattern, xpathformat, tagName); { '/','/','*','[','l','o','c','a','l','-','n','a','m','e','(',')','=','\'' };
} static const WCHAR closeW[] = { '\'',']',0 };
hr = queryresult_create((xmlNodePtr)get_doc(This), szPattern, resultList); LPWSTR pattern;
heap_free(szPattern); WCHAR *ptr;
INT length;
length = lstrlenW(tagName);
/* without two WCHARs from format specifier */
ptr = pattern = heap_alloc(sizeof(xpathformat) + length*sizeof(WCHAR) + sizeof(closeW));
memcpy(ptr, xpathformat, sizeof(xpathformat));
ptr += sizeof(xpathformat)/sizeof(WCHAR);
memcpy(ptr, tagName, length*sizeof(WCHAR));
ptr += length;
memcpy(ptr, closeW, sizeof(closeW));
hr = queryresult_create((xmlNodePtr)get_doc(This), pattern, resultList);
heap_free(pattern);
}
return hr; return hr;
} }

View File

@ -122,13 +122,13 @@ extern IUnknown *create_doc_Implementation(void);
extern IUnknown *create_doc_fragment( xmlNodePtr fragment ); extern IUnknown *create_doc_fragment( xmlNodePtr fragment );
extern IUnknown *create_doc_entity_ref( xmlNodePtr entity ); extern IUnknown *create_doc_entity_ref( xmlNodePtr entity );
extern HRESULT queryresult_create( xmlNodePtr, LPWSTR, IXMLDOMNodeList ** ); extern HRESULT queryresult_create( xmlNodePtr, LPCWSTR, IXMLDOMNodeList ** );
/* data accessors */ /* data accessors */
xmlNodePtr xmlNodePtr_from_domnode( IXMLDOMNode *iface, xmlElementType type ); xmlNodePtr xmlNodePtr_from_domnode( IXMLDOMNode *iface, xmlElementType type );
/* helpers */ /* helpers */
extern xmlChar *xmlChar_from_wchar( LPWSTR str ); extern xmlChar *xmlChar_from_wchar( LPCWSTR str );
extern LONG xmldoc_add_ref( xmlDocPtr doc ); extern LONG xmldoc_add_ref( xmlDocPtr doc );
extern LONG xmldoc_release( xmlDocPtr doc ); extern LONG xmldoc_release( xmlDocPtr doc );

View File

@ -185,7 +185,7 @@ static HRESULT WINAPI xmlnodemap_Invoke(
return hr; return hr;
} }
xmlChar *xmlChar_from_wchar( LPWSTR str ) xmlChar *xmlChar_from_wchar( LPCWSTR str )
{ {
DWORD len; DWORD len;
xmlChar *xmlstr; xmlChar *xmlstr;

View File

@ -372,7 +372,7 @@ static dispex_static_data_t queryresult_dispex = {
queryresult_iface_tids queryresult_iface_tids
}; };
HRESULT queryresult_create(xmlNodePtr node, LPWSTR szQuery, IXMLDOMNodeList **out) HRESULT queryresult_create(xmlNodePtr node, LPCWSTR szQuery, IXMLDOMNodeList **out)
{ {
queryresult *This = heap_alloc_zero(sizeof(queryresult)); queryresult *This = heap_alloc_zero(sizeof(queryresult));
xmlXPathContextPtr ctxt = xmlXPathNewContext(node->doc); xmlXPathContextPtr ctxt = xmlXPathNewContext(node->doc);

View File

@ -2269,12 +2269,13 @@ static void test_create(void)
static void test_getElementsByTagName(void) static void test_getElementsByTagName(void)
{ {
HRESULT r;
BSTR str;
VARIANT_BOOL b;
IXMLDOMDocument *doc;
IXMLDOMNodeList *node_list; IXMLDOMNodeList *node_list;
IXMLDOMDocument *doc;
WCHAR buff[100];
VARIANT_BOOL b;
HRESULT r;
LONG len; LONG len;
BSTR str;
r = CoCreateInstance( &CLSID_DOMDocument, NULL, r = CoCreateInstance( &CLSID_DOMDocument, NULL,
CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc ); CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
@ -2289,6 +2290,13 @@ static void test_getElementsByTagName(void)
SysFreeString( str ); SysFreeString( str );
str = SysAllocString( szstar ); str = SysAllocString( szstar );
/* null arguments cases */
r = IXMLDOMDocument_getElementsByTagName(doc, NULL, &node_list);
ok( r == E_INVALIDARG, "ret %08x\n", r );
r = IXMLDOMDocument_getElementsByTagName(doc, str, NULL);
ok( r == E_INVALIDARG, "ret %08x\n", r );
r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list); r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
ok( r == S_OK, "ret %08x\n", r ); ok( r == S_OK, "ret %08x\n", r );
r = IXMLDOMNodeList_get_length( node_list, &len ); r = IXMLDOMNodeList_get_length( node_list, &len );
@ -2300,6 +2308,17 @@ static void test_getElementsByTagName(void)
IXMLDOMNodeList_Release( node_list ); IXMLDOMNodeList_Release( node_list );
SysFreeString( str ); SysFreeString( str );
/* broken query BSTR */
memcpy(&buff[2], szstar, sizeof(szstar));
/* just a big length */
*(DWORD*)buff = 0xf0f0;
r = IXMLDOMDocument_getElementsByTagName(doc, &buff[2], &node_list);
ok( r == S_OK, "ret %08x\n", r );
r = IXMLDOMNodeList_get_length( node_list, &len );
ok( r == S_OK, "ret %08x\n", r );
ok( len == 6, "len %d\n", len );
IXMLDOMNodeList_Release( node_list );
str = SysAllocString( szbs ); str = SysAllocString( szbs );
r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list); r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
ok( r == S_OK, "ret %08x\n", r ); ok( r == S_OK, "ret %08x\n", r );