From: Jacek Caban Subject: jscript: Don't allow function execution if script engine is not in started state. Message-Id: <54B40ABA.9040905@codeweavers.com> Date: Mon, 12 Jan 2015 18:56:10 +0100 --- dlls/jscript/function.c | 5 +++ dlls/jscript/jscript.c | 9 +----- dlls/jscript/jscript.h | 7 ++++ dlls/jscript/tests/run.c | 84 ++++++++++++++++++++++++++++++++++++++++++------ 4 files changed, 87 insertions(+), 18 deletions(-) diff --git a/dlls/jscript/function.c b/dlls/jscript/function.c index 276c4f9..ccdac05 100644 --- a/dlls/jscript/function.c +++ b/dlls/jscript/function.c @@ -205,6 +205,11 @@ static HRESULT invoke_source(script_ctx_t *ctx, FunctionInstance *function, IDis scope_chain_t *scope; HRESULT hres; + if(!is_script_started(ctx)) { + WARN("Script engine state does not allow running code.\n"); + return E_UNEXPECTED; + } + if(!function->func_code) { FIXME("no source\n"); return E_FAIL; diff --git a/dlls/jscript/jscript.c b/dlls/jscript/jscript.c index 4a32c4d..bfc130c 100644 --- a/dlls/jscript/jscript.c +++ b/dlls/jscript/jscript.c @@ -91,13 +91,6 @@ static void change_state(JScript *This, SCRIPTSTATE state) IActiveScriptSite_OnStateChange(This->site, state); } -static inline BOOL is_started(script_ctx_t *ctx) -{ - return ctx->state == SCRIPTSTATE_STARTED - || ctx->state == SCRIPTSTATE_CONNECTED - || ctx->state == SCRIPTSTATE_DISCONNECTED; -} - static HRESULT exec_global_code(JScript *This, bytecode_t *code) { exec_ctx_t *exec_ctx; @@ -795,7 +788,7 @@ static HRESULT WINAPI JScriptParse_ParseScriptText(IActiveScriptParse *iface, return hres; } - if(!is_started(This->ctx)) { + if(!is_script_started(This->ctx)) { if(This->queue_tail) This->queue_tail = This->queue_tail->next = code; else diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h index 1e306b6..b0b4674 100644 --- a/dlls/jscript/jscript.h +++ b/dlls/jscript/jscript.h @@ -421,6 +421,13 @@ static inline void script_addref(script_ctx_t *ctx) ctx->ref++; } +static inline BOOL is_script_started(script_ctx_t *ctx) +{ + return ctx->state == SCRIPTSTATE_STARTED + || ctx->state == SCRIPTSTATE_CONNECTED + || ctx->state == SCRIPTSTATE_DISCONNECTED; +} + HRESULT init_global(script_ctx_t*) DECLSPEC_HIDDEN; HRESULT init_function_constr(script_ctx_t*,jsdisp_t*) DECLSPEC_HIDDEN; HRESULT create_object_prototype(script_ctx_t*,jsdisp_t**) DECLSPEC_HIDDEN; diff --git a/dlls/jscript/tests/run.c b/dlls/jscript/tests/run.c index c0a62b8..ad2fa83 100644 --- a/dlls/jscript/tests/run.c +++ b/dlls/jscript/tests/run.c @@ -1908,7 +1908,7 @@ static void test_isvisible(BOOL global_members) IActiveScriptParse_Release(parser); } -static HRESULT parse_script_expr(const char *expr, VARIANT *res) +static HRESULT parse_script_expr(const char *expr, VARIANT *res, IActiveScript **engine_ret) { IActiveScriptParse *parser; IActiveScript *engine; @@ -1939,9 +1939,14 @@ static HRESULT parse_script_expr(const char *expr, VARIANT *res) hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION, res, NULL); SysFreeString(str); - IActiveScript_Release(engine); IActiveScriptParse_Release(parser); + if(engine_ret) { + *engine_ret = engine; + }else { + IActiveScript_Close(engine); + IActiveScript_Release(engine); + } return hres; } @@ -1952,7 +1957,7 @@ static void test_default_value(void) VARIANT v; HRESULT hres; - hres = parse_script_expr("new Date()", &v); + hres = parse_script_expr("new Date()", &v, NULL); ok(hres == S_OK, "parse_script_expr failed: %08x\n", hres); ok(V_VT(&v) == VT_DISPATCH, "V_VT(v) = %d\n", V_VT(&v)); disp = V_DISPATCH(&v); @@ -1976,38 +1981,38 @@ static void test_script_exprs(void) testing_expr = TRUE; - hres = parse_script_expr("true", &v); + hres = parse_script_expr("true", &v, NULL); ok(hres == S_OK, "parse_script_expr failed: %08x\n", hres); ok(V_VT(&v) == VT_BOOL, "V_VT(v) = %d\n", V_VT(&v)); ok(V_BOOL(&v) == VARIANT_TRUE, "V_BOOL(v) = %x\n", V_BOOL(&v)); - hres = parse_script_expr("false, true", &v); + hres = parse_script_expr("false, true", &v, NULL); ok(hres == S_OK, "parse_script_expr failed: %08x\n", hres); ok(V_VT(&v) == VT_BOOL, "V_VT(v) = %d\n", V_VT(&v)); ok(V_BOOL(&v) == VARIANT_TRUE, "V_BOOL(v) = %x\n", V_BOOL(&v)); SET_EXPECT(global_success_d); SET_EXPECT(global_success_i); - hres = parse_script_expr("reportSuccess(); true", &v); + hres = parse_script_expr("reportSuccess(); true", &v, NULL); ok(hres == S_OK, "parse_script_expr failed: %08x\n", hres); ok(V_VT(&v) == VT_BOOL, "V_VT(v) = %d\n", V_VT(&v)); ok(V_BOOL(&v) == VARIANT_TRUE, "V_BOOL(v) = %x\n", V_BOOL(&v)); CHECK_CALLED(global_success_d); CHECK_CALLED(global_success_i); - hres = parse_script_expr("if(false) true", &v); + hres = parse_script_expr("if(false) true", &v, NULL); ok(hres == S_OK, "parse_script_expr failed: %08x\n", hres); ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v)); - hres = parse_script_expr("return testPropGet", &v); + hres = parse_script_expr("return testPropGet", &v, NULL); ok(hres == 0x800a03fa, "parse_script_expr failed: %08x\n", hres); - hres = parse_script_expr("reportSuccess(); return true", &v); + hres = parse_script_expr("reportSuccess(); return true", &v, NULL); ok(hres == 0x800a03fa, "parse_script_expr failed: %08x\n", hres); SET_EXPECT(global_success_d); SET_EXPECT(global_success_i); - hres = parse_script_expr("reportSuccess(); true", NULL); + hres = parse_script_expr("reportSuccess(); true", NULL, NULL); ok(hres == S_OK, "parse_script_expr failed: %08x\n", hres); CHECK_CALLED(global_success_d); CHECK_CALLED(global_success_i); @@ -2017,6 +2022,64 @@ static void test_script_exprs(void) testing_expr = FALSE; } +static void test_invokeex(void) +{ + DISPID func_id, prop_id; + DISPPARAMS dp = {NULL}; + IActiveScript *script; + IDispatchEx *dispex; + VARIANT v; + BSTR str; + HRESULT hres; + + hres = parse_script_expr("var o = {func: function() {return 3;}, prop: 6}; o", &v, &script); + ok(hres == S_OK, "parse_script_expr failed: %08x\n", hres); + ok(V_VT(&v) == VT_DISPATCH, "V_VT(v) = %d\n", V_VT(&v)); + + hres = IDispatch_QueryInterface(V_DISPATCH(&v), &IID_IDispatchEx, (void**)&dispex); + ok(hres == S_OK, "Could not get IDispatchEx iface: %08x\n", hres); + VariantClear(&v); + + str = a2bstr("func"); + hres = IDispatchEx_GetDispID(dispex, str, 0, &func_id); + SysFreeString(str); + ok(hres == S_OK, "GetDispID failed: %08x\n", hres); + + str = a2bstr("prop"); + hres = IDispatchEx_GetDispID(dispex, str, 0, &prop_id); + SysFreeString(str); + ok(hres == S_OK, "GetDispID failed: %08x\n", hres); + + hres = IDispatchEx_InvokeEx(dispex, func_id, 0, DISPATCH_METHOD, &dp, &v, NULL, NULL); + ok(hres == S_OK, "InvokeEx failed: %08x\n", hres); + ok(V_VT(&v) == VT_I4, "V_VT(v) = %d\n", V_VT(&v)); + ok(V_I4(&v) == 3, "V_I4(v) = %d\n", V_I4(&v)); + + hres = IDispatchEx_InvokeEx(dispex, prop_id, 0, DISPATCH_PROPERTYGET, &dp, &v, NULL, NULL); + ok(hres == S_OK, "InvokeEx failed: %08x\n", hres); + ok(V_VT(&v) == VT_I4, "V_VT(v) = %d\n", V_VT(&v)); + ok(V_I4(&v) == 6, "V_I4(v) = %d\n", V_I4(&v)); + + hres = IActiveScript_SetScriptState(script, SCRIPTSTATE_UNINITIALIZED); + ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres); + + str = a2bstr("func"); + hres = IDispatchEx_GetDispID(dispex, str, 0, &func_id); + SysFreeString(str); + ok(hres == S_OK, "GetDispID failed: %08x\n", hres); + + hres = IDispatchEx_InvokeEx(dispex, func_id, 0, DISPATCH_METHOD, &dp, &v, NULL, NULL); + ok(hres == E_UNEXPECTED, "InvokeEx failed: %08x\n", hres); + + hres = IDispatchEx_InvokeEx(dispex, prop_id, 0, DISPATCH_PROPERTYGET, &dp, &v, NULL, NULL); + ok(hres == S_OK, "InvokeEx failed: %08x\n", hres); + ok(V_VT(&v) == VT_I4, "V_VT(v) = %d\n", V_VT(&v)); + ok(V_I4(&v) == 6, "V_I4(v) = %d\n", V_I4(&v)); + + IDispatchEx_Release(dispex); + IActiveScript_Release(script); +} + struct bom_test { WCHAR str[1024]; @@ -2335,6 +2398,7 @@ static BOOL run_tests(void) ok(hres != S_OK, "ParseScriptText have not failed\n"); test_script_exprs(); + test_invokeex(); parse_script_with_error_a( "?",