Module: wine Branch: master Commit: a3dbd5067b4cad48e63b68d17d1598284e05d376 URL: https://gitlab.winehq.org/wine/wine/-/commit/a3dbd5067b4cad48e63b68d17d15982...
Author: Gabriel Ivăncescu gabrielopcode@gmail.com Date: Mon Oct 31 18:27:37 2022 +0200
mshtml: Allow null or undefined listeners in attachEvent/detachEvent.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com
---
dlls/mshtml/dispex.c | 11 ++++++- dlls/mshtml/htmlevent.c | 5 +++ dlls/mshtml/tests/script.c | 77 +++++++++++++++++++++++++++++++++++++++------- 3 files changed, 81 insertions(+), 12 deletions(-)
diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index ebb1a675d91..d8aaf819f58 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -1072,7 +1072,8 @@ HRESULT change_type(VARIANT *dst, VARIANT *src, VARTYPE vt, IServiceProvider *ca if(SUCCEEDED(hres)) { hres = IVariantChangeType_ChangeType(change_type, dst, src, LOCALE_NEUTRAL, vt); IVariantChangeType_Release(change_type); - return hres; + if(SUCCEEDED(hres)) + return S_OK; } }
@@ -1084,6 +1085,14 @@ HRESULT change_type(VARIANT *dst, VARIANT *src, VARTYPE vt, IServiceProvider *ca return S_OK; } break; + case VT_UNKNOWN: + case VT_DISPATCH: + if(V_VT(src) == VT_EMPTY || V_VT(src) == VT_NULL) { + V_VT(dst) = vt; + V_DISPATCH(dst) = NULL; + return S_OK; + } + break; }
return VariantChangeType(dst, src, 0, vt); diff --git a/dlls/mshtml/htmlevent.c b/dlls/mshtml/htmlevent.c index 581d949a447..ebedff82564 100644 --- a/dlls/mshtml/htmlevent.c +++ b/dlls/mshtml/htmlevent.c @@ -3870,6 +3870,11 @@ HRESULT attach_event(EventTarget *event_target, BSTR name, IDispatch *disp, VARI event_listener_t *listener; eventid_t eid;
+ if(!disp) { + *res = VARIANT_FALSE; + return S_OK; + } + eid = attr_to_eid(name); if(eid == EVENTID_LAST) { WARN("Unknown event\n"); diff --git a/dlls/mshtml/tests/script.c b/dlls/mshtml/tests/script.c index 14e3a148239..6762cd985d0 100644 --- a/dlls/mshtml/tests/script.c +++ b/dlls/mshtml/tests/script.c @@ -135,7 +135,8 @@ DEFINE_EXPECT(external_success); DEFINE_EXPECT(QS_VariantConversion); DEFINE_EXPECT(QS_IActiveScriptSite); DEFINE_EXPECT(QS_GetCaller); -DEFINE_EXPECT(ChangeType); +DEFINE_EXPECT(ChangeType_bstr); +DEFINE_EXPECT(ChangeType_dispatch); DEFINE_EXPECT(GetTypeInfo);
#define TESTSCRIPT_CLSID "{178fc163-f585-4e24-9c13-4bb7faf80746}" @@ -364,18 +365,29 @@ static ULONG WINAPI VariantChangeType_Release(IVariantChangeType *iface)
static HRESULT WINAPI VariantChangeType_ChangeType(IVariantChangeType *iface, VARIANT *dst, VARIANT *src, LCID lcid, VARTYPE vt) { - CHECK_EXPECT(ChangeType); - ok(dst != NULL, "dst = NULL\n"); ok(V_VT(dst) == VT_EMPTY, "V_VT(dst) = %d\n", V_VT(dst)); ok(src != NULL, "src = NULL\n"); - ok(V_VT(src) == VT_I4, "V_VT(src) = %d\n", V_VT(src)); - ok(V_I4(src) == 0xf0f0f0, "V_I4(src) = %lx\n", V_I4(src)); ok(lcid == LOCALE_NEUTRAL, "lcid = %ld\n", lcid); - ok(vt == VT_BSTR, "vt = %d\n", vt);
- V_VT(dst) = VT_BSTR; - V_BSTR(dst) = SysAllocString(L"red"); + switch(vt) { + case VT_BSTR: + CHECK_EXPECT(ChangeType_bstr); + ok(V_VT(src) == VT_I4, "V_VT(src) = %d\n", V_VT(src)); + ok(V_I4(src) == 0xf0f0f0, "V_I4(src) = %lx\n", V_I4(src)); + V_VT(dst) = VT_BSTR; + V_BSTR(dst) = SysAllocString(L"red"); + break; + case VT_DISPATCH: + CHECK_EXPECT(ChangeType_dispatch); + ok(V_VT(src) == VT_NULL, "V_VT(src) = %d\n", V_VT(src)); + /* native jscript returns E_NOTIMPL, use a "valid" error to test that it doesn't matter */ + return E_OUTOFMEMORY; + default: + ok(0, "unexpected vt %d\n", vt); + return E_NOTIMPL; + } + return S_OK; }
@@ -2292,10 +2304,13 @@ static void test_global_id(void)
static void test_arg_conv(IHTMLWindow2 *window) { + DISPPARAMS dp = { 0 }; IHTMLDocument2 *doc; IDispatchEx *dispex; IHTMLElement *elem; - VARIANT v; + VARIANT v, args[2]; + DISPID id; + BSTR bstr; HRESULT hres;
hres = IHTMLWindow2_get_document(window, &doc); @@ -2310,20 +2325,60 @@ static void test_arg_conv(IHTMLWindow2 *window) ok(hres == S_OK, "Could not get IDispatchEx iface: %08lx\n", hres);
SET_EXPECT(QS_VariantConversion); - SET_EXPECT(ChangeType); + SET_EXPECT(ChangeType_bstr); V_VT(&v) = VT_I4; V_I4(&v) = 0xf0f0f0; hres = dispex_propput(dispex, DISPID_IHTMLBODYELEMENT_BACKGROUND, 0, &v, &caller_sp); ok(hres == S_OK, "InvokeEx failed: %08lx\n", hres); CHECK_CALLED(QS_VariantConversion); - CHECK_CALLED(ChangeType); + CHECK_CALLED(ChangeType_bstr);
V_VT(&v) = VT_EMPTY; hres = dispex_propget(dispex, DISPID_IHTMLBODYELEMENT_BGCOLOR, &v, &caller_sp); ok(hres == S_OK, "InvokeEx failed: %08lx\n", hres); ok(V_VT(&v) == VT_BSTR, "V_VT(var)=%d\n", V_VT(&v)); ok(!V_BSTR(&v), "V_BSTR(&var) = %s\n", wine_dbgstr_w(V_BSTR(&v))); + IDispatchEx_Release(dispex); + + hres = IHTMLWindow2_QueryInterface(window, &IID_IDispatchEx, (void**)&dispex); + ok(hres == S_OK, "Could not get IDispatchEx iface: %08lx\n", hres); + + SET_EXPECT(GetScriptDispatch); + bstr = SysAllocString(L"attachEvent"); + hres = IDispatchEx_GetDispID(dispex, bstr, fdexNameCaseSensitive, &id); + ok(hres == S_OK, "GetDispID failed: %08lx\n", hres); + CHECK_CALLED(GetScriptDispatch); + SysFreeString(bstr); + + SET_EXPECT(QS_VariantConversion); + SET_EXPECT(ChangeType_dispatch); + dp.cArgs = 2; + dp.rgvarg = args; + V_VT(&args[1]) = VT_BSTR; + V_BSTR(&args[1]) = SysAllocString(L"onload"); + V_VT(&args[0]) = VT_NULL; + hres = IDispatchEx_InvokeEx(dispex, id, LOCALE_NEUTRAL, DISPATCH_METHOD, &dp, &v, NULL, &caller_sp); + ok(hres == S_OK, "InvokeEx failed: %08lx\n", hres); + ok(V_VT(&v) == VT_BOOL, "V_VT(var) = %d\n", V_VT(&v)); + ok(V_BOOL(&v) == VARIANT_FALSE, "V_BOOL(var) = %d\n", V_BOOL(&v)); + CHECK_CALLED(QS_VariantConversion); + CHECK_CALLED(ChangeType_dispatch); + + SET_EXPECT(GetScriptDispatch); + bstr = SysAllocString(L"detachEvent"); + hres = IDispatchEx_GetDispID(dispex, bstr, fdexNameCaseSensitive, &id); + ok(hres == S_OK, "GetDispID failed: %08lx\n", hres); + CHECK_CALLED(GetScriptDispatch); + SysFreeString(bstr); + + SET_EXPECT(QS_VariantConversion); + SET_EXPECT(ChangeType_dispatch); + hres = IDispatchEx_InvokeEx(dispex, id, LOCALE_NEUTRAL, DISPATCH_METHOD, &dp, NULL, NULL, &caller_sp); + ok(hres == S_OK, "InvokeEx failed: %08lx\n", hres); + CHECK_CALLED(QS_VariantConversion); + CHECK_CALLED(ChangeType_dispatch);
+ SysFreeString(V_BSTR(&args[1])); IDispatchEx_Release(dispex); }