Instead of only interpreted functions. Property retrievals or setters are allowed though, as long as they are not accessors.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/dispex.c | 3 ++ dlls/jscript/function.c | 10 ++-- dlls/jscript/tests/run.c | 111 ++++++++++++++++++++++++++++++++++++--- 3 files changed, 111 insertions(+), 13 deletions(-)
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index df829b7..298f7e1 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -1971,6 +1971,9 @@ HRESULT jsdisp_call_value(jsdisp_t *jsfunc, IDispatch *jsthis, WORD flags, unsig return JS_E_FUNCTION_EXPECTED; }
+ if(jsfunc->ctx->state == SCRIPTSTATE_UNINITIALIZED || jsfunc->ctx->state == SCRIPTSTATE_CLOSED) + return E_UNEXPECTED; + flags &= ~DISPATCH_JSCRIPT_INTERNAL_MASK; hres = jsfunc->builtin_info->call(jsfunc->ctx, jsthis ? jsval_disp(jsthis) : jsval_null(), flags, argc, argv, r); } diff --git a/dlls/jscript/function.c b/dlls/jscript/function.c index 18465e5..984eebf 100644 --- a/dlls/jscript/function.c +++ b/dlls/jscript/function.c @@ -257,6 +257,11 @@ HRESULT Function_invoke(jsdisp_t *func_this, IDispatch *jsthis, WORD flags, unsi assert(is_class(func_this, JSCLASS_FUNCTION)); function = function_from_jsdisp(func_this);
+ if(function->dispex.ctx->state == SCRIPTSTATE_UNINITIALIZED || function->dispex.ctx->state == SCRIPTSTATE_CLOSED) { + WARN("Script engine state does not allow running code.\n"); + return E_UNEXPECTED; + } + if(jsthis) vthis = jsval_disp(jsthis); else @@ -725,11 +730,6 @@ static HRESULT InterpretedFunction_call(script_ctx_t *ctx, FunctionInstance *fun
TRACE("%p\n", function);
- if(ctx->state == SCRIPTSTATE_UNINITIALIZED || ctx->state == SCRIPTSTATE_CLOSED) { - WARN("Script engine state does not allow running code.\n"); - return E_UNEXPECTED; - } - if(flags & DISPATCH_CONSTRUCT) { hres = create_object(ctx, &function->function.dispex, &new_obj); if(FAILED(hres)) diff --git a/dlls/jscript/tests/run.c b/dlls/jscript/tests/run.c index 94dc2e1..f7ad1fe 100644 --- a/dlls/jscript/tests/run.c +++ b/dlls/jscript/tests/run.c @@ -2914,13 +2914,20 @@ static void test_default_value(void)
V_VT(&v) = VT_EMPTY; hres = IDispatch_Invoke(disp, DISPID_VALUE, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dp, &v, NULL, NULL); - ok(hres == S_OK || broken(hres == 0x8000ffff), "Invoke failed: %08lx\n", hres); - if(hres == S_OK) - { - ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v)); - } + ok(hres == E_UNEXPECTED, "Invoke failed: %08lx\n", hres); + + hres = parse_script_expr(L"new Date()", &v, &script); + ok(hres == S_OK, "parse_script_expr failed: %08lx\n", hres); + ok(V_VT(&v) == VT_DISPATCH, "V_VT(v) = %d\n", V_VT(&v)); + disp = V_DISPATCH(&v); + + V_VT(&v) = VT_EMPTY; + hres = IDispatch_Invoke(disp, DISPID_VALUE, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dp, &v, NULL, NULL); + ok(hres == S_OK, "Invoke failed: %08lx\n", hres); + ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v)); VariantClear(&v); IDispatch_Release(disp); + close_script(script);
hres = parse_script_expr(L"var arr = [5]; arr.toString = function() {return "foo";}; arr.valueOf = function() {return 42;}; arr", &v, &script); ok(hres == S_OK, "parse_script_expr failed: %08lx\n", hres); @@ -3149,15 +3156,15 @@ static void test_script_exprs(void)
static void test_invokeex(void) { - DISPID func_id, prop_id; - DISPPARAMS dp = {NULL}; + DISPPARAMS dp = {NULL}, dp_max = {NULL}; + DISPID func_id, max_id, prop_id; IActiveScript *script; IDispatchEx *dispex; VARIANT v, arg; BSTR str; HRESULT hres;
- hres = parse_script_expr(L"var o = {func: function() {return 3;}, prop: 6}; o", &v, &script); + hres = parse_script_expr(L"var o = {func: function() {return 3;}, max: Math.max, prop: 6}; o", &v, &script); ok(hres == S_OK, "parse_script_expr failed: %08lx\n", hres); ok(V_VT(&v) == VT_DISPATCH, "V_VT(v) = %d\n", V_VT(&v));
@@ -3170,16 +3177,31 @@ static void test_invokeex(void) SysFreeString(str); ok(hres == S_OK, "GetDispID failed: %08lx\n", hres);
+ str = SysAllocString(L"max"); + hres = IDispatchEx_GetDispID(dispex, str, 0, &max_id); + SysFreeString(str); + ok(hres == S_OK, "GetDispID failed: %08lx\n", hres); + str = SysAllocString(L"prop"); hres = IDispatchEx_GetDispID(dispex, str, 0, &prop_id); SysFreeString(str); ok(hres == S_OK, "GetDispID failed: %08lx\n", hres);
+ dp_max.rgvarg = &arg; + dp_max.cArgs = 1; + V_VT(&arg) = VT_I4; + V_I4(&arg) = 42; + hres = IDispatchEx_InvokeEx(dispex, func_id, 0, DISPATCH_METHOD, &dp, &v, NULL, NULL); ok(hres == S_OK, "InvokeEx failed: %08lx\n", hres); ok(V_VT(&v) == VT_I4, "V_VT(v) = %d\n", V_VT(&v)); ok(V_I4(&v) == 3, "V_I4(v) = %ld\n", V_I4(&v));
+ hres = IDispatchEx_InvokeEx(dispex, max_id, 0, DISPATCH_METHOD, &dp_max, &v, NULL, NULL); + ok(hres == S_OK, "InvokeEx failed: %08lx\n", hres); + ok(V_VT(&v) == VT_I4, "V_VT(v) = %d\n", V_VT(&v)); + ok(V_I4(&v) == 42, "V_I4(v) = %ld\n", V_I4(&v)); + hres = IDispatchEx_InvokeEx(dispex, prop_id, 0, DISPATCH_PROPERTYGET, &dp, &v, NULL, NULL); ok(hres == S_OK, "InvokeEx failed: %08lx\n", hres); ok(V_VT(&v) == VT_I4, "V_VT(v) = %d\n", V_VT(&v)); @@ -3193,9 +3215,23 @@ static void test_invokeex(void) SysFreeString(str); ok(hres == S_OK, "GetDispID failed: %08lx\n", hres);
+ V_VT(&v) = VT_EMPTY; hres = IDispatchEx_InvokeEx(dispex, func_id, 0, DISPATCH_METHOD, &dp, &v, NULL, NULL); ok(hres == E_UNEXPECTED || broken(hres == 0x800a1393), "InvokeEx failed: %08lx\n", hres);
+ V_VT(&v) = VT_EMPTY; + hres = IDispatchEx_InvokeEx(dispex, max_id, 0, DISPATCH_METHOD, &dp_max, &v, NULL, NULL); + ok(hres == E_UNEXPECTED || broken(hres == 0x800a1393), "InvokeEx failed: %08lx\n", hres); + + V_VT(&v) = VT_EMPTY; + hres = IDispatchEx_InvokeEx(dispex, prop_id, 0, DISPATCH_PROPERTYGET, &dp, &v, NULL, NULL); + ok(hres == S_OK, "InvokeEx failed: %08lx\n", hres); + ok(V_VT(&v) == VT_I4, "V_VT(v) = %d\n", V_VT(&v)); + ok(V_I4(&v) == 6, "V_I4(v) = %ld\n", V_I4(&v)); + + IActiveScript_Close(script); + + V_VT(&v) = VT_EMPTY; hres = IDispatchEx_InvokeEx(dispex, prop_id, 0, DISPATCH_PROPERTYGET, &dp, &v, NULL, NULL); ok(hres == S_OK, "InvokeEx failed: %08lx\n", hres); ok(V_VT(&v) == VT_I4, "V_VT(v) = %d\n", V_VT(&v)); @@ -3204,6 +3240,65 @@ static void test_invokeex(void) IDispatchEx_Release(dispex); IActiveScript_Release(script);
+ hres = parse_script_expr(L"Math.max", &v, &script); + ok(hres == S_OK, "parse_script_expr failed: %08lx\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: %08lx\n", hres); + VariantClear(&v); + + str = SysAllocString(L"call"); + hres = IDispatchEx_GetDispID(dispex, str, 0, &func_id); + SysFreeString(str); + ok(hres == S_OK, "GetDispID failed: %08lx\n", hres); + + hres = IActiveScript_SetScriptState(script, SCRIPTSTATE_UNINITIALIZED); + ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08lx\n", hres); + + str = SysAllocString(L"call"); + hres = IDispatchEx_GetDispID(dispex, str, 0, &func_id); + SysFreeString(str); + ok(hres == S_OK, "GetDispID failed: %08lx\n", hres); + + str = SysAllocString(L"length"); + hres = IDispatchEx_GetDispID(dispex, str, 0, &prop_id); + SysFreeString(str); + ok(hres == S_OK, "GetDispID failed: %08lx\n", hres); + + hres = IDispatchEx_InvokeEx(dispex, func_id, 0, DISPATCH_PROPERTYGET, &dp, &v, NULL, NULL); + ok(hres == S_OK, "InvokeEx failed: %08lx\n", hres); + ok(V_VT(&v) == VT_DISPATCH, "V_VT(v) = %d\n", V_VT(&v)); + VariantClear(&v); + + hres = IDispatchEx_InvokeEx(dispex, prop_id, 0, DISPATCH_PROPERTYGET, &dp, &v, NULL, NULL); + ok(hres == S_OK, "InvokeEx failed: %08lx\n", hres); + ok(V_VT(&v) == VT_I4, "V_VT(v) = %d\n", V_VT(&v)); + ok(V_I4(&v) == 2, "V_I4(v) = %ld\n", V_I4(&v)); + + IDispatchEx_Release(dispex); + IActiveScript_Release(script); + + hres = parse_script_expr(L"Math.max", &v, &script); + ok(hres == S_OK, "parse_script_expr failed: %08lx\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: %08lx\n", hres); + VariantClear(&v); + + hres = IActiveScript_SetScriptState(script, SCRIPTSTATE_UNINITIALIZED); + ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08lx\n", hres); + + str = SysAllocString(L"call"); + hres = IDispatchEx_GetDispID(dispex, str, 0, &func_id); + SysFreeString(str); + todo_wine + ok(hres == E_UNEXPECTED, "GetDispID failed: %08lx\n", hres); + + IDispatchEx_Release(dispex); + IActiveScript_Release(script); + /* test InvokeEx following prototype chain of builtin object (PROP_PROTREF) */ hres = parse_script_expr(L"o = new Array(); o.push("foo"); o", &v, &script); ok(hres == S_OK, "parse_script_expr failed: %08lx\n", hres);