[PATCH v6 0/1] MR10393: Draft: vbscript: Check named item dispatch for Dim variable names.
When declaring variables with Dim in a visible named item context, check the named item's IDispatch for each variable name via GetIDsOfNames. This matches Windows VBScript behavior where Dim probes the host object before creating the variable. -- v6: vbscript: Check named item dispatch for Dim variable names. https://gitlab.winehq.org/wine/wine/-/merge_requests/10393
From: Francis De Brabandere <francisdb@gmail.com> When declaring variables with Dim in a visible named item context, check the named item's IDispatch for each variable name via GetIDsOfNames. This matches Windows VBScript behavior where Dim probes the host object before creating the variable. --- dlls/vbscript/tests/vbscript.c | 4 ++-- dlls/vbscript/vbscript.c | 38 +++++++++++++++++++++++++++++++--- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/dlls/vbscript/tests/vbscript.c b/dlls/vbscript/tests/vbscript.c index adda087ce76..506e6869a7c 100644 --- a/dlls/vbscript/tests/vbscript.c +++ b/dlls/vbscript/tests/vbscript.c @@ -2088,8 +2088,8 @@ static void test_named_items(void) hres = IActiveScriptParse_ParseScriptText(parse, L"dim abc\n", L"visibleItem", NULL, NULL, 0, 0, 0, NULL, NULL); ok(hres == S_OK, "ParseScriptText failed: %08lx\n", hres); CHECK_CALLED(OnEnterScript); - todo_wine CHECK_CALLED(GetItemInfo_visible); - todo_wine CHECK_CALLED(GetIDsOfNames_visible); + CHECK_CALLED(GetItemInfo_visible); + CHECK_CALLED(GetIDsOfNames_visible); CHECK_CALLED(OnLeaveScript); SET_EXPECT(OnEnterScript); SET_EXPECT(OnLeaveScript); diff --git a/dlls/vbscript/vbscript.c b/dlls/vbscript/vbscript.c index 715c98d32bb..146e99a75d1 100644 --- a/dlls/vbscript/vbscript.c +++ b/dlls/vbscript/vbscript.c @@ -91,6 +91,8 @@ static inline BOOL is_started(VBScript *This) || This->state == SCRIPTSTATE_DISCONNECTED; } +static HRESULT retrieve_named_item_disp(IActiveScriptSite *site, named_item_t *item); + static HRESULT exec_global_code(script_ctx_t *ctx, vbscode_t *code, VARIANT *res) { ScriptDisp *obj = ctx->script_obj; @@ -136,8 +138,40 @@ static HRESULT exec_global_code(script_ctx_t *ctx, vbscode_t *code, VARIANT *res obj->global_funcs_size = cnt; } + /* For visible named items with Dim declarations, re-fetch the dispatch + from the host even if previously cached, then probe each variable name + via GetIDsOfNames. The variable is always created regardless of whether + the name exists on the host dispatch. + TODO: It is unclear why Windows probes the host dispatch when the result + is not used to skip variable creation. Perhaps it is used for some side + effect or diagnostic purpose that we have not yet identified. */ + if(code->main_code.var_cnt && code->named_item + && !(code->named_item->flags & SCRIPTITEM_CODEONLY)) + { + if(code->named_item->disp) + { + IDispatch_Release(code->named_item->disp); + code->named_item->disp = NULL; + } + retrieve_named_item_disp(ctx->site, code->named_item); + } + for (i = 0; i < code->main_code.var_cnt; i++) { + /* Probe the named item's dispatch for each variable name, matching + Windows behavior. The variable is always created regardless. */ + if(code->named_item && code->named_item->disp + && !(code->named_item->flags & SCRIPTITEM_CODEONLY)) + { + BSTR name = SysAllocString(code->main_code.vars[i].name); + if(name) + { + DISPID id; + disp_get_id(code->named_item->disp, name, VBDISP_CALLGET, TRUE, &id); + SysFreeString(name); + } + } + if (!(var = heap_pool_alloc(&obj->heap, sizeof(*var)))) return E_OUTOFMEMORY; @@ -148,11 +182,9 @@ static HRESULT exec_global_code(script_ctx_t *ctx, vbscode_t *code, VARIANT *res var->is_const = FALSE; var->array = NULL; - obj->global_vars[obj->global_vars_cnt + i] = var; + obj->global_vars[obj->global_vars_cnt++] = var; } - obj->global_vars_cnt += code->main_code.var_cnt; - for (func_iter = code->funcs; func_iter; func_iter = func_iter->next) { for (i = 0; i < obj->global_funcs_cnt; i++) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10393
Francis De Brabandere (@francisdb) commented about dlls/vbscript/vbscript.c:
obj->global_funcs_size = cnt; }
+ /* For visible named items with Dim declarations, re-fetch the dispatch + from the host even if previously cached, then probe each variable name + via GetIDsOfNames. The variable is always created regardless of whether + the name exists on the host dispatch. + TODO: It is unclear why Windows probes the host dispatch when the result
@jacek any idea what could be going on here that we should be handling? -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10393#note_133047
participants (2)
-
Francis De Brabandere -
Francis De Brabandere (@francisdb)