Index: test/cctest/test-access-checks.cc |
diff --git a/test/cctest/test-access-checks.cc b/test/cctest/test-access-checks.cc |
index 59c17b89eb057decaac2bbcc23374f6d08d9a932..83165adbac99b6a8a548794088c8140d6b588a87 100644 |
--- a/test/cctest/test-access-checks.cc |
+++ b/test/cctest/test-access-checks.cc |
@@ -34,6 +34,12 @@ void NamedSetter(v8::Local<v8::Name> property, v8::Local<v8::Value> value, |
info.GetReturnValue().Set(value); |
} |
+void NamedSetterThrowsException( |
+ v8::Local<v8::Name> property, v8::Local<v8::Value> value, |
+ const v8::PropertyCallbackInfo<v8::Value>& info) { |
+ info.GetIsolate()->ThrowException(v8_str("exception")); |
+} |
+ |
void NamedQuery(v8::Local<v8::Name> property, |
const v8::PropertyCallbackInfo<v8::Integer>& info) { |
CHECK(g_expect_interceptor_call); |
@@ -181,6 +187,24 @@ void CheckCrossContextAccess(v8::Isolate* isolate, |
"[\"7\",\"cross_context_int\"]"); |
} |
+void CheckCrossContextSetterWithException( |
+ v8::Isolate* isolate, v8::Local<v8::Context> accessing_context, |
+ v8::Local<v8::Object> accessed_object) { |
+ v8::HandleScope handle_scope(isolate); |
+ accessing_context->Global() |
+ ->Set(accessing_context, v8_str("other"), accessed_object) |
+ .FromJust(); |
+ v8::Context::Scope context_scope(accessing_context); |
+ |
+ v8::TryCatch try_catch(isolate); |
+ CompileRun("this.other.should_throw = 8"); |
+ CHECK(try_catch.HasCaught()); |
+ CHECK(try_catch.Exception()->IsString()); |
+ CHECK(v8_str("exception") |
+ ->Equals(accessing_context, try_catch.Exception()) |
+ .FromJust()); |
+} |
+ |
void Ctor(const v8::FunctionCallbackInfo<v8::Value>& info) { |
CHECK(info.IsConstructCall()); |
} |
@@ -215,6 +239,33 @@ TEST(AccessCheckWithInterceptor) { |
CheckCrossContextAccess(isolate, context1, context0->Global()); |
} |
+TEST(AccessCheckWithExceptionThrowingSetterInterceptor) { |
+ v8::Isolate* isolate = CcTest::isolate(); |
+ isolate->SetFailedAccessCheckCallbackFunction([](v8::Local<v8::Object> target, |
+ v8::AccessType type, |
+ v8::Local<v8::Value> data) { |
+ CHECK(false); // This should never be called. |
+ }); |
+ |
+ v8::HandleScope scope(isolate); |
+ v8::Local<v8::ObjectTemplate> global_template = |
+ v8::ObjectTemplate::New(isolate); |
+ global_template->SetAccessCheckCallbackAndHandler( |
+ AccessCheck, v8::NamedPropertyHandlerConfiguration( |
+ NamedGetter, NamedSetterThrowsException), |
+ v8::IndexedPropertyHandlerConfiguration()); |
+ |
+ // Create two contexts. |
+ v8::Local<v8::Context> context0 = |
+ v8::Context::New(isolate, nullptr, global_template); |
+ v8::Local<v8::Context> context1 = |
+ v8::Context::New(isolate, nullptr, global_template); |
+ |
+ // Try setting a cross-context property, which should throw an exception but |
+ // not invoke the access failed callback. |
+ CheckCrossContextSetterWithException(isolate, context1, context0->Global()); |
+} |
+ |
TEST(NewRemoteContext) { |
v8::Isolate* isolate = CcTest::isolate(); |
v8::HandleScope scope(isolate); |