From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/dispex.c | 11 +++++++- dlls/mshtml/htmlevent.c | 5 ++++ dlls/mshtml/tests/script.c | 57 ++++++++++++++++++++++++++++++++++++-- 3 files changed, 70 insertions(+), 3 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..1a0ee4eb2c7 100644 --- a/dlls/mshtml/tests/script.c +++ b/dlls/mshtml/tests/script.c @@ -362,6 +362,8 @@ static ULONG WINAPI VariantChangeType_Release(IVariantChangeType *iface) return 1; }
+static BOOL ChangeType_expect_null_dispatch; + static HRESULT WINAPI VariantChangeType_ChangeType(IVariantChangeType *iface, VARIANT *dst, VARIANT *src, LCID lcid, VARTYPE vt) { CHECK_EXPECT(ChangeType); @@ -369,9 +371,15 @@ static HRESULT WINAPI VariantChangeType_ChangeType(IVariantChangeType *iface, VA 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(lcid == LOCALE_NEUTRAL, "lcid = %ld\n", lcid); + if(ChangeType_expect_null_dispatch) { + ok(V_VT(src) == VT_NULL, "V_VT(src) = %d\n", V_VT(src)); + ok(vt == VT_DISPATCH, "vt = %d\n", vt); + /* native jscript returns E_NOTIMPL, use a "valid" error to test that it doesn't matter */ + return E_OUTOFMEMORY; + } 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; @@ -2292,10 +2300,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); @@ -2323,7 +2334,49 @@ static void test_arg_conv(IHTMLWindow2 *window) 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); + + ChangeType_expect_null_dispatch = TRUE; + SET_EXPECT(QS_VariantConversion); + SET_EXPECT(ChangeType); + 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); + + 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); + 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);
+ ChangeType_expect_null_dispatch = FALSE; + SysFreeString(V_BSTR(&args[1])); IDispatchEx_Release(dispex); }