Index: test/cctest/test-api.cc |
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc |
index 06582526af8d8ea70bb246f3cc1fe16e82f052a1..4dcd841a9cc14d3baf60c3ccff3d70e4733d79a7 100644 |
--- a/test/cctest/test-api.cc |
+++ b/test/cctest/test-api.cc |
@@ -8741,6 +8741,13 @@ static bool AccessAlwaysBlocked(Local<v8::Object> global, Local<Value> name, |
} |
+static bool AccessAlwaysAllowed(Local<v8::Object> global, Local<Value> name, |
+ v8::AccessType type, Local<Value> data) { |
+ i::PrintF("Access allowed.\n"); |
+ return true; |
+} |
+ |
+ |
THREADED_TEST(AccessControlGetOwnPropertyNames) { |
v8::Isolate* isolate = CcTest::isolate(); |
v8::HandleScope handle_scope(isolate); |
@@ -9980,7 +9987,7 @@ THREADED_TEST(EvalInDetachedGlobal) { |
context0->DetachGlobal(); |
v8::TryCatch catcher(isolate); |
x_value = CompileRun("fun('x')"); |
- CHECK_EQ(42, x_value->Int32Value()); |
+ CHECK(x_value->IsUndefined()); |
context1->Exit(); |
} |
@@ -21946,3 +21953,71 @@ TEST(ArrayIteratorMethods) { |
ExpectString("typeof values", "function"); |
ExpectString("typeof entries", "function"); |
} |
+ |
+ |
+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(result->IsInt32()); |
+ CHECK_EQ(1, result->Int32Value()); |
+} |
+ |
+ |
+TEST(EvalInAccessCheckedContext) { |
+ v8::Isolate* isolate = CcTest::isolate(); |
+ v8::HandleScope scope(isolate); |
+ |
+ v8::Handle<v8::ObjectTemplate> obj_template = |
+ v8::ObjectTemplate::New(isolate); |
+ |
+ obj_template->SetAccessCheckCallbacks(AccessAlwaysAllowed, NULL); |
+ |
+ v8::Local<Context> context0 = Context::New(isolate, NULL, obj_template); |
+ v8::Local<Context> context1 = Context::New(isolate, NULL, obj_template); |
+ |
+ Local<Value> foo = v8_str("foo"); |
+ Local<Value> bar = v8_str("bar"); |
+ |
+ // Set to different domains. |
+ context0->SetSecurityToken(foo); |
+ context1->SetSecurityToken(bar); |
+ |
+ // Set up function in context0 that uses eval from context0. |
+ context0->Enter(); |
+ v8::Handle<v8::Value> fun = CompileRun( |
+ "var x = 42;" |
+ "(function() {" |
+ " var e = eval;" |
+ " return function(s) { return e(s); }" |
+ "})()"); |
+ context0->Exit(); |
+ |
+ // Put the function into context1 and call it. Since the access check |
+ // callback always returns true, the call succeeds even though the tokens |
+ // are different. |
+ context1->Enter(); |
+ context1->Global()->Set(v8_str("fun"), fun); |
+ v8::Handle<v8::Value> x_value = CompileRun("fun('x')"); |
+ CHECK_EQ(42, x_value->Int32Value()); |
+ context1->Exit(); |
+} |