[PATCH 1/1] Fix IXMLDOMDocument::getElementsByTagName() for some special cases

Nikolay Sivov nsivov at codeweavers.com
Wed Sep 1 15:29:18 CDT 2010


---
 dlls/msxml3/domdoc.c        |   38 ++++++++++++++++++++++++++------------
 dlls/msxml3/msxml_private.h |    4 ++--
 dlls/msxml3/nodemap.c       |    2 +-
 dlls/msxml3/queryresult.c   |    2 +-
 dlls/msxml3/tests/domdoc.c  |   27 +++++++++++++++++++++++----
 5 files changed, 53 insertions(+), 20 deletions(-)

diff --git a/dlls/msxml3/domdoc.c b/dlls/msxml3/domdoc.c
index 12672a5..9a50366 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 };
+
+        LPWSTR pattern;
+        WCHAR *ptr;
+        INT length;
 
-    hr = queryresult_create((xmlNodePtr)get_doc(This), szPattern, resultList);
-    heap_free(szPattern);
+        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 00957c0..2210574 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 4b7b233..3f2ee47 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 ef337a6..33a2f41 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 7104afb..7a7f4cd 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 );
-- 
1.5.6.5


--------------080900060602070307020303--



More information about the wine-patches mailing list