}
-// Walk up the stack expecting:
-// - Runtime_CompileString
-// - JSFunction callee (eval, Function constructor, etc)
-// - call() (maybe)
-// - apply() (maybe)
-// - bind() (maybe)
-// - JSFunction caller (maybe)
-//
-// return true if the caller has the same security token as the callee
-// or if an exit frame was hit, in which case allow it through, as it could
-// have come through the api.
-static bool TokensMatchForCompileString(Isolate* isolate) {
- MaybeHandle<JSFunction> callee;
- bool exit_handled = true;
- bool tokens_match = true;
- bool done = false;
- for (StackFrameIterator it(isolate); !it.done() && !done; it.Advance()) {
- StackFrame* raw_frame = it.frame();
- if (!raw_frame->is_java_script()) {
- if (raw_frame->is_exit()) exit_handled = false;
- continue;
- }
- JavaScriptFrame* outer_frame = JavaScriptFrame::cast(raw_frame);
- List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
- outer_frame->Summarize(&frames);
- for (int i = frames.length() - 1; i >= 0 && !done; --i) {
- FrameSummary& frame = frames[i];
- Handle<JSFunction> fun = frame.function();
- // Capture the callee function.
- if (callee.is_null()) {
- callee = fun;
- exit_handled = true;
- continue;
- }
- // Exit condition.
- Handle<Context> context(callee.ToHandleChecked()->context());
- if (!fun->context()->HasSameSecurityTokenAs(*context)) {
- tokens_match = false;
- done = true;
- continue;
- }
- // Skip bound functions in correct origin.
- if (fun->shared()->bound()) {
- exit_handled = true;
- continue;
- }
- done = true;
- }
- }
- return !exit_handled || tokens_match;
-}
-
-
RUNTIME_FUNCTION(Runtime_CompileString) {
HandleScope scope(isolate);
DCHECK(args.length() == 2);
// Extract native context.
Handle<Context> context(isolate->native_context());
- // Filter cross security context calls.
- if (!TokensMatchForCompileString(isolate)) {
- return isolate->heap()->undefined_value();
- }
-
// Check if native context allows code generation from
// strings. Throw an exception if it doesn't.
if (context->allow_code_gen_from_strings()->IsFalse() &&
}
-Local<v8::Context> call_eval_context;
-Local<v8::Function> call_eval_bound_function;
-static void CallEval(const v8::FunctionCallbackInfo<v8::Value>& args) {
- v8::Context::Scope scope(call_eval_context);
- args.GetReturnValue().Set(
- call_eval_bound_function->Call(call_eval_context->Global(), 0, NULL));
-}
-
-
-TEST(CrossActivationEval) {
- LocalContext env;
- v8::Isolate* isolate = env->GetIsolate();
- v8::HandleScope scope(isolate);
- {
- call_eval_context = v8::Context::New(isolate);
- v8::Context::Scope scope(call_eval_context);
- call_eval_bound_function =
- Local<Function>::Cast(CompileRun("eval.bind(this, '1')"));
- }
- env->Global()->Set(v8_str("CallEval"),
- v8::FunctionTemplate::New(isolate, CallEval)->GetFunction());
- Local<Value> result = CompileRun("CallEval();");
- CHECK_EQ(result, v8::Integer::New(isolate, 1));
-}
-
-
void SourceURLHelper(const char* source, const char* expected_source_url,
const char* expected_source_mapping_url) {
Local<Script> script = v8_compile(source);
Realm.eval(realms[0], script);
assertSame(Realm.shared.caller_0, Realm.shared.result_0);
assertSame(null, Realm.shared.result_1);
-
-
-// Check function constructor.
-var ctor_script = "Function.constructor";
-var ctor_a_script =
- "(function() { return Function.constructor.apply(this, ['return 1;']); })";
-var ctor_b_script = "Function.constructor.bind(this, 'return 1;')";
-var ctor_c_script =
- "(function() { return Function.constructor.call(this, 'return 1;'); })";
-Realm.shared = {
- ctor_0 : Realm.eval(realms[0], ctor_script),
- ctor_1 : Realm.eval(realms[1], ctor_script),
- ctor_a_0 : Realm.eval(realms[0], ctor_a_script),
- ctor_a_1 : Realm.eval(realms[1], ctor_a_script),
- ctor_b_0 : Realm.eval(realms[0], ctor_b_script),
- ctor_b_1 : Realm.eval(realms[1], ctor_b_script),
- ctor_c_0 : Realm.eval(realms[0], ctor_c_script),
- ctor_c_1 : Realm.eval(realms[1], ctor_c_script),
-}
-
-var script_0 = " \
- var ctor_0 = Realm.shared.ctor_0; \
- Realm.shared.direct_0 = ctor_0('return 1'); \
- Realm.shared.indirect_0 = (function() { return ctor_0('return 1;'); })(); \
- Realm.shared.apply_0 = ctor_0.apply(this, ['return 1']); \
- Realm.shared.bind_0 = ctor_0.bind(this, 'return 1')(); \
- Realm.shared.call_0 = ctor_0.call(this, 'return 1'); \
- Realm.shared.a_0 = Realm.shared.ctor_a_0(); \
- Realm.shared.b_0 = Realm.shared.ctor_b_0(); \
- Realm.shared.c_0 = Realm.shared.ctor_c_0(); \
-";
-
-script = script_0 + script_0.replace(/_0/g, "_1");
-
-Realm.eval(realms[0], script);
-assertSame(1, Realm.shared.direct_0());
-assertSame(1, Realm.shared.indirect_0());
-assertSame(1, Realm.shared.apply_0());
-assertSame(1, Realm.shared.bind_0());
-assertSame(1, Realm.shared.call_0());
-assertSame(1, Realm.shared.a_0());
-assertSame(1, Realm.shared.b_0());
-assertSame(1, Realm.shared.c_0());
-assertSame(undefined, Realm.shared.direct_1);
-assertSame(undefined, Realm.shared.indirect_1);
-assertSame(undefined, Realm.shared.apply_1);
-assertSame(undefined, Realm.shared.bind_1);
-assertSame(undefined, Realm.shared.call_1);
-assertSame(1, Realm.shared.a_1());
-assertSame(undefined, Realm.shared.b_1);
-assertSame(1, Realm.shared.c_1());
-
-Realm.eval(realms[1], script);
-assertSame(undefined, Realm.shared.direct_0);
-assertSame(undefined, Realm.shared.indirect_0);
-assertSame(undefined, Realm.shared.apply_0);
-assertSame(undefined, Realm.shared.bind_0);
-assertSame(undefined, Realm.shared.call_0);
-assertSame(1, Realm.shared.a_0());
-assertSame(undefined, Realm.shared.b_0);
-assertSame(1, Realm.shared.c_1());
-assertSame(1, Realm.shared.direct_1());
-assertSame(1, Realm.shared.indirect_1());
-assertSame(1, Realm.shared.apply_1());
-assertSame(1, Realm.shared.bind_1());
-assertSame(1, Realm.shared.call_1());
-assertSame(1, Realm.shared.a_1());
-assertSame(1, Realm.shared.b_1());
-assertSame(1, Realm.shared.c_1());