// Check access rights if required.
if (current->IsAccessCheckNeeded() &&
- !isolate->MayNamedAccessWrapper(current,
- isolate->factory()->undefined_value(),
- v8::ACCESS_KEYS)) {
- isolate->ReportFailedAccessCheckWrapper(current, v8::ACCESS_KEYS);
+ !isolate->MayNamedAccess(
+ current, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) {
+ isolate->ReportFailedAccessCheck(current, v8::ACCESS_KEYS);
RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, FixedArray);
break;
}
}
-void Isolate::ReportFailedAccessCheck(JSObject* receiver, v8::AccessType type) {
+static inline AccessCheckInfo* GetAccessCheckInfo(Isolate* isolate,
+ Handle<JSObject> receiver) {
+ JSFunction* constructor = JSFunction::cast(receiver->map()->constructor());
+ if (!constructor->shared()->IsApiFunction()) return NULL;
+
+ Object* data_obj =
+ constructor->shared()->get_api_func_data()->access_check_info();
+ if (data_obj == isolate->heap()->undefined_value()) return NULL;
+
+ return AccessCheckInfo::cast(data_obj);
+}
+
+
+void Isolate::ReportFailedAccessCheck(Handle<JSObject> receiver,
+ v8::AccessType type) {
if (!thread_local_top()->failed_access_check_callback_) return;
ASSERT(receiver->IsAccessCheckNeeded());
ASSERT(context());
// Get the data object from access check info.
- JSFunction* constructor = JSFunction::cast(receiver->map()->constructor());
- if (!constructor->shared()->IsApiFunction()) return;
- Object* data_obj =
- constructor->shared()->get_api_func_data()->access_check_info();
- if (data_obj == heap_.undefined_value()) return;
-
HandleScope scope(this);
- Handle<JSObject> receiver_handle(receiver);
- Handle<Object> data(AccessCheckInfo::cast(data_obj)->data(), this);
- { VMState<EXTERNAL> state(this);
- thread_local_top()->failed_access_check_callback_(
- v8::Utils::ToLocal(receiver_handle),
+ Handle<Object> data;
+ { DisallowHeapAllocation no_gc;
+ AccessCheckInfo* access_check_info = GetAccessCheckInfo(this, receiver);
+ if (!access_check_info) return;
+ data = handle(access_check_info->data(), this);
+ }
+
+ // Leaving JavaScript.
+ VMState<EXTERNAL> state(this);
+ thread_local_top()->failed_access_check_callback_(
+ v8::Utils::ToLocal(receiver),
type,
v8::Utils::ToLocal(data));
- }
}
static MayAccessDecision MayAccessPreCheck(Isolate* isolate,
- JSObject* receiver,
+ Handle<JSObject> receiver,
v8::AccessType type) {
+ DisallowHeapAllocation no_gc;
// During bootstrapping, callback functions are not enabled yet.
if (isolate->bootstrapper()->IsActive()) return YES;
if (receiver->IsJSGlobalProxy()) {
- Object* receiver_context = JSGlobalProxy::cast(receiver)->native_context();
+ Object* receiver_context = JSGlobalProxy::cast(*receiver)->native_context();
if (!receiver_context->IsContext()) return NO;
// Get the native context of current top context.
}
-bool Isolate::MayNamedAccess(JSObject* receiver, Object* key,
+bool Isolate::MayNamedAccess(Handle<JSObject> receiver,
+ Handle<Object> key,
v8::AccessType type) {
ASSERT(receiver->IsJSGlobalProxy() || receiver->IsAccessCheckNeeded());
- // The callers of this method are not expecting a GC.
- DisallowHeapAllocation no_gc;
-
// Skip checks for hidden properties access. Note, we do not
// require existence of a context in this case.
- if (key == heap_.hidden_string()) return true;
+ if (key.is_identical_to(factory()->hidden_string())) return true;
// Check for compatibility between the security tokens in the
// current lexical context and the accessed object.
MayAccessDecision decision = MayAccessPreCheck(this, receiver, type);
if (decision != UNKNOWN) return decision == YES;
- // Get named access check callback
- JSFunction* constructor = JSFunction::cast(receiver->map()->constructor());
- if (!constructor->shared()->IsApiFunction()) return false;
-
- Object* data_obj =
- constructor->shared()->get_api_func_data()->access_check_info();
- if (data_obj == heap_.undefined_value()) return false;
-
- Object* fun_obj = AccessCheckInfo::cast(data_obj)->named_callback();
- v8::NamedSecurityCallback callback =
- v8::ToCData<v8::NamedSecurityCallback>(fun_obj);
-
- if (!callback) return false;
-
HandleScope scope(this);
- Handle<JSObject> receiver_handle(receiver, this);
- Handle<Object> key_handle(key, this);
- Handle<Object> data(AccessCheckInfo::cast(data_obj)->data(), this);
- LOG(this, ApiNamedSecurityCheck(key));
- bool result = false;
- {
- // Leaving JavaScript.
- VMState<EXTERNAL> state(this);
- result = callback(v8::Utils::ToLocal(receiver_handle),
- v8::Utils::ToLocal(key_handle),
- type,
- v8::Utils::ToLocal(data));
+ Handle<Object> data;
+ v8::NamedSecurityCallback callback;
+ { DisallowHeapAllocation no_gc;
+ AccessCheckInfo* access_check_info = GetAccessCheckInfo(this, receiver);
+ if (!access_check_info) return false;
+ Object* fun_obj = access_check_info->named_callback();
+ callback = v8::ToCData<v8::NamedSecurityCallback>(fun_obj);
+ if (!callback) return false;
+ data = handle(access_check_info->data(), this);
}
- return result;
+
+ LOG(this, ApiNamedSecurityCheck(*key));
+
+ // Leaving JavaScript.
+ VMState<EXTERNAL> state(this);
+ return callback(v8::Utils::ToLocal(receiver),
+ v8::Utils::ToLocal(key),
+ type,
+ v8::Utils::ToLocal(data));
}
-bool Isolate::MayIndexedAccess(JSObject* receiver,
+bool Isolate::MayIndexedAccess(Handle<JSObject> receiver,
uint32_t index,
v8::AccessType type) {
ASSERT(receiver->IsJSGlobalProxy() || receiver->IsAccessCheckNeeded());
MayAccessDecision decision = MayAccessPreCheck(this, receiver, type);
if (decision != UNKNOWN) return decision == YES;
- // Get indexed access check callback
- JSFunction* constructor = JSFunction::cast(receiver->map()->constructor());
- if (!constructor->shared()->IsApiFunction()) return false;
-
- Object* data_obj =
- constructor->shared()->get_api_func_data()->access_check_info();
- if (data_obj == heap_.undefined_value()) return false;
-
- Object* fun_obj = AccessCheckInfo::cast(data_obj)->indexed_callback();
- v8::IndexedSecurityCallback callback =
- v8::ToCData<v8::IndexedSecurityCallback>(fun_obj);
-
- if (!callback) return false;
-
HandleScope scope(this);
- Handle<JSObject> receiver_handle(receiver, this);
- Handle<Object> data(AccessCheckInfo::cast(data_obj)->data(), this);
- LOG(this, ApiIndexedSecurityCheck(index));
- bool result = false;
- {
- // Leaving JavaScript.
- VMState<EXTERNAL> state(this);
- result = callback(v8::Utils::ToLocal(receiver_handle),
- index,
- type,
- v8::Utils::ToLocal(data));
+ Handle<Object> data;
+ v8::IndexedSecurityCallback callback;
+ { DisallowHeapAllocation no_gc;
+ // Get named access check callback
+ AccessCheckInfo* access_check_info = GetAccessCheckInfo(this, receiver);
+ if (!access_check_info) return false;
+ Object* fun_obj = access_check_info->indexed_callback();
+ callback = v8::ToCData<v8::IndexedSecurityCallback>(fun_obj);
+ if (!callback) return false;
+ data = handle(access_check_info->data(), this);
}
- return result;
+
+ LOG(this, ApiIndexedSecurityCheck(index));
+
+ // Leaving JavaScript.
+ VMState<EXTERNAL> state(this);
+ return callback(
+ v8::Utils::ToLocal(receiver), index, type, v8::Utils::ToLocal(data));
}
// the result is false, the pending exception is guaranteed to be
// set.
- // TODO(yangguo): temporary wrappers
- bool MayNamedAccessWrapper(Handle<JSObject> receiver,
- Handle<Object> key,
- v8::AccessType type) {
- return MayNamedAccess(*receiver, *key, type);
- }
- bool MayIndexedAccessWrapper(Handle<JSObject> receiver,
- uint32_t index,
- v8::AccessType type) {
- return MayIndexedAccess(*receiver, index, type);
- }
- void ReportFailedAccessCheckWrapper(Handle<JSObject> receiver,
- v8::AccessType type) {
- ReportFailedAccessCheck(*receiver, type);
- }
-
- bool MayNamedAccess(JSObject* receiver,
- Object* key,
+ bool MayNamedAccess(Handle<JSObject> receiver,
+ Handle<Object> key,
v8::AccessType type);
- bool MayIndexedAccess(JSObject* receiver,
+ bool MayIndexedAccess(Handle<JSObject> receiver,
uint32_t index,
v8::AccessType type);
void SetFailedAccessCheckCallback(v8::FailedAccessCheckCallback callback);
- void ReportFailedAccessCheck(JSObject* receiver, v8::AccessType type);
+ void ReportFailedAccessCheck(Handle<JSObject> receiver, v8::AccessType type);
// Exception throwing support. The caller should use the result
// of Throw() as its return value.
// No accessible property found.
*attributes = ABSENT;
- isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_GET);
+ isolate->ReportFailedAccessCheck(object, v8::ACCESS_GET);
RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
return isolate->factory()->undefined_value();
}
}
}
- object->GetIsolate()->ReportFailedAccessCheckWrapper(object, v8::ACCESS_HAS);
+ object->GetIsolate()->ReportFailedAccessCheck(object, v8::ACCESS_HAS);
+ // TODO(yangguo): Issue 3269, check for scheduled exception missing?
return ABSENT;
}
// property from the current object, we still check that we have
// access to it.
Handle<JSObject> checked = Handle<JSObject>::cast(current);
- if (!isolate->MayNamedAccessWrapper(checked, name, v8::ACCESS_GET)) {
+ if (!isolate->MayNamedAccess(checked, name, v8::ACCESS_GET)) {
return JSObject::GetPropertyWithFailedAccessCheck(
checked, receiver, result, name, attributes);
}
// Check access rights if needed.
if (js_object->IsAccessCheckNeeded()) {
- if (!isolate->MayIndexedAccessWrapper(js_object, index, v8::ACCESS_GET)) {
- isolate->ReportFailedAccessCheckWrapper(js_object, v8::ACCESS_GET);
+ if (!isolate->MayIndexedAccess(js_object, index, v8::ACCESS_GET)) {
+ isolate->ReportFailedAccessCheck(js_object, v8::ACCESS_GET);
RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
return isolate->factory()->undefined_value();
}
}
Isolate* isolate = object->GetIsolate();
- isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_SET);
+ isolate->ReportFailedAccessCheck(object, v8::ACCESS_SET);
RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
return value;
}
// Check access rights if needed.
if (object->IsAccessCheckNeeded()) {
- if (!isolate->MayNamedAccessWrapper(object, name, v8::ACCESS_SET)) {
+ if (!isolate->MayNamedAccess(object, name, v8::ACCESS_SET)) {
return SetPropertyWithFailedAccessCheck(object, lookup, name, value,
true, strict_mode);
}
// Check access rights if needed.
if (object->IsAccessCheckNeeded()) {
- if (!isolate->MayNamedAccessWrapper(object, name, v8::ACCESS_SET)) {
+ if (!isolate->MayNamedAccess(object, name, v8::ACCESS_SET)) {
return SetPropertyWithFailedAccessCheck(object, &lookup, name, value,
false, SLOPPY);
}
if (object->IsAccessCheckNeeded()) {
Heap* heap = object->GetHeap();
Handle<JSObject> obj = Handle<JSObject>::cast(object);
- if (!heap->isolate()->MayNamedAccessWrapper(obj, name, v8::ACCESS_HAS)) {
+ if (!heap->isolate()->MayNamedAccess(obj, name, v8::ACCESS_HAS)) {
return JSObject::GetPropertyAttributeWithFailedAccessCheck(
obj, lookup, name, continue_search);
}
// Check access rights if needed.
if (object->IsAccessCheckNeeded()) {
- if (!isolate->MayIndexedAccessWrapper(object, index, v8::ACCESS_HAS)) {
- isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_HAS);
+ if (!isolate->MayIndexedAccess(object, index, v8::ACCESS_HAS)) {
+ isolate->ReportFailedAccessCheck(object, v8::ACCESS_HAS);
+ // TODO(yangguo): Issue 3269, check for scheduled exception missing?
return ABSENT;
}
}
// Check access rights if needed.
if (object->IsAccessCheckNeeded() &&
- !isolate->MayIndexedAccessWrapper(object, index, v8::ACCESS_DELETE)) {
- isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_DELETE);
+ !isolate->MayIndexedAccess(object, index, v8::ACCESS_DELETE)) {
+ isolate->ReportFailedAccessCheck(object, v8::ACCESS_DELETE);
RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
return factory->false_value();
}
// Check access rights if needed.
if (object->IsAccessCheckNeeded() &&
- !isolate->MayNamedAccessWrapper(object, name, v8::ACCESS_DELETE)) {
- isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_DELETE);
+ !isolate->MayNamedAccess(object, name, v8::ACCESS_DELETE)) {
+ isolate->ReportFailedAccessCheck(object, v8::ACCESS_DELETE);
RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
return isolate->factory()->false_value();
}
if (!object->map()->is_extensible()) return object;
if (object->IsAccessCheckNeeded() &&
- !isolate->MayNamedAccessWrapper(object,
- isolate->factory()->undefined_value(),
- v8::ACCESS_KEYS)) {
- isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_KEYS);
+ !isolate->MayNamedAccess(
+ object, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) {
+ isolate->ReportFailedAccessCheck(object, v8::ACCESS_KEYS);
RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
return isolate->factory()->false_value();
}
Isolate* isolate = object->GetIsolate();
if (object->IsAccessCheckNeeded() &&
- !isolate->MayNamedAccessWrapper(object,
- isolate->factory()->undefined_value(),
- v8::ACCESS_KEYS)) {
- isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_KEYS);
+ !isolate->MayNamedAccess(
+ object, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) {
+ isolate->ReportFailedAccessCheck(object, v8::ACCESS_KEYS);
RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
return isolate->factory()->false_value();
}
bool JSObject::CanSetCallback(Handle<JSObject> object, Handle<Name> name) {
Isolate* isolate = object->GetIsolate();
ASSERT(!object->IsAccessCheckNeeded() ||
- isolate->MayNamedAccessWrapper(object, name, v8::ACCESS_SET));
+ isolate->MayNamedAccess(object, name, v8::ACCESS_SET));
// Check if there is an API defined callback object which prohibits
// callback overwriting in this object or its prototype chain.
Isolate* isolate = object->GetIsolate();
// Check access rights if needed.
if (object->IsAccessCheckNeeded() &&
- !isolate->MayNamedAccessWrapper(object, name, v8::ACCESS_SET)) {
- isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_SET);
+ !isolate->MayNamedAccess(object, name, v8::ACCESS_SET)) {
+ isolate->ReportFailedAccessCheck(object, v8::ACCESS_SET);
+ // TODO(yangguo): Issue 3269, check for scheduled exception missing?
return;
}
// Check access rights if needed.
if (object->IsAccessCheckNeeded() &&
- !isolate->MayNamedAccessWrapper(object, name, v8::ACCESS_SET)) {
- isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_SET);
+ !isolate->MayNamedAccess(object, name, v8::ACCESS_SET)) {
+ isolate->ReportFailedAccessCheck(object, v8::ACCESS_SET);
RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
return factory->undefined_value();
}
// Check access rights if needed.
if (object->IsAccessCheckNeeded() &&
- !isolate->MayNamedAccessWrapper(object, name, v8::ACCESS_HAS)) {
- isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_HAS);
+ !isolate->MayNamedAccess(object, name, v8::ACCESS_HAS)) {
+ isolate->ReportFailedAccessCheck(object, v8::ACCESS_HAS);
RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
return isolate->factory()->undefined_value();
}
// Check access rights if needed.
if (object->IsAccessCheckNeeded()) {
- if (!isolate->MayIndexedAccessWrapper(object, index, v8::ACCESS_SET)) {
- isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_SET);
+ if (!isolate->MayIndexedAccess(object, index, v8::ACCESS_SET)) {
+ isolate->ReportFailedAccessCheck(object, v8::ACCESS_SET);
RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
return value;
}
SealHandleScope shs(isolate);
// Check access rights if needed.
if (object->IsAccessCheckNeeded()) {
- if (!isolate->MayNamedAccessWrapper(object, key, v8::ACCESS_HAS)) {
- isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_HAS);
+ if (!isolate->MayNamedAccess(object, key, v8::ACCESS_HAS)) {
+ isolate->ReportFailedAccessCheck(object, v8::ACCESS_HAS);
+ // TODO(yangguo): Issue 3269, check for scheduled exception missing?
return false;
}
}
HandleScope scope(isolate);
// Check access rights if needed.
if (object->IsAccessCheckNeeded()) {
- if (!isolate->MayIndexedAccessWrapper(object, index, v8::ACCESS_HAS)) {
- isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_HAS);
+ if (!isolate->MayIndexedAccess(object, index, v8::ACCESS_HAS)) {
+ isolate->ReportFailedAccessCheck(object, v8::ACCESS_HAS);
+ // TODO(yangguo): Issue 3269, check for scheduled exception missing?
return false;
}
}
SealHandleScope shs(isolate);
// Check access rights if needed.
if (object->IsAccessCheckNeeded()) {
- if (!isolate->MayNamedAccessWrapper(object, key, v8::ACCESS_HAS)) {
- isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_HAS);
+ if (!isolate->MayNamedAccess(object, key, v8::ACCESS_HAS)) {
+ isolate->ReportFailedAccessCheck(object, v8::ACCESS_HAS);
+ // TODO(yangguo): Issue 3269, check for scheduled exception missing?
return false;
}
}
ASSERT(!obj->IsAccessCheckNeeded() || obj->IsJSObject());
do {
if (obj->IsAccessCheckNeeded() &&
- !isolate->MayNamedAccessWrapper(Handle<JSObject>::cast(obj),
- isolate->factory()->proto_string(),
- v8::ACCESS_GET)) {
- isolate->ReportFailedAccessCheckWrapper(Handle<JSObject>::cast(obj),
- v8::ACCESS_GET);
+ !isolate->MayNamedAccess(Handle<JSObject>::cast(obj),
+ isolate->factory()->proto_string(),
+ v8::ACCESS_GET)) {
+ isolate->ReportFailedAccessCheck(Handle<JSObject>::cast(obj),
+ v8::ACCESS_GET);
RETURN_IF_SCHEDULED_EXCEPTION(isolate);
return isolate->heap()->undefined_value();
}
CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
if (obj->IsAccessCheckNeeded() &&
- !isolate->MayNamedAccessWrapper(obj,
- isolate->factory()->proto_string(),
- v8::ACCESS_SET)) {
- isolate->ReportFailedAccessCheckWrapper(obj, v8::ACCESS_SET);
+ !isolate->MayNamedAccess(
+ obj, isolate->factory()->proto_string(), v8::ACCESS_SET)) {
+ isolate->ReportFailedAccessCheck(obj, v8::ACCESS_SET);
RETURN_IF_SCHEDULED_EXCEPTION(isolate);
return isolate->heap()->undefined_value();
}
if (name->AsArrayIndex(&index)) {
// TODO(1095): we should traverse hidden prototype hierachy as well.
if (CheckGenericAccess(
- obj, obj, index, access_type, &Isolate::MayIndexedAccessWrapper)) {
+ obj, obj, index, access_type, &Isolate::MayIndexedAccess)) {
return ACCESS_ALLOWED;
}
- obj->GetIsolate()->ReportFailedAccessCheckWrapper(obj, access_type);
+ obj->GetIsolate()->ReportFailedAccessCheck(obj, access_type);
return ACCESS_FORBIDDEN;
}
if (!lookup.IsProperty()) return ACCESS_ABSENT;
Handle<JSObject> holder(lookup.holder(), isolate);
if (CheckGenericAccess<Handle<Object> >(
- obj, holder, name, access_type, &Isolate::MayNamedAccessWrapper)) {
+ obj, holder, name, access_type, &Isolate::MayNamedAccess)) {
return ACCESS_ALLOWED;
}
break;
}
- isolate->ReportFailedAccessCheckWrapper(obj, access_type);
+ isolate->ReportFailedAccessCheck(obj, access_type);
return ACCESS_FORBIDDEN;
}
if (obj->IsJSGlobalProxy()) {
// Only collect names if access is permitted.
if (obj->IsAccessCheckNeeded() &&
- !isolate->MayNamedAccessWrapper(obj,
- isolate->factory()->undefined_value(),
- v8::ACCESS_KEYS)) {
- isolate->ReportFailedAccessCheckWrapper(obj, v8::ACCESS_KEYS);
+ !isolate->MayNamedAccess(
+ obj, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) {
+ isolate->ReportFailedAccessCheck(obj, v8::ACCESS_KEYS);
RETURN_IF_SCHEDULED_EXCEPTION(isolate);
return *isolate->factory()->NewJSArray(0);
}
for (int i = 0; i < length; i++) {
// Only collect names if access is permitted.
if (jsproto->IsAccessCheckNeeded() &&
- !isolate->MayNamedAccessWrapper(jsproto,
- isolate->factory()->undefined_value(),
- v8::ACCESS_KEYS)) {
- isolate->ReportFailedAccessCheckWrapper(jsproto, v8::ACCESS_KEYS);
+ !isolate->MayNamedAccess(
+ jsproto, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) {
+ isolate->ReportFailedAccessCheck(jsproto, v8::ACCESS_KEYS);
RETURN_IF_SCHEDULED_EXCEPTION(isolate);
return *isolate->factory()->NewJSArray(0);
}
if (object->IsJSGlobalProxy()) {
// Do access checks before going to the global object.
if (object->IsAccessCheckNeeded() &&
- !isolate->MayNamedAccessWrapper(object,
- isolate->factory()->undefined_value(),
- v8::ACCESS_KEYS)) {
- isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_KEYS);
+ !isolate->MayNamedAccess(
+ object, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) {
+ isolate->ReportFailedAccessCheck(object, v8::ACCESS_KEYS);
RETURN_IF_SCHEDULED_EXCEPTION(isolate);
return *isolate->factory()->NewJSArray(0);
}
Handle<Object> key = args.at<Object>(2);
SaveContext save(isolate);
isolate->set_context(observer->context());
- if (!isolate->MayNamedAccessWrapper(object,
- isolate->factory()->undefined_value(),
- v8::ACCESS_KEYS)) {
+ if (!isolate->MayNamedAccess(
+ object, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) {
return isolate->heap()->false_value();
}
bool access_allowed = false;
if (key->ToArrayIndex(&index) ||
(key->IsString() && String::cast(*key)->AsArrayIndex(&index))) {
access_allowed =
- isolate->MayIndexedAccessWrapper(object, index, v8::ACCESS_GET) &&
- isolate->MayIndexedAccessWrapper(object, index, v8::ACCESS_HAS);
+ isolate->MayIndexedAccess(object, index, v8::ACCESS_GET) &&
+ isolate->MayIndexedAccess(object, index, v8::ACCESS_HAS);
} else {
access_allowed =
- isolate->MayNamedAccessWrapper(object, key, v8::ACCESS_GET) &&
- isolate->MayNamedAccessWrapper(object, key, v8::ACCESS_HAS);
+ isolate->MayNamedAccess(object, key, v8::ACCESS_GET) &&
+ isolate->MayNamedAccess(object, key, v8::ACCESS_HAS);
}
return isolate->heap()->ToBoolean(access_allowed);
}
}
-// For use within the TestSecurityHandler() test.
-static bool g_security_callback_result = false;
-static bool NamedSecurityTestCallback(Local<v8::Object> global,
- Local<Value> name,
- v8::AccessType type,
- Local<Value> data) {
- // Always allow read access.
- if (type == v8::ACCESS_GET)
- return true;
-
- // Sometimes allow other access.
- return g_security_callback_result;
-}
-
-
-static bool IndexedSecurityTestCallback(Local<v8::Object> global,
- uint32_t key,
- v8::AccessType type,
- Local<Value> data) {
- // Always allow read access.
- if (type == v8::ACCESS_GET)
- return true;
-
- // Sometimes allow other access.
- return g_security_callback_result;
-}
-
-
static int trouble_nesting = 0;
static void TroubleCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {
ApiTestFuzzer::Fuzz();
}
+// For use within the TestSecurityHandler() test.
+static bool g_security_callback_result = false;
+static bool NamedSecurityTestCallback(Local<v8::Object> global,
+ Local<Value> name,
+ v8::AccessType type,
+ Local<Value> data) {
+ printf("a\n");
+ // Always allow read access.
+ if (type == v8::ACCESS_GET)
+ return true;
+
+ // Sometimes allow other access.
+ return g_security_callback_result;
+}
+
+
+static bool IndexedSecurityTestCallback(Local<v8::Object> global,
+ uint32_t key,
+ v8::AccessType type,
+ Local<Value> data) {
+ printf("b\n");
+ // Always allow read access.
+ if (type == v8::ACCESS_GET)
+ return true;
+
+ // Sometimes allow other access.
+ return g_security_callback_result;
+}
+
+
// SecurityHandler can't be run twice
TEST(SecurityHandler) {
v8::Isolate* isolate = CcTest::isolate();
}
+static bool named_security_check_with_gc_called;
+
+static bool NamedSecurityCallbackWithGC(Local<v8::Object> global,
+ Local<Value> name,
+ v8::AccessType type,
+ Local<Value> data) {
+ CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
+ named_security_check_with_gc_called = true;
+ return true;
+}
+
+
+static bool indexed_security_check_with_gc_called;
+
+static bool IndexedSecurityTestCallbackWithGC(Local<v8::Object> global,
+ uint32_t key,
+ v8::AccessType type,
+ Local<Value> data) {
+ CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
+ indexed_security_check_with_gc_called = true;
+ return true;
+}
+
+
+TEST(SecurityTestGCAllowed) {
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope handle_scope(isolate);
+ v8::Handle<v8::ObjectTemplate> object_template =
+ v8::ObjectTemplate::New(isolate);
+ object_template->SetAccessCheckCallbacks(NamedSecurityCallbackWithGC,
+ IndexedSecurityTestCallbackWithGC);
+
+ v8::Handle<Context> context = Context::New(isolate);
+ v8::Context::Scope context_scope(context);
+
+ context->Global()->Set(v8_str("obj"), object_template->NewInstance());
+
+ named_security_check_with_gc_called = false;
+ CompileRun("obj.foo = new String(1001);");
+ CHECK(named_security_check_with_gc_called);
+
+ indexed_security_check_with_gc_called = false;
+ CompileRun("obj[0] = new String(1002);");
+ CHECK(indexed_security_check_with_gc_called);
+
+ named_security_check_with_gc_called = false;
+ CHECK(CompileRun("obj.foo")->ToString()->Equals(v8_str("1001")));
+ CHECK(named_security_check_with_gc_called);
+
+ indexed_security_check_with_gc_called = false;
+ CHECK(CompileRun("obj[0]")->ToString()->Equals(v8_str("1002")));
+ CHECK(indexed_security_check_with_gc_called);
+}
+
+
THREADED_TEST(CrossDomainDelete) {
LocalContext env1;
v8::HandleScope handle_scope(env1->GetIsolate());