Jacek Caban : jscript: Allow calling eval function from external code.
Alexandre Julliard
julliard at winehq.org
Mon May 20 15:50:49 CDT 2019
Module: wine
Branch: master
Commit: aac2110e8ff93d74ac99ab3bb78a47e1ea491cfa
URL: https://source.winehq.org/git/wine.git/?a=commit;h=aac2110e8ff93d74ac99ab3bb78a47e1ea491cfa
Author: Jacek Caban <jacek at codeweavers.com>
Date: Mon May 20 21:05:25 2019 +0200
jscript: Allow calling eval function from external code.
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/jscript/global.c | 13 ++---
dlls/jscript/tests/run.c | 146 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 150 insertions(+), 9 deletions(-)
diff --git a/dlls/jscript/global.c b/dlls/jscript/global.c
index 92b146c..cdabf6f 100644
--- a/dlls/jscript/global.c
+++ b/dlls/jscript/global.c
@@ -181,7 +181,7 @@ static HRESULT JSGlobal_escape(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, u
HRESULT JSGlobal_eval(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
jsval_t *r)
{
- call_frame_t *frame;
+ call_frame_t *frame = ctx->call_ctx;
DWORD exec_flags = EXEC_EVAL;
bytecode_t *code;
const WCHAR *src;
@@ -201,11 +201,6 @@ HRESULT JSGlobal_eval(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned a
return S_OK;
}
- if(!(frame = ctx->call_ctx)) {
- FIXME("No active exec_ctx\n");
- return E_UNEXPECTED;
- }
-
src = jsstr_flatten(get_string(argv[0]));
if(!src)
return E_OUTOFMEMORY;
@@ -217,12 +212,12 @@ HRESULT JSGlobal_eval(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned a
return throw_syntax_error(ctx, hres, NULL);
}
- if(frame->flags & EXEC_GLOBAL)
+ if(!frame || (frame->flags & EXEC_GLOBAL))
exec_flags |= EXEC_GLOBAL;
if(flags & DISPATCH_JSCRIPT_CALLEREXECSSOURCE)
exec_flags |= EXEC_RETURN_TO_INTERP;
- hres = exec_source(ctx, exec_flags, code, &code->global_code, frame->scope,
- frame->this_obj, NULL, frame->variable_obj, 0, NULL, r);
+ hres = exec_source(ctx, exec_flags, code, &code->global_code, frame ? frame->scope : NULL,
+ frame ? frame->this_obj : NULL, NULL, frame ? frame->variable_obj : ctx->global, 0, NULL, r);
release_bytecode(code);
return hres;
}
diff --git a/dlls/jscript/tests/run.c b/dlls/jscript/tests/run.c
index c8a143b..e48f748 100644
--- a/dlls/jscript/tests/run.c
+++ b/dlls/jscript/tests/run.c
@@ -91,6 +91,7 @@ DEFINE_EXPECT(global_notexists_d);
DEFINE_EXPECT(global_propargput_d);
DEFINE_EXPECT(global_propargput_i);
DEFINE_EXPECT(global_testargtypes_i);
+DEFINE_EXPECT(global_calleval_i);
DEFINE_EXPECT(puredisp_prop_d);
DEFINE_EXPECT(puredisp_noprop_d);
DEFINE_EXPECT(puredisp_value);
@@ -149,6 +150,7 @@ DEFINE_EXPECT(BindHandler);
#define DISPID_GLOBAL_GETSCRIPTSTATE 0x101c
#define DISPID_GLOBAL_BINDEVENTHANDLER 0x101d
#define DISPID_GLOBAL_TESTENUMOBJ 0x101e
+#define DISPID_GLOBAL_CALLEVAL 0x101f
#define DISPID_GLOBAL_TESTPROPDELETE 0x2000
#define DISPID_GLOBAL_TESTNOPROPDELETE 0x2001
@@ -988,6 +990,11 @@ static HRESULT WINAPI Global_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD
return S_OK;
}
+ if(!strcmp_wa(bstrName, "callEval")) {
+ *pid = DISPID_GLOBAL_CALLEVAL;
+ return S_OK;
+ }
+
if(strict_dispid_check && strcmp_wa(bstrName, "t"))
ok(0, "unexpected call %s\n", wine_dbgstr_w(bstrName));
return DISP_E_UNKNOWNNAME;
@@ -1492,6 +1499,43 @@ static HRESULT WINAPI Global_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid,
return S_OK;
}
+
+ case DISPID_GLOBAL_CALLEVAL: {
+ IDispatchEx *eval_func;
+ DISPPARAMS params;
+ VARIANT arg, res;
+ HRESULT hres;
+
+ CHECK_EXPECT(global_calleval_i);
+
+ ok(pdp != NULL, "pdp == NULL\n");
+ ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
+ ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
+ ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
+ ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
+ ok(pvarRes == NULL, "pvarRes != NULL\n");
+ ok(pei != NULL, "pei == NULL\n");
+
+ ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(arg) = %d\n", V_VT(pdp->rgvarg));
+ hres = IDispatch_QueryInterface(V_DISPATCH(pdp->rgvarg), &IID_IDispatchEx, (void**)&eval_func);
+ ok(hres == S_OK, "Could not get IDispatchEx iface: %08x\n", hres);
+
+ params.rgvarg = &arg;
+ params.rgdispidNamedArgs = NULL;
+ params.cArgs = 1;
+ params.cNamedArgs = 0;
+ V_VT(&arg) = VT_BSTR;
+
+ V_BSTR(&arg) = a2bstr("var x = 5; v");
+ V_VT(&res) = VT_ERROR;
+ hres = IDispatchEx_InvokeEx(eval_func, DISPID_VALUE, 0, DISPATCH_METHOD, ¶ms, &res, NULL, NULL);
+ ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
+ ok(V_VT(&res) == VT_I4, "eval returned type %u\n", V_VT(&res));
+ ok(V_I4(&res) == 2, "eval returned %d\n", V_I4(&res));
+ SysFreeString(V_BSTR(&arg));
+ IDispatchEx_Release(eval_func);
+ return S_OK;
+ }
}
ok(0, "unexpected call %x\n", id);
@@ -2492,6 +2536,107 @@ static void test_invokeex(void)
IActiveScript_Release(script);
}
+static void test_eval(void)
+{
+ IActiveScriptParse *parser;
+ IDispatchEx *script_dispex;
+ IDispatch *script_disp;
+ IActiveScript *engine;
+ VARIANT arg, res;
+ DISPPARAMS params;
+ DISPID id, v_id;
+ BSTR str;
+ HRESULT hres;
+
+ engine = create_script();
+
+ hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
+ ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
+
+ hres = IActiveScriptParse_InitNew(parser);
+ ok(hres == S_OK, "InitNew failed: %08x\n", hres);
+
+ hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
+ ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
+
+ SET_EXPECT(GetItemInfo_testVal);
+ hres = IActiveScript_AddNamedItem(engine, test_valW,
+ SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|SCRIPTITEM_GLOBALMEMBERS);
+ ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
+ CHECK_CALLED(GetItemInfo_testVal);
+
+ hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
+ ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
+
+ hres = IActiveScript_GetScriptDispatch(engine, NULL, &script_disp);
+ ok(hres == S_OK, "GetScriptDispatch failed: %08x\n", hres);
+ ok(script_disp != NULL, "script_disp == NULL\n");
+
+ hres = IDispatch_QueryInterface(script_disp, &IID_IDispatchEx, (void**)&script_dispex);
+ ok(hres == S_OK, "Coult not get IDispatchEx iface: %08x\n", hres);
+ IDispatch_Release(script_disp);
+
+ str = a2bstr("eval");
+ hres = IDispatchEx_GetDispID(script_dispex, str, 0, &id);
+ ok(hres == S_OK, "Could not get eval dispid: %08x\n", hres);
+ SysFreeString(str);
+
+ params.rgvarg = &arg;
+ params.rgdispidNamedArgs = NULL;
+ params.cArgs = 1;
+ params.cNamedArgs = 0;
+ V_VT(&arg) = VT_BSTR;
+
+ V_BSTR(&arg) = a2bstr("var v = 1;");
+ V_VT(&res) = VT_ERROR;
+ hres = IDispatchEx_InvokeEx(script_dispex, id, 0, DISPATCH_METHOD, ¶ms, &res, NULL, NULL);
+ ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
+ ok(V_VT(&res) == VT_EMPTY, "eval returned type %u\n", V_VT(&res));
+ SysFreeString(V_BSTR(&arg));
+
+ V_BSTR(&arg) = a2bstr("v");
+ V_VT(&res) = VT_ERROR;
+ hres = IDispatchEx_InvokeEx(script_dispex, id, 0, DISPATCH_METHOD, ¶ms, &res, NULL, NULL);
+ ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
+ ok(V_VT(&res) == VT_I4, "eval returned type %u\n", V_VT(&res));
+ ok(V_I4(&res) == 1, "eval returned %d\n", V_I4(&res));
+ SysFreeString(V_BSTR(&arg));
+
+ str = a2bstr("v");
+ hres = IDispatchEx_GetDispID(script_dispex, str, 0, &v_id);
+ ok(hres == S_OK, "Could not get v dispid: %08x\n", hres);
+ SysFreeString(str);
+
+ params.rgvarg = NULL;
+ params.cArgs = 0;
+ V_VT(&res) = VT_ERROR;
+ hres = IDispatchEx_InvokeEx(script_dispex, v_id, 0, DISPATCH_PROPERTYGET, ¶ms, &res, NULL, NULL);
+ ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
+ ok(V_VT(&res) == VT_I4, "eval returned type %u\n", V_VT(&res));
+ ok(V_I4(&res) == 1, "eval returned %d\n", V_I4(&res));
+
+ SET_EXPECT(global_calleval_i);
+ str = a2bstr("(function(){"
+ " var v = 2;"
+ " callEval(eval);"
+ " ok(x === 5, 'x = ' + x);"
+ "})();");
+ hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
+ ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
+ SysFreeString(str);
+ CHECK_CALLED(global_calleval_i);
+
+ str = a2bstr("x");
+ hres = IDispatchEx_GetDispID(script_dispex, str, 0, &id);
+ ok(hres == DISP_E_UNKNOWNNAME, "GetDispID(x) returned %08x\n", hres);
+ SysFreeString(str);
+
+ IDispatchEx_Release(script_dispex);
+ IActiveScriptParse_Release(parser);
+ IActiveScript_Close(engine);
+ IActiveScript_Release(engine);
+}
+
struct bom_test
{
WCHAR str[1024];
@@ -2877,6 +3022,7 @@ static BOOL run_tests(void)
test_script_exprs();
test_invokeex();
+ test_eval();
parse_script_with_error_a(
"?",
More information about the wine-cvs
mailing list