From 055bf9f5a238005d5a8f80ce8dd24b221837e7e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20Iv=C4=83ncescu?= Date: Wed, 13 Nov 2024 19:32:43 +0200 Subject: [PATCH] mshtml: Override window's element prop directly rather than using GLOBAL_DISPEXVAR. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When GLOBAL_DISPEXVAR is used, we store the id of the dynamic prop and invoke it using the same id. But this is not the case if we have a jsdisp, which is redirected from InvokeEx and results in an invalid id. The actual way this works on native (in IE9+) is that element/frame props are special and not part of the window object at all. They're actually looked up after the prototype is, in a special way, but that requires a revamp. Storing over it just creates an actual prop on the window (which is what we are doing here). Signed-off-by: Gabriel Ivăncescu --- dlls/jscript/dispex.c | 8 +++++++- dlls/mshtml/htmlwindow.c | 3 +++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index 7d5ebe2c863..aa81de7ad75 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -656,7 +656,13 @@ static HRESULT prop_put(jsdisp_t *This, dispex_prop_t *prop, jsval_t val) TRACE("no prop_put\n"); return S_OK; } - return This->builtin_info->prop_put(This, prop->u.id, val); + hres = This->builtin_info->prop_put(This, prop->u.id, val); + if(hres != S_FALSE) + return hres; + prop->type = PROP_JSVAL; + prop->flags = PROPF_ENUMERABLE | PROPF_CONFIGURABLE | PROPF_WRITABLE; + prop->u.val = jsval_undefined(); + break; default: ERR("type %d\n", prop->type); return E_FAIL; diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index 8a7119c5451..1343c75ba34 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -3926,6 +3926,9 @@ HRESULT HTMLWindow_invoke(DispatchEx *dispex, DISPID id, LCID lcid, WORD flags, case DISPATCH_PROPERTYPUT: { DISPID dispex_id; + if(This->event_target.dispex.jsdisp) + return S_FALSE; + hres = dispex_get_dynid(&This->event_target.dispex, prop->name, TRUE, &dispex_id); if(FAILED(hres)) return hres;