diff --git a/dlls/msxml3/domdoc.c b/dlls/msxml3/domdoc.c index 12672a52a31..9a5036680fb 100644 --- a/dlls/msxml3/domdoc.c +++ b/dlls/msxml3/domdoc.c @@ -1361,28 +1361,42 @@ static HRESULT WINAPI domdoc_getElementsByTagName( BSTR tagName, IXMLDOMNodeList** resultList ) { - static const WCHAR xpathformat[] = - { '/','/','*','[','l','o','c','a','l','-','n','a','m','e','(',')','=','\'','%','s','\'',']',0 }; domdoc *This = impl_from_IXMLDOMDocument3( iface ); - LPWSTR szPattern; HRESULT hr; + TRACE("(%p)->(%s %p)\n", This, debugstr_w(tagName), resultList); + if (!tagName || !resultList) return E_INVALIDARG; + if (tagName[0] == '*' && tagName[1] == 0) { - szPattern = heap_alloc(sizeof(WCHAR)*4); - szPattern[0] = szPattern[1] = '/'; - szPattern[2] = '*'; - szPattern[3] = 0; + static const WCHAR formatallW[] = {'/','/','*',0}; + hr = queryresult_create((xmlNodePtr)get_doc(This), formatallW, resultList); } else { - szPattern = heap_alloc(sizeof(WCHAR)*(20+lstrlenW(tagName)+1)); - wsprintfW(szPattern, xpathformat, tagName); - } + static const WCHAR xpathformat[] = + { '/','/','*','[','l','o','c','a','l','-','n','a','m','e','(',')','=','\'' }; + static const WCHAR closeW[] = { '\'',']',0 }; - hr = queryresult_create((xmlNodePtr)get_doc(This), szPattern, resultList); - heap_free(szPattern); + LPWSTR pattern; + 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; } diff --git a/dlls/msxml3/msxml_private.h b/dlls/msxml3/msxml_private.h index 00957c08666..2210574812e 100644 --- a/dlls/msxml3/msxml_private.h +++ b/dlls/msxml3/msxml_private.h @@ -122,13 +122,13 @@ extern IUnknown *create_doc_Implementation(void); extern IUnknown *create_doc_fragment( xmlNodePtr fragment ); extern IUnknown *create_doc_entity_ref( xmlNodePtr entity ); -extern HRESULT queryresult_create( xmlNodePtr, LPWSTR, IXMLDOMNodeList ** ); +extern HRESULT queryresult_create( xmlNodePtr, LPCWSTR, IXMLDOMNodeList ** ); /* data accessors */ xmlNodePtr xmlNodePtr_from_domnode( IXMLDOMNode *iface, xmlElementType type ); /* 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_release( xmlDocPtr doc ); diff --git a/dlls/msxml3/nodemap.c b/dlls/msxml3/nodemap.c index 4b7b233b462..3f2ee47f241 100644 --- a/dlls/msxml3/nodemap.c +++ b/dlls/msxml3/nodemap.c @@ -185,7 +185,7 @@ static HRESULT WINAPI xmlnodemap_Invoke( return hr; } -xmlChar *xmlChar_from_wchar( LPWSTR str ) +xmlChar *xmlChar_from_wchar( LPCWSTR str ) { DWORD len; xmlChar *xmlstr; diff --git a/dlls/msxml3/queryresult.c b/dlls/msxml3/queryresult.c index ef337a614ba..33a2f41e7a7 100644 --- a/dlls/msxml3/queryresult.c +++ b/dlls/msxml3/queryresult.c @@ -372,7 +372,7 @@ static dispex_static_data_t queryresult_dispex = { 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)); xmlXPathContextPtr ctxt = xmlXPathNewContext(node->doc); diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c index 7104afb28ee..7a7f4cd2f60 100644 --- a/dlls/msxml3/tests/domdoc.c +++ b/dlls/msxml3/tests/domdoc.c @@ -2269,12 +2269,13 @@ static void test_create(void) static void test_getElementsByTagName(void) { - HRESULT r; - BSTR str; - VARIANT_BOOL b; - IXMLDOMDocument *doc; IXMLDOMNodeList *node_list; + IXMLDOMDocument *doc; + WCHAR buff[100]; + VARIANT_BOOL b; + HRESULT r; LONG len; + BSTR str; r = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc ); @@ -2289,6 +2290,13 @@ static void test_getElementsByTagName(void) SysFreeString( str ); 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); ok( r == S_OK, "ret %08x\n", r ); r = IXMLDOMNodeList_get_length( node_list, &len ); @@ -2300,6 +2308,17 @@ static void test_getElementsByTagName(void) IXMLDOMNodeList_Release( node_list ); 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 ); r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list); ok( r == S_OK, "ret %08x\n", r );