mshtml: Handle cNames > 1 in GetIDsOfNames properly.

Native ignores any cNames > 1 and doesn't even fill the dispids for them. Note
that it was already wrong; the multiple dispids are supposed to correspond
to the member's argument names, not extra dispids.

Signed-off-by: Gabriel Ivăncescu <gabrielopcode@gmail.com>
This commit is contained in:
Gabriel Ivăncescu 2022-11-14 19:53:27 +02:00 committed by Alexandre Julliard
parent 7001705c86
commit cc0f443088
4 changed files with 142 additions and 15 deletions

View file

@ -1636,19 +1636,16 @@ static HRESULT WINAPI DispatchEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid,
LCID lcid, DISPID *rgDispId)
{
DispatchEx *This = impl_from_IDispatchEx(iface);
UINT i;
HRESULT hres;
HRESULT hres = S_OK;
TRACE("(%p)->(%s %p %u %lu %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
lcid, rgDispId);
for(i=0; i < cNames; i++) {
hres = IDispatchEx_GetDispID(&This->IDispatchEx_iface, rgszNames[i], 0, rgDispId+i);
if(FAILED(hres))
return hres;
}
/* Native ignores all cNames > 1, and doesn't even fill them */
if(cNames)
hres = IDispatchEx_GetDispID(&This->IDispatchEx_iface, rgszNames[0], 0, rgDispId);
return S_OK;
return hres;
}
static HRESULT WINAPI DispatchEx_Invoke(IDispatchEx *iface, DISPID dispIdMember,

View file

@ -3476,19 +3476,17 @@ static HRESULT WINAPI WindowDispEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid
LCID lcid, DISPID *rgDispId)
{
HTMLWindow *This = impl_from_IDispatchEx(iface);
UINT i;
HRESULT hres;
HRESULT hres = S_OK;
WARN("(%p)->(%s %p %u %lu %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);
for(i=0; i < cNames; i++) {
/* Native ignores all cNames > 1, and doesn't even fill them */
if(cNames) {
/* We shouldn't use script's IDispatchEx here, so we shouldn't use GetDispID */
hres = IDispatchEx_GetDispID(&This->IDispatchEx_iface, rgszNames[i], 0, rgDispId+i);
if(FAILED(hres))
return hres;
hres = IDispatchEx_GetDispID(&This->IDispatchEx_iface, rgszNames[0], 0, rgDispId);
}
return S_OK;
return hres;
}
static HRESULT WINAPI WindowDispEx_Invoke(IDispatchEx *iface, DISPID dispIdMember,

View file

@ -27,6 +27,7 @@
#include "ole2.h"
#include "mshtml.h"
#include "mshtmcid.h"
#include "mshtmdid.h"
#include "mshtmhst.h"
#include "docobj.h"
#include "hlink.h"
@ -5288,6 +5289,98 @@ static void _test_doc_set_title(unsigned line, IHTMLDocument2 *doc, const WCHAR
SysFreeString(tmp);
}
static void test_doc_GetIDsOfNames(IHTMLDocument2 *doc)
{
DISPID dispids[3];
HRESULT hres;
BSTR bstr[3];
bstr[0] = SysAllocString(L"createStyleSheet");
bstr[1] = SysAllocString(L"bstrHref");
bstr[2] = SysAllocString(L"lIndex");
dispids[0] = 0;
dispids[1] = 0xdead;
dispids[2] = 0xbeef;
hres = IHTMLDocument2_GetIDsOfNames(doc, &IID_NULL, bstr, 3, 0, dispids);
ok(hres == S_OK, "GetIDsOfNames failed: %08lx\n", hres);
ok(dispids[0] == DISPID_IHTMLDOCUMENT2_CREATESTYLESHEET, "createStyleSheet dispid = %ld\n", dispids[0]);
ok(dispids[1] == 0xdead, "bstrHref dispid = %ld\n", dispids[1]);
ok(dispids[2] == 0xbeef, "lIndex dispid = %ld\n", dispids[2]);
SysFreeString(bstr[2]);
SysFreeString(bstr[1]);
SysFreeString(bstr[0]);
}
static void test_window_GetIDsOfNames(IHTMLWindow2 *window)
{
DISPID dispids[3];
HRESULT hres;
BSTR bstr[3];
bstr[0] = SysAllocString(L"showHelp");
bstr[1] = SysAllocString(L"helpURL");
bstr[2] = SysAllocString(L"helpArg");
dispids[0] = 0;
dispids[1] = 0xdead;
dispids[2] = 0xbeef;
hres = IHTMLWindow2_GetIDsOfNames(window, &IID_NULL, bstr, 3, 0, dispids);
ok(hres == S_OK, "GetIDsOfNames failed: %08lx\n", hres);
ok(dispids[0] == DISPID_IHTMLWINDOW2_SHOWHELP, "showHelp dispid = %ld\n", dispids[0]);
ok(dispids[1] == 0xdead, "helpURL dispid = %ld\n", dispids[1]);
ok(dispids[2] == 0xbeef, "helpArg dispid = %ld\n", dispids[2]);
SysFreeString(bstr[2]);
SysFreeString(bstr[1]);
SysFreeString(bstr[0]);
}
static void test_elem_GetIDsOfNames(IHTMLElement *elem)
{
DISPID dispids[3];
HRESULT hres;
BSTR bstr[3];
/* IE9+ use something like js proxies even on native and have different dispids */
if(compat_mode >= COMPAT_IE9)
return;
bstr[0] = SysAllocString(L"insertAdjacentText");
bstr[1] = SysAllocString(L"where");
bstr[2] = SysAllocString(L"text");
dispids[0] = 0;
dispids[1] = 0xdead;
dispids[2] = 0xbeef;
hres = IHTMLElement_GetIDsOfNames(elem, &IID_NULL, bstr, 3, 0, dispids);
ok(hres == S_OK, "GetIDsOfNames failed: %08lx\n", hres);
ok(dispids[0] == DISPID_IHTMLELEMENT_INSERTADJACENTTEXT, "insertAdjacentText dispid = %ld\n", dispids[0]);
ok(dispids[1] == 0xdead, "where dispid = %ld\n", dispids[1]);
ok(dispids[2] == 0xbeef, "text dispid = %ld\n", dispids[2]);
SysFreeString(bstr[2]);
SysFreeString(bstr[1]);
SysFreeString(bstr[0]);
}
static void test_attr_GetIDsOfNames(IHTMLDOMAttribute *attr)
{
DISPID dispids[3];
HRESULT hres;
BSTR bstr[3];
bstr[0] = SysAllocString(L"insertBefore");
bstr[1] = SysAllocString(L"newChild");
bstr[2] = SysAllocString(L"refChild");
dispids[0] = 0;
dispids[1] = 0xdead;
dispids[2] = 0xbeef;
hres = IHTMLDOMAttribute_GetIDsOfNames(attr, &IID_NULL, bstr, 3, 0, dispids);
ok(hres == S_OK, "GetIDsOfNames failed: %08lx\n", hres);
ok(dispids[0] == DISPID_IHTMLDOMATTRIBUTE2_INSERTBEFORE, "insertBefore dispid = %ld\n", dispids[0]);
ok(dispids[1] == 0xdead, "newChild dispid = %ld\n", dispids[1]);
ok(dispids[2] == 0xbeef, "refChild dispid = %ld\n", dispids[2]);
SysFreeString(bstr[2]);
SysFreeString(bstr[1]);
SysFreeString(bstr[0]);
}
static void test_elem_bounding_client_rect(IUnknown *unk)
{
IHTMLRectCollection *rects;
@ -5462,6 +5555,7 @@ static IHTMLElement *get_elem_by_id(IHTMLDocument2 *doc, const WCHAR *id, BOOL e
elem = get_elem_iface((IUnknown*)disp);
IDispatch_Release(disp);
test_elem_GetIDsOfNames(elem);
return elem;
}
@ -5482,6 +5576,8 @@ static IHTMLElement *get_doc_elem_by_id(IHTMLDocument2 *doc, const WCHAR *id)
IHTMLDocument3_Release(doc3);
if(elem)
test_elem_GetIDsOfNames(elem);
return elem;
}
@ -6854,6 +6950,8 @@ static void test_doc_elem(IHTMLDocument2 *doc)
HRESULT hres;
BSTR bstr;
test_doc_GetIDsOfNames(doc);
hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument3, (void**)&doc3);
ok(hres == S_OK, "QueryInterface(IID_IHTMLDocument3) failed: %08lx\n", hres);
@ -6875,6 +6973,7 @@ static void test_doc_elem(IHTMLDocument2 *doc)
owner_doc = get_owner_doc((IUnknown*)elem);
ok(iface_cmp((IUnknown *)doc_node, (IUnknown *)owner_doc), "doc_node != owner_doc\n");
IHTMLDocument2_Release(owner_doc);
test_doc_GetIDsOfNames(doc_node);
owner_doc = get_owner_doc((IUnknown*)doc_node);
ok(!owner_doc, "owner_doc = %p\n", owner_doc);
@ -7158,6 +7257,7 @@ static void test_window(IHTMLDocument2 *doc)
win_skip("IID_ITravelLogClient not supported\n");
test_disp((IUnknown*)window, &DIID_DispHTMLWindow2, &CLSID_HTMLWindow2, L"[object]");
test_window_GetIDsOfNames(window);
hres = IHTMLWindow2_get_document(window, &doc2);
ok(hres == S_OK, "get_document failed: %08lx\n", hres);
@ -9796,6 +9896,7 @@ static void test_attr(IHTMLDocument2 *doc, IHTMLElement *elem)
test_no_iface((IUnknown*)attr, &IID_IHTMLDOMNode);
test_attr_specified(attr, VARIANT_TRUE);
test_attr_parent(attr);
test_attr_GetIDsOfNames(attr);
attr2 = get_elem_attr_node((IUnknown*)elem, L"id", TRUE);
ok(iface_cmp((IUnknown*)attr, (IUnknown*)attr2), "attr != attr2\n");

View file

@ -25,6 +25,7 @@
#include "winbase.h"
#include "ole2.h"
#include "mshtml.h"
#include "mshtmdid.h"
#include "objsafe.h"
#include "wine/test.h"
@ -402,6 +403,35 @@ static void create_xmlhttprequest(IHTMLDocument2 *doc)
ok(xhr != NULL, "xhr == NULL\n");
}
static void test_GetIDsOfNames(IHTMLDocument2 *doc)
{
DISPID dispids[3];
HRESULT hres;
BSTR bstr[3];
create_xmlhttprequest(doc);
if(!xhr)
return;
bstr[0] = SysAllocString(L"open");
bstr[1] = SysAllocString(L"bstrMethod");
bstr[2] = SysAllocString(L"varAsync");
dispids[0] = 0;
dispids[1] = 0xdead;
dispids[2] = 0xbeef;
hres = IHTMLXMLHttpRequest_GetIDsOfNames(xhr, &IID_NULL, bstr, 3, 0, dispids);
ok(hres == S_OK, "GetIDsOfNames failed: %08lx\n", hres);
ok(dispids[0] == DISPID_IHTMLXMLHTTPREQUEST_OPEN, "open dispid = %ld\n", dispids[0]);
ok(dispids[1] == 0xdead, "bstrMethod dispid = %ld\n", dispids[1]);
ok(dispids[2] == 0xbeef, "varAsync dispid = %ld\n", dispids[2]);
SysFreeString(bstr[2]);
SysFreeString(bstr[1]);
SysFreeString(bstr[0]);
IHTMLXMLHttpRequest_Release(xhr);
xhr = NULL;
}
static void test_header(const struct HEADER_TYPE expect[], int num)
{
int i;
@ -1100,6 +1130,7 @@ START_TEST(xmlhttprequest)
content_type = SysAllocString(L"Content-Type");
doc = create_doc_from_url(start_url);
if(doc) {
test_GetIDsOfNames(doc);
test_sync_xhr(doc, xml_url, expect_response_text);
test_sync_xhr(doc, large_page_url, NULL);
test_async_xhr(doc, xml_url, expect_response_text);