The current code can't cope with it, so do the same thing as in GetDispID, to prevent a possible crash.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/vbscript/vbdisp.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/dlls/vbscript/vbdisp.c b/dlls/vbscript/vbdisp.c index c14cd7b..36eba21 100644 --- a/dlls/vbscript/vbdisp.c +++ b/dlls/vbscript/vbdisp.c @@ -1388,6 +1388,9 @@ static HRESULT WINAPI ScriptDisp_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
TRACE("(%p)->(%x %x %x %p %p %p %p)\n", This, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller);
+ if (!This->ctx) + return E_UNEXPECTED; + if (id & DISPID_FUNCTION_MASK) { id &= ~DISPID_FUNCTION_MASK;
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com ---
Simplifies the 5th patch.
dlls/vbscript/interp.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-)
diff --git a/dlls/vbscript/interp.c b/dlls/vbscript/interp.c index b328674..f0820be 100644 --- a/dlls/vbscript/interp.c +++ b/dlls/vbscript/interp.c @@ -110,6 +110,22 @@ static BOOL lookup_global_vars(ScriptDisp *script, const WCHAR *name, ref_t *ref return FALSE; }
+static BOOL lookup_global_funcs(ScriptDisp *script, const WCHAR *name, ref_t *ref) +{ + function_t **funcs = script->global_funcs; + size_t i, cnt = script->global_funcs_cnt; + + for(i = 0; i < cnt; i++) { + if(!wcsicmp(funcs[i]->name, name)) { + ref->type = REF_FUNC; + ref->u.f = funcs[i]; + return TRUE; + } + } + + return FALSE; +} + static HRESULT lookup_identifier(exec_ctx_t *ctx, BSTR name, vbdisp_invoke_type_t invoke_type, ref_t *ref) { ScriptDisp *script_obj = ctx->script->script_obj; @@ -177,15 +193,8 @@ static HRESULT lookup_identifier(exec_ctx_t *ctx, BSTR name, vbdisp_invoke_type_
if(lookup_global_vars(script_obj, name, ref)) return S_OK; - - for(i = 0; i < script_obj->global_funcs_cnt; i++) { - function_t *func = script_obj->global_funcs[i]; - if(!wcsicmp(func->name, name)) { - ref->type = REF_FUNC; - ref->u.f = func; - return S_OK; - } - } + if(lookup_global_funcs(script_obj, name, ref)) + return S_OK;
hres = get_builtin_id(ctx->script->global_obj, name, &id); if(SUCCEEDED(hres)) {
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com ---
This is needed for 5th patch to avoid forward declaring ScriptDisp.
dlls/vbscript/vbscript.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/dlls/vbscript/vbscript.h b/dlls/vbscript/vbscript.h index f37b0ce..589abc3 100644 --- a/dlls/vbscript/vbscript.h +++ b/dlls/vbscript/vbscript.h @@ -55,14 +55,6 @@ typedef struct _vbscode_t vbscode_t; typedef struct _script_ctx_t script_ctx_t; typedef struct _vbdisp_t vbdisp_t;
-typedef struct named_item_t { - IDispatch *disp; - DWORD flags; - LPWSTR name; - - struct list entry; -} named_item_t; - typedef enum { VBDISP_CALLGET, VBDISP_LET, @@ -156,6 +148,14 @@ typedef struct { script_ctx_t *ctx; } BuiltinDisp;
+typedef struct named_item_t { + IDispatch *disp; + DWORD flags; + LPWSTR name; + + struct list entry; +} named_item_t; + HRESULT create_vbdisp(const class_desc_t*,vbdisp_t**) DECLSPEC_HIDDEN; HRESULT disp_get_id(IDispatch*,BSTR,vbdisp_invoke_type_t,BOOL,DISPID*) DECLSPEC_HIDDEN; HRESULT vbdisp_get_id(vbdisp_t*,BSTR,vbdisp_invoke_type_t,BOOL,DISPID*) DECLSPEC_HIDDEN;
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com ---
v5: Don't use an extra parameter, instead calculate it based on 'flags'.
dlls/vbscript/tests/vbscript.c | 56 +++++++++++++++++++++++++++++++++- dlls/vbscript/vbscript.c | 3 +- 2 files changed, 57 insertions(+), 2 deletions(-)
diff --git a/dlls/vbscript/tests/vbscript.c b/dlls/vbscript/tests/vbscript.c index 10af993..4e44758 100644 --- a/dlls/vbscript/tests/vbscript.c +++ b/dlls/vbscript/tests/vbscript.c @@ -97,6 +97,7 @@ DEFINE_EXPECT(OnEnterScript); DEFINE_EXPECT(OnLeaveScript); DEFINE_EXPECT(GetItemInfo_global); DEFINE_EXPECT(GetItemInfo_visible); +DEFINE_EXPECT(GetItemInfo_visible_code); DEFINE_EXPECT(testCall);
DEFINE_GUID(CLSID_VBScript, 0xb54f3741, 0x5b07, 0x11cf, 0xa4,0xb0, 0x00,0xaa,0x00,0x4a,0x55,0xe8); @@ -137,7 +138,7 @@ static HRESULT WINAPI Dispatch_QueryInterface(IDispatch *iface, REFIID riid, voi return E_NOINTERFACE; }
-static ULONG global_named_item_ref, visible_named_item_ref; +static ULONG global_named_item_ref, visible_named_item_ref, visible_code_named_item_ref;
static ULONG WINAPI global_AddRef(IDispatch *iface) { @@ -159,6 +160,16 @@ static ULONG WINAPI visible_Release(IDispatch *iface) return --visible_named_item_ref; }
+static ULONG WINAPI visible_code_AddRef(IDispatch *iface) +{ + return ++visible_code_named_item_ref; +} + +static ULONG WINAPI visible_code_Release(IDispatch *iface) +{ + return --visible_code_named_item_ref; +} + static HRESULT WINAPI Dispatch_GetTypeInfoCount(IDispatch *iface, UINT *pctinfo) { ok(0, "unexpected call\n"); @@ -214,6 +225,18 @@ static const IDispatchVtbl visible_named_item_vtbl = {
static IDispatch visible_named_item = { &visible_named_item_vtbl };
+static const IDispatchVtbl visible_code_named_item_vtbl = { + Dispatch_QueryInterface, + visible_code_AddRef, + visible_code_Release, + Dispatch_GetTypeInfoCount, + Dispatch_GetTypeInfo, + Dispatch_GetIDsOfNames, + Dispatch_Invoke +}; + +static IDispatch visible_code_named_item = { &visible_code_named_item_vtbl }; + static HRESULT WINAPI ActiveScriptSite_QueryInterface(IActiveScriptSite *iface, REFIID riid, void **ppv) { *ppv = NULL; @@ -261,6 +284,12 @@ static HRESULT WINAPI ActiveScriptSite_GetItemInfo(IActiveScriptSite *iface, LPC *item_unk = (IUnknown*)&visible_named_item; return S_OK; } + if(!wcscmp(name, L"visibleCodeItem")) { + CHECK_EXPECT(GetItemInfo_visible_code); + IDispatch_AddRef(&visible_code_named_item); + *item_unk = (IUnknown*)&visible_code_named_item; + return S_OK; + } ok(0, "unexpected call %s\n", wine_dbgstr_w(name)); return E_NOTIMPL; } @@ -1704,6 +1733,7 @@ static void test_named_items(void) { IActiveScriptParse *parse; IActiveScript *script; + IDispatch *disp; ULONG ref; HRESULT hres;
@@ -1731,9 +1761,12 @@ static void test_named_items(void)
hres = IActiveScript_AddNamedItem(script, L"visibleItem", SCRIPTITEM_ISVISIBLE); ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres); + hres = IActiveScript_AddNamedItem(script, L"visibleCodeItem", SCRIPTITEM_ISVISIBLE | SCRIPTITEM_CODEONLY); + ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
ok(global_named_item_ref > 0, "global_named_item_ref = %u\n", global_named_item_ref); ok(visible_named_item_ref == 0, "visible_named_item_ref = %u\n", visible_named_item_ref); + ok(visible_code_named_item_ref == 0, "visible_code_named_item_ref = %u\n", visible_code_named_item_ref);
SET_EXPECT(OnStateChange_INITIALIZED); hres = IActiveScriptParse_InitNew(parse); @@ -1755,8 +1788,28 @@ static void test_named_items(void) CHECK_CALLED(GetItemInfo_visible); CHECK_CALLED(testCall);
+ SET_EXPECT(OnEnterScript); + SET_EXPECT(OnLeaveScript); + SET_EXPECT(testCall); + hres = IActiveScriptParse_ParseScriptText(parse, L"testCall\n", L"visibleCodeItem", NULL, NULL, 0, 0, 0, NULL, NULL); + ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres); + CHECK_CALLED(OnEnterScript); + CHECK_CALLED(OnLeaveScript); + CHECK_CALLED(testCall); + + hres = IActiveScript_GetScriptDispatch(script, L"visibleCodeItem", &disp); + ok(hres == S_OK, "GetScriptDispatch returned: %08x\n", hres); + IDispatch_Release(disp); + + SET_EXPECT(GetItemInfo_visible_code); + SET_EXPECT(testCall); + parse_script(parse, "visibleCodeItem.testCall\n"); + CHECK_CALLED(GetItemInfo_visible_code); + CHECK_CALLED(testCall); + ok(global_named_item_ref > 0, "global_named_item_ref = %u\n", global_named_item_ref); ok(visible_named_item_ref == 1, "visible_named_item_ref = %u\n", visible_named_item_ref); + ok(visible_code_named_item_ref == 1, "visible_code_named_item_ref = %u\n", visible_code_named_item_ref);
SET_EXPECT(testCall); parse_script(parse, "visibleItem.testCall\n"); @@ -1773,6 +1826,7 @@ static void test_named_items(void)
ok(global_named_item_ref == 0, "global_named_item_ref = %u\n", global_named_item_ref); ok(visible_named_item_ref == 0, "visible_named_item_ref = %u\n", visible_named_item_ref); + ok(visible_code_named_item_ref == 0, "visible_code_named_item_ref = %u\n", visible_code_named_item_ref);
test_state(script, SCRIPTSTATE_CLOSED);
diff --git a/dlls/vbscript/vbscript.c b/dlls/vbscript/vbscript.c index 88574fe..670b66d 100644 --- a/dlls/vbscript/vbscript.c +++ b/dlls/vbscript/vbscript.c @@ -191,12 +191,13 @@ static void exec_queued_code(script_ctx_t *ctx)
named_item_t *lookup_named_item(script_ctx_t *ctx, const WCHAR *name, unsigned flags) { + unsigned no_disp_flags = flags ? 0 : SCRIPTITEM_CODEONLY; named_item_t *item; HRESULT hres;
LIST_FOR_EACH_ENTRY(item, &ctx->named_items, named_item_t, entry) { if((item->flags & flags) == flags && !wcsicmp(item->name, name)) { - if(!item->disp) { + if(!item->disp && !(item->flags & no_disp_flags)) { IUnknown *unk;
hres = IActiveScriptSite_GetItemInfo(ctx->site, item->name,
Hi Gabriel,
On 12.02.2020 14:36, Gabriel Ivăncescu wrote:
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com
v5: Don't use an extra parameter, instead calculate it based on 'flags'.
I sent a version with some more tests. Please rebase the rest of the series and use it to simplify GetIDsOfNames in tests.
Thanks,
Jacek
Each named item should have its own associated script dispatch object. Identifiers are added to this object, but code does look into the global script object as well.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com ---
v5: Create the script dispatch on demand in exec_global_code and in lookup_named_item (needed by compilation and GetScriptDispatch before executing any code).
dlls/vbscript/compile.c | 47 +++++++++++++++++++++++++-------------- dlls/vbscript/interp.c | 27 ++++++++++++++++------ dlls/vbscript/vbscript.c | 48 +++++++++++++++++++++++++++++++++++++--- dlls/vbscript/vbscript.h | 4 ++++ 4 files changed, 99 insertions(+), 27 deletions(-)
diff --git a/dlls/vbscript/compile.c b/dlls/vbscript/compile.c index 9888109..8ce4692 100644 --- a/dlls/vbscript/compile.c +++ b/dlls/vbscript/compile.c @@ -1778,26 +1778,33 @@ static HRESULT compile_class(compile_ctx_t *ctx, class_decl_t *class_decl) return S_OK; }
-static BOOL lookup_script_identifier(script_ctx_t *script, const WCHAR *identifier) +static BOOL lookup_script_identifier(compile_ctx_t *ctx, script_ctx_t *script, const WCHAR *identifier) { - ScriptDisp *obj = script->script_obj; + ScriptDisp *contexts[] = { + ctx->code->named_item ? ctx->code->named_item->script_obj : NULL, + script->script_obj + }; class_desc_t *class; vbscode_t *code; - unsigned i; + unsigned c, i;
- for(i = 0; i < obj->global_vars_cnt; i++) { - if(!wcsicmp(obj->global_vars[i]->name, identifier)) - return TRUE; - } + for(c = 0; c < ARRAY_SIZE(contexts); c++) { + if(!contexts[c]) continue;
- for(i = 0; i < obj->global_funcs_cnt; i++) { - if(!wcsicmp(obj->global_funcs[i]->name, identifier)) - return TRUE; - } + for(i = 0; i < contexts[c]->global_vars_cnt; i++) { + if(!wcsicmp(contexts[c]->global_vars[i]->name, identifier)) + return TRUE; + }
- for(class = obj->classes; class; class = class->next) { - if(!wcsicmp(class->name, identifier)) - return TRUE; + for(i = 0; i < contexts[c]->global_funcs_cnt; i++) { + if(!wcsicmp(contexts[c]->global_funcs[i]->name, identifier)) + return TRUE; + } + + for(class = contexts[c]->classes; class; class = class->next) { + if(!wcsicmp(class->name, identifier)) + return TRUE; + } }
LIST_FOR_EACH_ENTRY(code, &script->code_list, vbscode_t, entry) { @@ -1805,7 +1812,7 @@ static BOOL lookup_script_identifier(script_ctx_t *script, const WCHAR *identifi var_desc_t *vars = code->main_code.vars; function_t *func;
- if(!code->pending_exec) + if(!code->pending_exec || (code->named_item && code->named_item != ctx->code->named_item)) continue;
for(i = 0; i < var_cnt; i++) { @@ -1834,14 +1841,14 @@ static HRESULT check_script_collisions(compile_ctx_t *ctx, script_ctx_t *script) class_desc_t *class;
for(i = 0; i < var_cnt; i++) { - if(lookup_script_identifier(script, vars[i].name)) { + if(lookup_script_identifier(ctx, script, vars[i].name)) { FIXME("%s: redefined\n", debugstr_w(vars[i].name)); return E_FAIL; } }
for(class = ctx->code->classes; class; class = class->next) { - if(lookup_script_identifier(script, class->name)) { + if(lookup_script_identifier(ctx, script, class->name)) { FIXME("%s: redefined\n", debugstr_w(class->name)); return E_FAIL; } @@ -1862,6 +1869,8 @@ void release_vbscode(vbscode_t *code)
if(code->context) IDispatch_Release(code->context); + if(code->named_item) + release_named_item(code->named_item); heap_pool_free(&code->heap);
heap_free(code->bstr_pool); @@ -1944,6 +1953,10 @@ HRESULT compile_script(script_ctx_t *script, const WCHAR *src, const WCHAR *item code = ctx.code = alloc_vbscode(&ctx, src, cookie, start_line); if(!ctx.code) return E_OUTOFMEMORY; + if(item) { + code->named_item = item; + item->ref++; + }
hres = parse_script(&ctx.parser, code->source, delimiter, flags); if(FAILED(hres)) { diff --git a/dlls/vbscript/interp.c b/dlls/vbscript/interp.c index f0820be..4f5e463 100644 --- a/dlls/vbscript/interp.c +++ b/dlls/vbscript/interp.c @@ -191,6 +191,13 @@ static HRESULT lookup_identifier(exec_ctx_t *ctx, BSTR name, vbdisp_invoke_type_ } }
+ if(ctx->code->named_item) { + if(lookup_global_vars(ctx->code->named_item->script_obj, name, ref)) + return S_OK; + if(lookup_global_funcs(ctx->code->named_item->script_obj, name, ref)) + return S_OK; + } + if(lookup_global_vars(script_obj, name, ref)) return S_OK; if(lookup_global_funcs(script_obj, name, ref)) @@ -230,7 +237,7 @@ static HRESULT lookup_identifier(exec_ctx_t *ctx, BSTR name, vbdisp_invoke_type_ static HRESULT add_dynamic_var(exec_ctx_t *ctx, const WCHAR *name, BOOL is_const, VARIANT **out_var) { - ScriptDisp *script_obj = ctx->script->script_obj; + ScriptDisp *script_obj = ctx->code->named_item ? ctx->code->named_item->script_obj : ctx->script->script_obj; dynamic_var_t *new_var; heap_pool_t *heap; WCHAR *str; @@ -1113,7 +1120,7 @@ static HRESULT interp_deref(exec_ctx_t *ctx) static HRESULT interp_new(exec_ctx_t *ctx) { const WCHAR *arg = ctx->instr->arg1.bstr; - class_desc_t *class_desc; + class_desc_t *class_desc = NULL; vbdisp_t *obj; VARIANT v; HRESULT hres; @@ -1131,10 +1138,14 @@ static HRESULT interp_new(exec_ctx_t *ctx) return stack_push(ctx, &v); }
- for(class_desc = ctx->script->script_obj->classes; class_desc; class_desc = class_desc->next) { - if(!wcsicmp(class_desc->name, arg)) - break; - } + if(ctx->code->named_item) + for(class_desc = ctx->code->named_item->script_obj->classes; class_desc; class_desc = class_desc->next) + if(!wcsicmp(class_desc->name, arg)) + break; + if(!class_desc) + for(class_desc = ctx->script->script_obj->classes; class_desc; class_desc = class_desc->next) + if(!wcsicmp(class_desc->name, arg)) + break; if(!class_desc) { FIXME("Class %s not found\n", debugstr_w(arg)); return E_FAIL; @@ -1151,7 +1162,7 @@ static HRESULT interp_new(exec_ctx_t *ctx)
static HRESULT interp_dim(exec_ctx_t *ctx) { - ScriptDisp *script_obj = ctx->script->script_obj; + ScriptDisp *script_obj = ctx->code->named_item ? ctx->code->named_item->script_obj : ctx->script->script_obj; const BSTR ident = ctx->instr->arg1.bstr; const unsigned array_id = ctx->instr->arg2.uint; const array_desc_t *array_desc; @@ -1517,6 +1528,8 @@ static HRESULT interp_me(exec_ctx_t *ctx)
if(ctx->vbthis) disp = (IDispatch*)&ctx->vbthis->IDispatchEx_iface; + else if(ctx->code->named_item) + disp = (IDispatch*)&ctx->code->named_item->script_obj->IDispatchEx_iface; else if(ctx->script->host_global) disp = ctx->script->host_global; else diff --git a/dlls/vbscript/vbscript.c b/dlls/vbscript/vbscript.c index 670b66d..52dbd32 100644 --- a/dlls/vbscript/vbscript.c +++ b/dlls/vbscript/vbscript.c @@ -97,6 +97,15 @@ static HRESULT exec_global_code(script_ctx_t *ctx, vbscode_t *code, VARIANT *res function_t *func_iter, **new_funcs; dynamic_var_t *var, **new_vars; size_t cnt, i; + HRESULT hres; + + if(code->named_item) { + if(!code->named_item->script_obj) { + hres = create_script_disp(ctx, &code->named_item->script_obj); + if(FAILED(hres)) return hres; + } + obj = code->named_item->script_obj; + }
cnt = obj->global_vars_cnt + code->main_code.var_cnt; if (cnt > obj->global_vars_size) @@ -197,6 +206,10 @@ named_item_t *lookup_named_item(script_ctx_t *ctx, const WCHAR *name, unsigned f
LIST_FOR_EACH_ENTRY(item, &ctx->named_items, named_item_t, entry) { if((item->flags & flags) == flags && !wcsicmp(item->name, name)) { + if(!item->script_obj) { + hres = create_script_disp(ctx, &item->script_obj); + if(FAILED(hres)) return NULL; + } if(!item->disp && !(item->flags & no_disp_flags)) { IUnknown *unk;
@@ -222,6 +235,23 @@ named_item_t *lookup_named_item(script_ctx_t *ctx, const WCHAR *name, unsigned f return NULL; }
+static void release_named_item_script_obj(named_item_t *item) +{ + if(!item->script_obj) return; + + item->script_obj->ctx = NULL; + IDispatchEx_Release(&item->script_obj->IDispatchEx_iface); + item->script_obj = NULL; +} + +void release_named_item(named_item_t *item) +{ + if(--item->ref) return; + + heap_free(item->name); + heap_free(item); +} + static void release_script(script_ctx_t *ctx) { vbscode_t *code, *code_next; @@ -235,6 +265,7 @@ static void release_script(script_ctx_t *ctx) { code->pending_exec = TRUE; if(code->last_class) code->last_class->next = NULL; + if(code->named_item) release_named_item_script_obj(code->named_item); } else { @@ -249,8 +280,8 @@ static void release_script(script_ctx_t *ctx) list_remove(&iter->entry); if(iter->disp) IDispatch_Release(iter->disp); - heap_free(iter->name); - heap_free(iter); + release_named_item_script_obj(iter); + release_named_item(iter); }
if(ctx->host_global) { @@ -659,8 +690,10 @@ static HRESULT WINAPI VBScript_AddNamedItem(IActiveScript *iface, LPCOLESTR pstr return E_OUTOFMEMORY; }
+ item->ref = 1; item->disp = disp; item->flags = dwFlags; + item->script_obj = NULL; item->name = heap_strdupW(pstrName); if(!item->name) { if(disp) @@ -684,6 +717,7 @@ static HRESULT WINAPI VBScript_AddTypeLib(IActiveScript *iface, REFGUID rguidTyp static HRESULT WINAPI VBScript_GetScriptDispatch(IActiveScript *iface, LPCOLESTR pstrItemName, IDispatch **ppdisp) { VBScript *This = impl_from_IActiveScript(iface); + ScriptDisp *script_obj;
TRACE("(%p)->(%s %p)\n", This, debugstr_w(pstrItemName), ppdisp);
@@ -695,7 +729,15 @@ static HRESULT WINAPI VBScript_GetScriptDispatch(IActiveScript *iface, LPCOLESTR return E_UNEXPECTED; }
- *ppdisp = (IDispatch*)&This->ctx->script_obj->IDispatchEx_iface; + if(pstrItemName) { + named_item_t *item = lookup_named_item(This->ctx, pstrItemName, 0); + if(!item) return E_INVALIDARG; + script_obj = item->script_obj; + } + else + script_obj = This->ctx->script_obj; + + *ppdisp = (IDispatch*)&script_obj->IDispatchEx_iface; IDispatch_AddRef(*ppdisp); return S_OK; } diff --git a/dlls/vbscript/vbscript.h b/dlls/vbscript/vbscript.h index 589abc3..5860863 100644 --- a/dlls/vbscript/vbscript.h +++ b/dlls/vbscript/vbscript.h @@ -149,7 +149,9 @@ typedef struct { } BuiltinDisp;
typedef struct named_item_t { + ScriptDisp *script_obj; IDispatch *disp; + unsigned ref; DWORD flags; LPWSTR name;
@@ -349,6 +351,7 @@ struct _vbscode_t { BOOL is_persistent; function_t main_code; IDispatch *context; + named_item_t *named_item;
BSTR *bstr_pool; unsigned bstr_pool_size; @@ -373,6 +376,7 @@ HRESULT compile_procedure(script_ctx_t*,const WCHAR*,const WCHAR*,const WCHAR*,D HRESULT exec_script(script_ctx_t*,BOOL,function_t*,vbdisp_t*,DISPPARAMS*,VARIANT*) DECLSPEC_HIDDEN; void release_dynamic_var(dynamic_var_t*) DECLSPEC_HIDDEN; named_item_t *lookup_named_item(script_ctx_t*,const WCHAR*,unsigned) DECLSPEC_HIDDEN; +void release_named_item(named_item_t*) DECLSPEC_HIDDEN; void clear_ei(EXCEPINFO*) DECLSPEC_HIDDEN; HRESULT report_script_error(script_ctx_t*,const vbscode_t*,unsigned) DECLSPEC_HIDDEN; void detach_global_objects(script_ctx_t*) DECLSPEC_HIDDEN;
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com ---
Tests with 'me' are added in next patch because that requires a separate (unrelated) fix.
dlls/vbscript/tests/vbscript.c | 304 +++++++++++++++++++++++++++++++-- 1 file changed, 289 insertions(+), 15 deletions(-)
diff --git a/dlls/vbscript/tests/vbscript.c b/dlls/vbscript/tests/vbscript.c index 4e44758..a1788dc 100644 --- a/dlls/vbscript/tests/vbscript.c +++ b/dlls/vbscript/tests/vbscript.c @@ -93,6 +93,7 @@ DEFINE_EXPECT(OnStateChange_CONNECTED); DEFINE_EXPECT(OnStateChange_DISCONNECTED); DEFINE_EXPECT(OnStateChange_CLOSED); DEFINE_EXPECT(OnStateChange_INITIALIZED); +DEFINE_EXPECT(OnScriptError); DEFINE_EXPECT(OnEnterScript); DEFINE_EXPECT(OnLeaveScript); DEFINE_EXPECT(GetItemInfo_global); @@ -126,6 +127,19 @@ static void _test_state(unsigned line, IActiveScript *script, SCRIPTSTATE exstat ok_(__FILE__,line) (state == exstate, "state=%d, expected %d\n", state, exstate); }
+static const WCHAR *named_item_global_idents[] = +{ + L"testSub_global", + L"testExplicitVar_global", + L"testVar_global" +}; +static const WCHAR *named_item_context_idents[] = +{ + L"testSub", + L"testExplicitVar", + L"testVar" +}; + static HRESULT WINAPI Dispatch_QueryInterface(IDispatch *iface, REFIID riid, void **ppv) { if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IDispatch, riid)) { @@ -184,10 +198,23 @@ static HRESULT WINAPI Dispatch_GetTypeInfo(IDispatch *iface, UINT iTInfo, LCID l static HRESULT WINAPI Dispatch_GetIDsOfNames(IDispatch *iface, REFIID riid, LPOLESTR *names, UINT name_cnt, LCID lcid, DISPID *ids) { + unsigned i; + ok(name_cnt == 1, "name_cnt = %u\n", name_cnt); - ok(!wcscmp(names[0], L"testCall"), "names[0] = %s\n", wine_dbgstr_w(names[0])); *ids = 1; - return S_OK; + if (!wcscmp(names[0], L"testCall")) + return S_OK; + + for (i = 0; i < ARRAY_SIZE(named_item_global_idents); i++) + if (!wcscmp(names[0], named_item_global_idents[i])) + return DISP_E_UNKNOWNNAME; + for (i = 0; i < ARRAY_SIZE(named_item_context_idents); i++) + if (!wcscmp(names[0], named_item_context_idents[i])) + return DISP_E_UNKNOWNNAME; + + ok(!wcscmp(names[0], L"testClass_global") || !wcscmp(names[0], L"testClass") || !wcscmp(names[0], L"x"), + "names[0] = %s\n", wine_dbgstr_w(names[0])); + return DISP_E_UNKNOWNNAME; }
static HRESULT WINAPI Dispatch_Invoke(IDispatch *iface, DISPID id, REFIID riid, LCID lcid, WORD flags, @@ -337,8 +364,8 @@ static HRESULT WINAPI ActiveScriptSite_OnStateChange(IActiveScriptSite *iface, S
static HRESULT WINAPI ActiveScriptSite_OnScriptError(IActiveScriptSite *iface, IActiveScriptError *pscripterror) { - ok(0, "unexpected call\n"); - return E_NOTIMPL; + CHECK_EXPECT(OnScriptError); + return S_OK; }
static HRESULT WINAPI ActiveScriptSite_OnEnterScript(IActiveScriptSite *iface) @@ -460,14 +487,14 @@ static void test_safety(IActiveScript *script) IObjectSafety_Release(safety); }
-static IDispatchEx *get_script_dispatch(IActiveScript *script) +static IDispatchEx *get_script_dispatch(IActiveScript *script, const WCHAR *item_name) { IDispatchEx *dispex; IDispatch *disp; HRESULT hres;
disp = (void*)0xdeadbeef; - hres = IActiveScript_GetScriptDispatch(script, NULL, &disp); + hres = IActiveScript_GetScriptDispatch(script, item_name, &disp); ok(hres == S_OK, "GetScriptDispatch failed: %08x\n", hres); if(FAILED(hres)) return NULL; @@ -560,7 +587,7 @@ static void test_scriptdisp(void) ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres); CHECK_CALLED(GetLCID);
- script_disp2 = get_script_dispatch(vbscript); + script_disp2 = get_script_dispatch(vbscript, NULL);
test_state(vbscript, SCRIPTSTATE_UNINITIALIZED);
@@ -578,7 +605,7 @@ static void test_scriptdisp(void)
test_state(vbscript, SCRIPTSTATE_CONNECTED);
- script_disp = get_script_dispatch(vbscript); + script_disp = get_script_dispatch(vbscript, NULL); ok(script_disp == script_disp2, "script_disp != script_disp2\n"); IDispatchEx_Release(script_disp2);
@@ -705,7 +732,7 @@ static void test_code_persistence(void) ok(hr == S_OK, "ParseScriptText failed: %08x\n", hr);
/* Pending code does not add identifiers to the global scope */ - script_disp = get_script_dispatch(vbscript); + script_disp = get_script_dispatch(vbscript, NULL); id = 0; get_disp_id(script_disp, "x", DISP_E_UNKNOWNNAME, &id); ok(id == -1, "id = %d, expected -1\n", id); @@ -744,7 +771,7 @@ static void test_code_persistence(void) CHECK_CALLED_MULTI(OnLeaveScript, 2); test_state(vbscript, SCRIPTSTATE_CONNECTED);
- script_disp = get_script_dispatch(vbscript); + script_disp = get_script_dispatch(vbscript, NULL); id = 0; get_disp_id(script_disp, "x", DISP_E_UNKNOWNNAME, &id); ok(id == -1, "id = %d, expected -1\n", id); @@ -790,7 +817,7 @@ static void test_code_persistence(void) CHECK_CALLED(GetLCID); CHECK_CALLED(OnStateChange_INITIALIZED);
- script_disp = get_script_dispatch(vbscript); + script_disp = get_script_dispatch(vbscript, NULL); id = 0; get_disp_id(script_disp, "z", DISP_E_UNKNOWNNAME, &id); ok(id == -1, "id = %d, expected -1\n", id); @@ -806,7 +833,7 @@ static void test_code_persistence(void) CHECK_CALLED(OnLeaveScript); test_state(vbscript, SCRIPTSTATE_CONNECTED);
- script_disp = get_script_dispatch(vbscript); + script_disp = get_script_dispatch(vbscript, NULL); id = 0; get_disp_id(script_disp, "z", S_OK, &id); ok(id != -1, "id = -1\n"); @@ -869,7 +896,7 @@ static void test_code_persistence(void) CHECK_CALLED(OnStateChange_CONNECTED); test_state(vbscript, SCRIPTSTATE_CONNECTED);
- script_disp = get_script_dispatch(vbscript); + script_disp = get_script_dispatch(vbscript, NULL); id = 0; get_disp_id(script_disp, "y", DISP_E_UNKNOWNNAME, &id); ok(id == -1, "id = %d, expected -1\n", id); @@ -982,7 +1009,7 @@ static void test_script_typeinfo(void) "implicit = 10\n" "dim obj\nset obj = new C\n");
- script_disp = get_script_dispatch(vbscript); + script_disp = get_script_dispatch(vbscript, NULL); hr = IDispatchEx_QueryInterface(script_disp, &IID_ITypeInfo, (void**)&typeinfo); ok(hr == E_NOINTERFACE, "QueryInterface(IID_ITypeInfo) returned: %08x\n", hr); hr = IDispatchEx_GetTypeInfo(script_disp, 1, LOCALE_USER_DEFAULT, &typeinfo); @@ -1475,7 +1502,7 @@ static void test_vbscript_uninitializing(void)
test_state(script, SCRIPTSTATE_CONNECTED);
- dispex = get_script_dispatch(script); + dispex = get_script_dispatch(script, NULL); ok(dispex != NULL, "dispex == NULL\n"); if(dispex) IDispatchEx_Release(dispex); @@ -1731,10 +1758,28 @@ static void test_vbscript_initializing(void)
static void test_named_items(void) { + static const WCHAR *global_code_test[] = + { + L"testSub_global\n", + L"if testExplicitVar_global <> 10 then err.raise 500\n", + L"if testVar_global <> 5 then err.raise 500\n", + L"set x = new testClass_global\n" + }; + static const WCHAR *context_code_test[] = + { + L"testSub\n", + L"if testExplicitVar <> 42 then err.raise 500\n", + L"if testVar <> 99 then err.raise 500\n", + L"set x = new testClass\n" + }; + IDispatchEx *script_disp, *script_disp2; IActiveScriptParse *parse; IActiveScript *script; IDispatch *disp; + unsigned i; + DISPID id; ULONG ref; + BSTR bstr; HRESULT hres;
script = create_vbscript(); @@ -1748,6 +1793,8 @@ static void test_named_items(void) ok(hres == E_UNEXPECTED, "AddNamedItem returned: %08x\n", hres); hres = IActiveScript_AddNamedItem(script, L"globalItem", SCRIPTITEM_GLOBALMEMBERS); ok(hres == E_UNEXPECTED, "AddNamedItem returned: %08x\n", hres); + hres = IActiveScript_AddNamedItem(script, L"code context", SCRIPTITEM_CODEONLY); + ok(hres == E_UNEXPECTED, "AddNamedItem returned: %08x\n", hres);
SET_EXPECT(GetLCID); hres = IActiveScript_SetScriptSite(script, &ActiveScriptSite); @@ -1763,11 +1810,20 @@ static void test_named_items(void) ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres); hres = IActiveScript_AddNamedItem(script, L"visibleCodeItem", SCRIPTITEM_ISVISIBLE | SCRIPTITEM_CODEONLY); ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres); + hres = IActiveScript_AddNamedItem(script, L"code context", SCRIPTITEM_CODEONLY); + ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
ok(global_named_item_ref > 0, "global_named_item_ref = %u\n", global_named_item_ref); ok(visible_named_item_ref == 0, "visible_named_item_ref = %u\n", visible_named_item_ref); ok(visible_code_named_item_ref == 0, "visible_code_named_item_ref = %u\n", visible_code_named_item_ref);
+ hres = IActiveScript_GetScriptDispatch(script, L"no context", &disp); + ok(hres == E_INVALIDARG, "GetScriptDispatch returned: %08x\n", hres); + + script_disp = get_script_dispatch(script, NULL); + script_disp2 = get_script_dispatch(script, L"code CONTEXT"); + ok(script_disp != script_disp2, "get_script_dispatch returned same dispatch objects.\n"); + SET_EXPECT(OnStateChange_INITIALIZED); hres = IActiveScriptParse_InitNew(parse); ok(hres == S_OK, "InitNew failed: %08x\n", hres); @@ -1815,6 +1871,224 @@ static void test_named_items(void) parse_script(parse, "visibleItem.testCall\n"); CHECK_CALLED(testCall);
+ hres = IActiveScriptParse_ParseScriptText(parse, L"sub testSub\nend sub\n", L"no context", NULL, NULL, 0, 0, 0, NULL, NULL); + ok(hres == E_INVALIDARG, "ParseScriptText returned: %08x\n", hres); + SET_EXPECT(OnEnterScript); + SET_EXPECT(OnLeaveScript); + hres = IActiveScriptParse_ParseScriptText(parse, L"" + "sub testSub_global\nend sub\n" + "dim testExplicitVar_global\ntestExplicitVar_global = 10\n" + "testVar_global = 10\n" + "class testClass_global\nend class\n", + NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISPERSISTENT, NULL, NULL); + ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres); + CHECK_CALLED(OnEnterScript); + CHECK_CALLED(OnLeaveScript); + SET_EXPECT(OnEnterScript); + SET_EXPECT(OnLeaveScript); + hres = IActiveScriptParse_ParseScriptText(parse, L"" + "sub testSub\nend sub\n" + "dim testExplicitVar\ntestExplicitVar = 42\n" + "class testClass\nend class\n", + L"code context", NULL, NULL, 0, 0, 0, NULL, NULL); + ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres); + CHECK_CALLED(OnEnterScript); + CHECK_CALLED(OnLeaveScript); + SET_EXPECT(OnEnterScript); + SET_EXPECT(OnLeaveScript); + hres = IActiveScriptParse_ParseScriptText(parse, L"" + "testVar = 99\n" + "testVar_global = 5\n", + L"Code Context", NULL, NULL, 0, 0, SCRIPTTEXT_ISPERSISTENT, NULL, NULL); + ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres); + CHECK_CALLED(OnEnterScript); + CHECK_CALLED(OnLeaveScript); + + for (i = 0; i < ARRAY_SIZE(named_item_global_idents); i++) + { + bstr = SysAllocString(named_item_global_idents[i]); + id = 0; + hres = IDispatchEx_GetDispID(script_disp, bstr, 0, &id); + ok(hres == S_OK, "GetDispID(%s) returned %08x\n", wine_dbgstr_w(named_item_global_idents[i]), hres); + ok(id != -1, "[%s] id = -1\n", wine_dbgstr_w(named_item_global_idents[i])); + id = 0; + hres = IDispatchEx_GetDispID(script_disp2, bstr, 0, &id); + ok(hres == DISP_E_UNKNOWNNAME, "GetDispID(%s) returned %08x\n", wine_dbgstr_w(named_item_global_idents[i]), hres); + ok(id == -1, "[%s] id = %d, expected -1\n", wine_dbgstr_w(named_item_global_idents[i]), id); + SysFreeString(bstr); + } + for (i = 0; i < ARRAY_SIZE(named_item_context_idents); i++) + { + bstr = SysAllocString(named_item_context_idents[i]); + id = 0; + hres = IDispatchEx_GetDispID(script_disp, bstr, 0, &id); + ok(hres == DISP_E_UNKNOWNNAME, "GetDispID(%s) returned %08x\n", wine_dbgstr_w(named_item_context_idents[i]), hres); + ok(id == -1, "[%s] id = %d, expected -1\n", wine_dbgstr_w(named_item_context_idents[i]), id); + id = 0; + hres = IDispatchEx_GetDispID(script_disp2, bstr, 0, &id); + ok(hres == S_OK, "GetDispID(%s) returned %08x\n", wine_dbgstr_w(named_item_context_idents[i]), hres); + ok(id != -1, "[%s] id = -1\n", wine_dbgstr_w(named_item_context_idents[i])); + SysFreeString(bstr); + } + + for (i = 0; i < ARRAY_SIZE(global_code_test); i++) + { + SET_EXPECT(OnEnterScript); + SET_EXPECT(OnLeaveScript); + hres = IActiveScriptParse_ParseScriptText(parse, global_code_test[i], NULL, NULL, NULL, 0, 0, 0, NULL, NULL); + ok(hres == S_OK, "ParseScriptText(%s) failed: %08x\n", wine_dbgstr_w(global_code_test[i]), hres); + CHECK_CALLED(OnEnterScript); + CHECK_CALLED(OnLeaveScript); + SET_EXPECT(OnEnterScript); + SET_EXPECT(OnLeaveScript); + hres = IActiveScriptParse_ParseScriptText(parse, global_code_test[i], L"code context", NULL, NULL, 0, 0, 0, NULL, NULL); + ok(hres == S_OK, "ParseScriptText(%s) failed: %08x\n", wine_dbgstr_w(global_code_test[i]), hres); + CHECK_CALLED(OnEnterScript); + CHECK_CALLED(OnLeaveScript); + } + for (i = 0; i < ARRAY_SIZE(context_code_test); i++) + { + SET_EXPECT(OnScriptError); + SET_EXPECT(OnEnterScript); + SET_EXPECT(OnLeaveScript); + hres = IActiveScriptParse_ParseScriptText(parse, context_code_test[i], NULL, NULL, NULL, 0, 0, 0, NULL, NULL); + ok(FAILED(hres), "ParseScriptText(%s) returned: %08x\n", wine_dbgstr_w(context_code_test[i]), hres); + CHECK_CALLED(OnScriptError); + CHECK_CALLED(OnEnterScript); + CHECK_CALLED(OnLeaveScript); + SET_EXPECT(OnEnterScript); + SET_EXPECT(OnLeaveScript); + hres = IActiveScriptParse_ParseScriptText(parse, context_code_test[i], L"code context", NULL, NULL, 0, 0, 0, NULL, NULL); + ok(hres == S_OK, "ParseScriptText(%s) failed: %08x\n", wine_dbgstr_w(context_code_test[i]), hres); + CHECK_CALLED(OnEnterScript); + CHECK_CALLED(OnLeaveScript); + } + SET_EXPECT(OnScriptError); + SET_EXPECT(OnEnterScript); + SET_EXPECT(OnLeaveScript); + hres = IActiveScriptParse_ParseScriptText(parse, L"testSub_global = 10\n", L"code context", NULL, NULL, 0, 0, 0, NULL, NULL); + ok(FAILED(hres), "ParseScriptText returned: %08x\n", hres); + CHECK_CALLED(OnScriptError); + CHECK_CALLED(OnEnterScript); + CHECK_CALLED(OnLeaveScript); + + IDispatchEx_Release(script_disp2); + IDispatchEx_Release(script_disp); + + SET_EXPECT(OnStateChange_DISCONNECTED); + SET_EXPECT(OnStateChange_INITIALIZED); + SET_EXPECT(OnStateChange_UNINITIALIZED); + hres = IActiveScript_SetScriptState(script, SCRIPTSTATE_UNINITIALIZED); + ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_UNINITIALIZED) failed: %08x\n", hres); + CHECK_CALLED(OnStateChange_DISCONNECTED); + CHECK_CALLED(OnStateChange_INITIALIZED); + CHECK_CALLED(OnStateChange_UNINITIALIZED); + test_no_script_dispatch(script); + + ok(global_named_item_ref == 0, "global_named_item_ref = %u\n", global_named_item_ref); + ok(visible_named_item_ref == 0, "visible_named_item_ref = %u\n", visible_named_item_ref); + ok(visible_code_named_item_ref == 0, "visible_code_named_item_ref = %u\n", visible_code_named_item_ref); + + hres = IActiveScript_GetScriptDispatch(script, L"code context", &disp); + ok(hres == E_UNEXPECTED, "hres = %08x, expected E_UNEXPECTED\n", hres); + + SET_EXPECT(GetLCID); + SET_EXPECT(OnStateChange_INITIALIZED); + hres = IActiveScript_SetScriptSite(script, &ActiveScriptSite); + ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres); + CHECK_CALLED(GetLCID); + CHECK_CALLED(OnStateChange_INITIALIZED); + + hres = IActiveScript_AddNamedItem(script, L"code context", SCRIPTITEM_CODEONLY); + ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres); + + SET_EXPECT(OnStateChange_CONNECTED); + SET_EXPECT_MULTI(OnEnterScript, 2); + SET_EXPECT_MULTI(OnLeaveScript, 2); + hres = IActiveScript_SetScriptState(script, SCRIPTSTATE_CONNECTED); + ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_CONNECTED) failed: %08x\n", hres); + CHECK_CALLED(OnStateChange_CONNECTED); + CHECK_CALLED_MULTI(OnEnterScript, 2); + CHECK_CALLED_MULTI(OnLeaveScript, 2); + test_state(script, SCRIPTSTATE_CONNECTED); + + script_disp = get_script_dispatch(script, NULL); + for (i = 0; i < ARRAY_SIZE(named_item_global_idents); i++) + { + bstr = SysAllocString(named_item_global_idents[i]); + id = 0; + hres = IDispatchEx_GetDispID(script_disp, bstr, 0, &id); + ok(hres == S_OK, "GetDispID(%s) returned %08x\n", wine_dbgstr_w(named_item_global_idents[i]), hres); + ok(id != -1, "[%s] id = -1\n", wine_dbgstr_w(named_item_global_idents[i])); + SysFreeString(bstr); + } + for (i = 0; i < ARRAY_SIZE(named_item_context_idents); i++) + { + bstr = SysAllocString(named_item_context_idents[i]); + id = 0; + hres = IDispatchEx_GetDispID(script_disp, bstr, 0, &id); + ok(hres == DISP_E_UNKNOWNNAME, "GetDispID(%s) returned %08x\n", wine_dbgstr_w(named_item_context_idents[i]), hres); + ok(id == -1, "[%s] id = %d, expected -1\n", wine_dbgstr_w(named_item_context_idents[i]), id); + SysFreeString(bstr); + } + IDispatchEx_Release(script_disp); + + script_disp = get_script_dispatch(script, L"code context"); + for (i = 0; i < ARRAY_SIZE(named_item_global_idents); i++) + { + bstr = SysAllocString(named_item_global_idents[i]); + id = 0; + hres = IDispatchEx_GetDispID(script_disp, bstr, 0, &id); + ok(hres == DISP_E_UNKNOWNNAME, "GetDispID(%s) returned %08x\n", wine_dbgstr_w(named_item_global_idents[i]), hres); + ok(id == -1, "[%s] id = %d, expected -1\n", wine_dbgstr_w(named_item_global_idents[i]), id); + SysFreeString(bstr); + } + for (i = 0; i < ARRAY_SIZE(named_item_context_idents); i++) + { + bstr = SysAllocString(named_item_context_idents[i]); + id = 0; + hres = IDispatchEx_GetDispID(script_disp, bstr, 0, &id); + ok(hres == DISP_E_UNKNOWNNAME, "GetDispID(%s) returned %08x\n", wine_dbgstr_w(named_item_context_idents[i]), hres); + ok(id == -1, "[%s] id = %d, expected -1\n", wine_dbgstr_w(named_item_context_idents[i]), id); + SysFreeString(bstr); + } + IDispatchEx_Release(script_disp); + + for (i = 0; i < ARRAY_SIZE(global_code_test); i++) + { + SET_EXPECT(OnEnterScript); + SET_EXPECT(OnLeaveScript); + hres = IActiveScriptParse_ParseScriptText(parse, global_code_test[i], NULL, NULL, NULL, 0, 0, 0, NULL, NULL); + ok(hres == S_OK, "ParseScriptText(%s) failed: %08x\n", wine_dbgstr_w(global_code_test[i]), hres); + CHECK_CALLED(OnEnterScript); + CHECK_CALLED(OnLeaveScript); + SET_EXPECT(OnEnterScript); + SET_EXPECT(OnLeaveScript); + hres = IActiveScriptParse_ParseScriptText(parse, global_code_test[i], L"code context", NULL, NULL, 0, 0, 0, NULL, NULL); + ok(hres == S_OK, "ParseScriptText(%s) failed: %08x\n", wine_dbgstr_w(global_code_test[i]), hres); + CHECK_CALLED(OnEnterScript); + CHECK_CALLED(OnLeaveScript); + } + for (i = 0; i < ARRAY_SIZE(context_code_test); i++) + { + SET_EXPECT(OnScriptError); + SET_EXPECT(OnEnterScript); + SET_EXPECT(OnLeaveScript); + hres = IActiveScriptParse_ParseScriptText(parse, context_code_test[i], NULL, NULL, NULL, 0, 0, 0, NULL, NULL); + ok(FAILED(hres), "ParseScriptText(%s) returned: %08x\n", wine_dbgstr_w(context_code_test[i]), hres); + CHECK_CALLED(OnScriptError); + CHECK_CALLED(OnEnterScript); + CHECK_CALLED(OnLeaveScript); + SET_EXPECT(OnScriptError); + SET_EXPECT(OnEnterScript); + SET_EXPECT(OnLeaveScript); + hres = IActiveScriptParse_ParseScriptText(parse, context_code_test[i], L"code context", NULL, NULL, 0, 0, 0, NULL, NULL); + ok(FAILED(hres), "ParseScriptText(%s) returned: %08x\n", wine_dbgstr_w(context_code_test[i]), hres); + CHECK_CALLED(OnScriptError); + CHECK_CALLED(OnEnterScript); + CHECK_CALLED(OnLeaveScript); + } + SET_EXPECT(OnStateChange_DISCONNECTED); SET_EXPECT(OnStateChange_INITIALIZED); SET_EXPECT(OnStateChange_CLOSED);
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com ---
This matches Windows behavior and allows us to test 'me' with named item script dispatches too.
dlls/vbscript/interp.c | 4 +--- dlls/vbscript/tests/run.c | 13 +++++++++++++ dlls/vbscript/tests/vbscript.c | 20 ++++++++++++++++++++ 3 files changed, 34 insertions(+), 3 deletions(-)
diff --git a/dlls/vbscript/interp.c b/dlls/vbscript/interp.c index 4f5e463..b0046cb 100644 --- a/dlls/vbscript/interp.c +++ b/dlls/vbscript/interp.c @@ -1494,9 +1494,7 @@ static HRESULT interp_retval(exec_ctx_t *ctx)
TRACE("\n");
- hres = stack_pop_val(ctx, &val); - if(FAILED(hres)) - return hres; + stack_pop_deref(ctx, &val);
if(val.owned) { VariantClear(&ctx->ret_val); diff --git a/dlls/vbscript/tests/run.c b/dlls/vbscript/tests/run.c index 8acf220..474fe1d 100644 --- a/dlls/vbscript/tests/run.c +++ b/dlls/vbscript/tests/run.c @@ -2685,6 +2685,7 @@ static void test_isexpression(void) { IActiveScriptParse *parser; IActiveScript *engine; + IDispatch *disp; SCRIPTSTATE ss; HRESULT hres; VARIANT var; @@ -2747,6 +2748,18 @@ static void test_isexpression(void) VariantClear(&var); SysFreeString(str);
+ /* Without a global host or named item context, "me" returns the script dispatch */ + hres = IActiveScript_GetScriptDispatch(engine, NULL, &disp); + ok(hres == S_OK, "GetScriptDispatch failed: %08x\n", hres); + str = a2bstr("me"); + hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION, &var, NULL); + ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres); + ok(V_VT(&var) == VT_DISPATCH, "Expected VT_DISPATCH, got %s\n", vt2a(&var)); + ok(V_DISPATCH(&var) == disp, "Wrong dispatch returned for 'me'\n"); + IDispatch_Release(disp); + VariantClear(&var); + SysFreeString(str); + /* An expression can also refer to a variable, function, class, etc previously set */ V_VT(&var) = VT_I2; str = a2bstr("If True Then foo = 42 Else foo = 0\n"); diff --git a/dlls/vbscript/tests/vbscript.c b/dlls/vbscript/tests/vbscript.c index a1788dc..16c126e 100644 --- a/dlls/vbscript/tests/vbscript.c +++ b/dlls/vbscript/tests/vbscript.c @@ -1776,6 +1776,7 @@ static void test_named_items(void) IActiveScriptParse *parse; IActiveScript *script; IDispatch *disp; + VARIANT var; unsigned i; DISPID id; ULONG ref; @@ -1972,6 +1973,25 @@ static void test_named_items(void) CHECK_CALLED(OnEnterScript); CHECK_CALLED(OnLeaveScript);
+ SET_EXPECT(OnEnterScript); + SET_EXPECT(OnLeaveScript); + hres = IActiveScriptParse_ParseScriptText(parse, L"me", NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION, &var, NULL); + ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres); + ok(V_VT(&var) == VT_DISPATCH && V_DISPATCH(&var) == &global_named_item, + "Unexpected 'me': V_VT = %d, V_DISPATCH = %p\n", V_VT(&var), V_DISPATCH(&var)); + VariantClear(&var); + CHECK_CALLED(OnEnterScript); + CHECK_CALLED(OnLeaveScript); + SET_EXPECT(OnEnterScript); + SET_EXPECT(OnLeaveScript); + hres = IActiveScriptParse_ParseScriptText(parse, L"me", L"code context", NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION, &var, NULL); + ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres); + ok(V_VT(&var) == VT_DISPATCH && V_DISPATCH(&var) == (IDispatch*)script_disp2, + "Unexpected 'me': V_VT = %d, V_DISPATCH = %p\n", V_VT(&var), V_DISPATCH(&var)); + VariantClear(&var); + CHECK_CALLED(OnEnterScript); + CHECK_CALLED(OnLeaveScript); + IDispatchEx_Release(script_disp2); IDispatchEx_Release(script_disp);