From 7e109410836f18a67418209a4b73dcdb513532f8 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Fri, 16 Mar 2018 23:34:52 +0100 Subject: [PATCH] vbscript: Added support for script context in ParseScriptText. Signed-off-by: Jacek Caban Signed-off-by: Alexandre Julliard --- dlls/vbscript/compile.c | 15 +++---------- dlls/vbscript/interp.c | 10 +++++++++ dlls/vbscript/tests/run.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++ dlls/vbscript/vbscript.c | 12 +++++++++++ dlls/vbscript/vbscript.h | 1 + 5 files changed, 80 insertions(+), 12 deletions(-) diff --git a/dlls/vbscript/compile.c b/dlls/vbscript/compile.c index c8189d6d969..302804f4c28 100644 --- a/dlls/vbscript/compile.c +++ b/dlls/vbscript/compile.c @@ -1746,6 +1746,8 @@ void release_vbscode(vbscode_t *code) for(i=0; i < code->bstr_cnt; i++) SysFreeString(code->bstr_pool[i]); + if(code->context) + IDispatch_Release(code->context); heap_pool_free(&code->heap); heap_free(code->bstr_pool); @@ -1758,7 +1760,7 @@ static vbscode_t *alloc_vbscode(compile_ctx_t *ctx, const WCHAR *source) { vbscode_t *ret; - ret = heap_alloc(sizeof(*ret)); + ret = heap_alloc_zero(sizeof(*ret)); if(!ret) return NULL; @@ -1780,19 +1782,8 @@ static vbscode_t *alloc_vbscode(compile_ctx_t *ctx, const WCHAR *source) ret->option_explicit = ctx->parser.option_explicit; - ret->bstr_pool = NULL; - ret->bstr_pool_size = 0; - ret->bstr_cnt = 0; - ret->pending_exec = FALSE; - ret->main_code.type = FUNC_GLOBAL; - ret->main_code.name = NULL; ret->main_code.code_ctx = ret; - ret->main_code.vars = NULL; - ret->main_code.var_cnt = 0; - ret->main_code.array_cnt = 0; - ret->main_code.arg_cnt = 0; - ret->main_code.args = NULL; list_init(&ret->entry); return ret; diff --git a/dlls/vbscript/interp.c b/dlls/vbscript/interp.c index 4f746c74301..b46bd01c0fc 100644 --- a/dlls/vbscript/interp.c +++ b/dlls/vbscript/interp.c @@ -154,6 +154,16 @@ static HRESULT lookup_identifier(exec_ctx_t *ctx, BSTR name, vbdisp_invoke_type_ } } + if(ctx->func->code_ctx->context) { + hres = disp_get_id(ctx->func->code_ctx->context, name, invoke_type, TRUE, &id); + if(SUCCEEDED(hres)) { + ref->type = REF_DISP; + ref->u.d.disp = ctx->func->code_ctx->context; + ref->u.d.id = id; + return S_OK; + } + } + if(ctx->func->type != FUNC_GLOBAL && lookup_dynamic_vars(ctx->script->global_vars, name, ref)) return S_OK; diff --git a/dlls/vbscript/tests/run.c b/dlls/vbscript/tests/run.c index ee811c6e5b2..9172add450f 100644 --- a/dlls/vbscript/tests/run.c +++ b/dlls/vbscript/tests/run.c @@ -1804,6 +1804,59 @@ static HRESULT parse_script_ar(const char *src) return hres; } +static void test_parse_context(void) +{ + IActiveScriptParse *parser; + IActiveScript *engine; + BSTR str; + HRESULT hres; + + static const WCHAR xW[] = {'x',0}; + static const WCHAR yW[] = {'y',0}; + + engine = create_and_init_script(0); + if(!engine) + return; + + hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser); + ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres); + + /* unknown identifier context is not a valid argument */ + str = a2bstr("Call reportSuccess()\n"); + hres = IActiveScriptParse_ParseScriptText(parser, str, yW, NULL, NULL, 0, 0, 0, NULL, NULL); + ok(hres == E_INVALIDARG, "ParseScriptText failed: %08x\n", hres); + SysFreeString(str); + + str = a2bstr("class Cl\n" + " Public Sub ClMethod\n" + " Call reportSuccess()\n" + " End Sub\n" + "End Class\n" + "Dim x\n" + "set x = new Cl\n"); + hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, 0, NULL, NULL); + ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres); + SysFreeString(str); + + /* known global variable is not a valid context */ + str = a2bstr("Call reportSuccess()\n"); + hres = IActiveScriptParse_ParseScriptText(parser, str, xW, NULL, NULL, 0, 0, 0, NULL, NULL); + ok(hres == E_INVALIDARG, "ParseScriptText failed: %08x\n", hres); + SysFreeString(str); + + SET_EXPECT(global_success_d); + SET_EXPECT(global_success_i); + str = a2bstr("Call reportSuccess()\n"); + hres = IActiveScriptParse_ParseScriptText(parser, str, testW, NULL, NULL, 0, 0, 0, NULL, NULL); + ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres); + SysFreeString(str); + CHECK_CALLED(global_success_d); + CHECK_CALLED(global_success_i); + + IActiveScriptParse_Release(parser); + close_script(engine); +} + static void parse_script_a(const char *src) { parse_script_af(SCRIPTITEM_GLOBALMEMBERS, src); @@ -2334,6 +2387,7 @@ static void run_tests(void) test_procedures(); test_gc(); test_msgbox(); + test_parse_context(); } static BOOL check_vbscript(void) diff --git a/dlls/vbscript/vbscript.c b/dlls/vbscript/vbscript.c index 054d53bdfc6..b97cf5acfbe 100644 --- a/dlls/vbscript/vbscript.c +++ b/dlls/vbscript/vbscript.c @@ -636,6 +636,7 @@ static HRESULT WINAPI VBScriptParse_ParseScriptText(IActiveScriptParse *iface, DWORD dwFlags, VARIANT *pvarResult, EXCEPINFO *pexcepinfo) { VBScript *This = impl_from_IActiveScriptParse(iface); + IDispatch *context = NULL; vbscode_t *code; HRESULT hres; @@ -646,10 +647,21 @@ static HRESULT WINAPI VBScriptParse_ParseScriptText(IActiveScriptParse *iface, if(This->thread_id != GetCurrentThreadId() || This->state == SCRIPTSTATE_CLOSED) return E_UNEXPECTED; + if(pstrItemName) { + context = lookup_named_item(This->ctx, pstrItemName, 0); + if(!context) { + WARN("Inknown context %s\n", debugstr_w(pstrItemName)); + return E_INVALIDARG; + } + } + hres = compile_script(This->ctx, pstrCode, pstrDelimiter, &code); if(FAILED(hres)) return hres; + if(context) + IDispatch_AddRef(code->context = context); + if(!is_started(This)) { code->pending_exec = TRUE; return S_OK; diff --git a/dlls/vbscript/vbscript.h b/dlls/vbscript/vbscript.h index 42b3cd198b3..58777626854 100644 --- a/dlls/vbscript/vbscript.h +++ b/dlls/vbscript/vbscript.h @@ -342,6 +342,7 @@ struct _vbscode_t { BOOL pending_exec; function_t main_code; + IDispatch *context; BSTR *bstr_pool; unsigned bstr_pool_size; -- 2.11.4.GIT