Commit b5fc4b80 authored by verwaest's avatar verwaest Committed by Commit bot

Remove internal use of v8::AccessType, always pass v8::ACCESS_HAS instead.

BUG=

Review URL: https://codereview.chromium.org/942963004

Cr-Commit-Position: refs/heads/master@{#26874}
parent 9dac60ad
......@@ -257,8 +257,7 @@ static void LookupForRead(LookupIterator* it) {
case LookupIterator::ACCESS_CHECK:
// PropertyHandlerCompiler::CheckPrototypes() knows how to emit
// access checks for global proxies.
if (it->GetHolder<JSObject>()->IsJSGlobalProxy() &&
it->HasAccess(v8::ACCESS_GET)) {
if (it->GetHolder<JSObject>()->IsJSGlobalProxy() && it->HasAccess()) {
break;
}
return;
......
......@@ -735,8 +735,7 @@ static inline AccessCheckInfo* GetAccessCheckInfo(Isolate* isolate,
}
void Isolate::ReportFailedAccessCheck(Handle<JSObject> receiver,
v8::AccessType type) {
void Isolate::ReportFailedAccessCheck(Handle<JSObject> receiver) {
if (!thread_local_top()->failed_access_check_callback_) {
Handle<String> message = factory()->InternalizeUtf8String("no access");
ScheduleThrow(*factory()->NewTypeError(message));
......@@ -758,40 +757,7 @@ void Isolate::ReportFailedAccessCheck(Handle<JSObject> receiver,
// Leaving JavaScript.
VMState<EXTERNAL> state(this);
thread_local_top()->failed_access_check_callback_(
v8::Utils::ToLocal(receiver),
type,
v8::Utils::ToLocal(data));
}
enum MayAccessDecision {
YES, NO, UNKNOWN
};
static MayAccessDecision MayAccessPreCheck(Isolate* isolate,
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();
if (!receiver_context->IsContext()) return NO;
// Get the native context of current top context.
// avoid using Isolate::native_context() because it uses Handle.
Context* native_context =
isolate->context()->global_object()->native_context();
if (receiver_context == native_context) return YES;
if (Context::cast(receiver_context)->security_token() ==
native_context->security_token())
return YES;
}
return UNKNOWN;
v8::Utils::ToLocal(receiver), v8::ACCESS_HAS, v8::Utils::ToLocal(data));
}
......@@ -807,21 +773,33 @@ bool Isolate::IsInternallyUsedPropertyName(Object* name) {
}
bool Isolate::MayNamedAccess(Handle<JSObject> receiver,
Handle<Object> key,
v8::AccessType type) {
bool Isolate::MayAccess(Handle<JSObject> receiver) {
DCHECK(receiver->IsJSGlobalProxy() || receiver->IsAccessCheckNeeded());
// Skip checks for internally used properties. Note, we do not
// require existence of a context in this case.
if (IsInternallyUsedPropertyName(key)) return true;
// Check for compatibility between the security tokens in the
// current lexical context and the accessed object.
DCHECK(context());
MayAccessDecision decision = MayAccessPreCheck(this, receiver, type);
if (decision != UNKNOWN) return decision == YES;
{
DisallowHeapAllocation no_gc;
// During bootstrapping, callback functions are not enabled yet.
if (bootstrapper()->IsActive()) return true;
if (receiver->IsJSGlobalProxy()) {
Object* receiver_context =
JSGlobalProxy::cast(*receiver)->native_context();
if (!receiver_context->IsContext()) return false;
// Get the native context of current top context.
// avoid using Isolate::native_context() because it uses Handle.
Context* native_context = context()->global_object()->native_context();
if (receiver_context == native_context) return true;
if (Context::cast(receiver_context)->security_token() ==
native_context->security_token())
return true;
}
}
HandleScope scope(this);
Handle<Object> data;
......@@ -835,47 +813,13 @@ bool Isolate::MayNamedAccess(Handle<JSObject> receiver,
data = handle(access_check_info->data(), this);
}
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(Handle<JSObject> receiver,
uint32_t index,
v8::AccessType type) {
DCHECK(receiver->IsJSGlobalProxy() || receiver->IsAccessCheckNeeded());
// Check for compatibility between the security tokens in the
// current lexical context and the accessed object.
DCHECK(context());
MayAccessDecision decision = MayAccessPreCheck(this, receiver, type);
if (decision != UNKNOWN) return decision == YES;
HandleScope scope(this);
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);
}
LOG(this, ApiIndexedSecurityCheck(index));
LOG(this, ApiSecurityCheck());
// Leaving JavaScript.
VMState<EXTERNAL> state(this);
return callback(
v8::Utils::ToLocal(receiver), index, type, v8::Utils::ToLocal(data));
Handle<Object> key = factory()->undefined_value();
return callback(v8::Utils::ToLocal(receiver), v8::Utils::ToLocal(key),
v8::ACCESS_HAS, v8::Utils::ToLocal(data));
}
......
......@@ -745,17 +745,12 @@ class Isolate {
// the result is false, the pending exception is guaranteed to be
// set.
bool MayNamedAccess(Handle<JSObject> receiver,
Handle<Object> key,
v8::AccessType type);
bool MayIndexedAccess(Handle<JSObject> receiver,
uint32_t index,
v8::AccessType type);
bool MayAccess(Handle<JSObject> receiver);
bool IsInternallyUsedPropertyName(Handle<Object> name);
bool IsInternallyUsedPropertyName(Object* name);
void SetFailedAccessCheckCallback(v8::FailedAccessCheckCallback callback);
void ReportFailedAccessCheck(Handle<JSObject> receiver, v8::AccessType type);
void ReportFailedAccessCheck(Handle<JSObject> receiver);
// Exception throwing support. The caller should use the result
// of Throw() as its return value.
......
......@@ -876,27 +876,9 @@ void Logger::ApiEvent(const char* format, ...) {
}
void Logger::ApiNamedSecurityCheck(Object* key) {
void Logger::ApiSecurityCheck() {
if (!log_->IsEnabled() || !FLAG_log_api) return;
if (key->IsString()) {
SmartArrayPointer<char> str =
String::cast(key)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
ApiEvent("api,check-security,\"%s\"", str.get());
} else if (key->IsSymbol()) {
Symbol* symbol = Symbol::cast(key);
if (symbol->name()->IsUndefined()) {
ApiEvent("api,check-security,symbol(hash %x)", Symbol::cast(key)->Hash());
} else {
SmartArrayPointer<char> str = String::cast(symbol->name())->ToCString(
DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
ApiEvent("api,check-security,symbol(\"%s\" hash %x)", str.get(),
Symbol::cast(key)->Hash());
}
} else if (key->IsUndefined()) {
ApiEvent("api,check-security,undefined");
} else {
ApiEvent("api,check-security,['no-name']");
}
ApiEvent("api,check-security");
}
......@@ -1029,12 +1011,6 @@ void Logger::RegExpCompileEvent(Handle<JSRegExp> regexp, bool in_cache) {
}
void Logger::ApiIndexedSecurityCheck(uint32_t index) {
if (!log_->IsEnabled() || !FLAG_log_api) return;
ApiEvent("api,check-security,%u", index);
}
void Logger::ApiNamedPropertyAccess(const char* tag,
JSObject* holder,
Object* name) {
......
......@@ -210,8 +210,7 @@ class Logger {
// ==== Events logged by --log-api. ====
void ApiNamedSecurityCheck(Object* key);
void ApiIndexedSecurityCheck(uint32_t index);
void ApiSecurityCheck();
void ApiNamedPropertyAccess(const char* tag, JSObject* holder, Object* name);
void ApiIndexedPropertyAccess(const char* tag,
JSObject* holder,
......
......@@ -72,9 +72,9 @@ bool LookupIterator::IsBootstrapping() const {
}
bool LookupIterator::HasAccess(v8::AccessType access_type) const {
bool LookupIterator::HasAccess() const {
DCHECK_EQ(ACCESS_CHECK, state_);
return isolate_->MayNamedAccess(GetHolder<JSObject>(), name_, access_type);
return isolate_->MayAccess(GetHolder<JSObject>());
}
......
......@@ -99,7 +99,7 @@ class LookupIterator FINAL BASE_EMBEDDED {
bool HolderIsReceiverOrHiddenPrototype() const;
/* ACCESS_CHECK */
bool HasAccess(v8::AccessType access_type) const;
bool HasAccess() const;
/* PROPERTY */
void PrepareForDataProperty(Handle<Object> value);
......
This diff is collapsed.
......@@ -223,9 +223,8 @@ RUNTIME_FUNCTION(Runtime_ClassGetSourceCode) {
static Object* LoadFromSuper(Isolate* isolate, Handle<Object> receiver,
Handle<JSObject> home_object, Handle<Name> name) {
if (home_object->IsAccessCheckNeeded() &&
!isolate->MayNamedAccess(home_object, name, v8::ACCESS_GET)) {
isolate->ReportFailedAccessCheck(home_object, v8::ACCESS_GET);
if (home_object->IsAccessCheckNeeded() && !isolate->MayAccess(home_object)) {
isolate->ReportFailedAccessCheck(home_object);
RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
}
......@@ -243,9 +242,8 @@ static Object* LoadFromSuper(Isolate* isolate, Handle<Object> receiver,
static Object* LoadElementFromSuper(Isolate* isolate, Handle<Object> receiver,
Handle<JSObject> home_object,
uint32_t index) {
if (home_object->IsAccessCheckNeeded() &&
!isolate->MayIndexedAccess(home_object, index, v8::ACCESS_GET)) {
isolate->ReportFailedAccessCheck(home_object, v8::ACCESS_GET);
if (home_object->IsAccessCheckNeeded() && !isolate->MayAccess(home_object)) {
isolate->ReportFailedAccessCheck(home_object);
RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
}
......@@ -297,9 +295,8 @@ RUNTIME_FUNCTION(Runtime_LoadKeyedFromSuper) {
static Object* StoreToSuper(Isolate* isolate, Handle<JSObject> home_object,
Handle<Object> receiver, Handle<Name> name,
Handle<Object> value, LanguageMode language_mode) {
if (home_object->IsAccessCheckNeeded() &&
!isolate->MayNamedAccess(home_object, name, v8::ACCESS_SET)) {
isolate->ReportFailedAccessCheck(home_object, v8::ACCESS_SET);
if (home_object->IsAccessCheckNeeded() && !isolate->MayAccess(home_object)) {
isolate->ReportFailedAccessCheck(home_object);
RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
}
......@@ -322,9 +319,8 @@ static Object* StoreElementToSuper(Isolate* isolate,
Handle<Object> receiver, uint32_t index,
Handle<Object> value,
LanguageMode language_mode) {
if (home_object->IsAccessCheckNeeded() &&
!isolate->MayIndexedAccess(home_object, index, v8::ACCESS_SET)) {
isolate->ReportFailedAccessCheck(home_object, v8::ACCESS_SET);
if (home_object->IsAccessCheckNeeded() && !isolate->MayAccess(home_object)) {
isolate->ReportFailedAccessCheck(home_object);
RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
}
......
......@@ -249,12 +249,10 @@ MaybeHandle<Object> Runtime::GetPrototype(Isolate* isolate,
PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER);
do {
if (PrototypeIterator::GetCurrent(iter)->IsAccessCheckNeeded() &&
!isolate->MayNamedAccess(
Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)),
isolate->factory()->proto_string(), v8::ACCESS_GET)) {
!isolate->MayAccess(
Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)))) {
isolate->ReportFailedAccessCheck(
Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)),
v8::ACCESS_GET);
Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)));
RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
return isolate->factory()->undefined_value();
}
......@@ -297,10 +295,8 @@ RUNTIME_FUNCTION(Runtime_SetPrototype) {
DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
if (obj->IsAccessCheckNeeded() &&
!isolate->MayNamedAccess(obj, isolate->factory()->proto_string(),
v8::ACCESS_SET)) {
isolate->ReportFailedAccessCheck(obj, v8::ACCESS_SET);
if (obj->IsAccessCheckNeeded() && !isolate->MayAccess(obj)) {
isolate->ReportFailedAccessCheck(obj);
RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
return isolate->heap()->undefined_value();
}
......@@ -917,10 +913,8 @@ RUNTIME_FUNCTION(Runtime_GetOwnPropertyNames) {
// real global object.
if (obj->IsJSGlobalProxy()) {
// Only collect names if access is permitted.
if (obj->IsAccessCheckNeeded() &&
!isolate->MayNamedAccess(obj, isolate->factory()->undefined_value(),
v8::ACCESS_KEYS)) {
isolate->ReportFailedAccessCheck(obj, v8::ACCESS_KEYS);
if (obj->IsAccessCheckNeeded() && !isolate->MayAccess(obj)) {
isolate->ReportFailedAccessCheck(obj);
RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
return *isolate->factory()->NewJSArray(0);
}
......@@ -941,11 +935,8 @@ RUNTIME_FUNCTION(Runtime_GetOwnPropertyNames) {
Handle<JSObject> jsproto =
Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
// Only collect names if access is permitted.
if (jsproto->IsAccessCheckNeeded() &&
!isolate->MayNamedAccess(jsproto,
isolate->factory()->undefined_value(),
v8::ACCESS_KEYS)) {
isolate->ReportFailedAccessCheck(jsproto, v8::ACCESS_KEYS);
if (jsproto->IsAccessCheckNeeded() && !isolate->MayAccess(jsproto)) {
isolate->ReportFailedAccessCheck(jsproto);
RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
return *isolate->factory()->NewJSArray(0);
}
......@@ -1094,10 +1085,8 @@ RUNTIME_FUNCTION(Runtime_OwnKeys) {
if (object->IsJSGlobalProxy()) {
// Do access checks before going to the global object.
if (object->IsAccessCheckNeeded() &&
!isolate->MayNamedAccess(object, isolate->factory()->undefined_value(),
v8::ACCESS_KEYS)) {
isolate->ReportFailedAccessCheck(object, v8::ACCESS_KEYS);
if (object->IsAccessCheckNeeded() && !isolate->MayAccess(object)) {
isolate->ReportFailedAccessCheck(object);
RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
return *isolate->factory()->NewJSArray(0);
}
......@@ -1442,7 +1431,7 @@ RUNTIME_FUNCTION(Runtime_DefineDataPropertyUnchecked) {
LookupIterator it(js_object, name, LookupIterator::OWN_SKIP_INTERCEPTOR);
if (it.IsFound() && it.state() == LookupIterator::ACCESS_CHECK) {
if (!isolate->MayNamedAccess(js_object, name, v8::ACCESS_SET)) {
if (!isolate->MayAccess(js_object)) {
return isolate->heap()->undefined_value();
}
it.Next();
......
......@@ -2934,16 +2934,8 @@ struct AccessCheckData {
};
bool SimpleNamedAccessChecker(Local<v8::Object> global, Local<Value> name,
v8::AccessType type, Local<Value> data) {
auto access_check_data = GetWrappedObject<AccessCheckData>(data);
access_check_data->count++;
return access_check_data->result;
}
bool SimpleIndexedAccessChecker(Local<v8::Object> global, uint32_t index,
v8::AccessType type, Local<Value> data) {
bool SimpleAccessChecker(Local<v8::Object> global, Local<Value> name,
v8::AccessType type, Local<Value> data) {
auto access_check_data = GetWrappedObject<AccessCheckData>(data);
access_check_data->count++;
return access_check_data->result;
......@@ -3015,7 +3007,7 @@ THREADED_TEST(NamedAllCanReadInterceptor) {
auto checked = v8::ObjectTemplate::New(isolate);
checked->SetAccessCheckCallbacks(
SimpleNamedAccessChecker, nullptr,
SimpleAccessChecker, nullptr,
BuildWrappedObject<AccessCheckData>(isolate, &access_check_data), false);
context->Global()->Set(v8_str("intercepted_0"), intercepted_0->NewInstance());
......@@ -3081,7 +3073,7 @@ THREADED_TEST(IndexedAllCanReadInterceptor) {
auto checked = v8::ObjectTemplate::New(isolate);
checked->SetAccessCheckCallbacks(
nullptr, SimpleIndexedAccessChecker,
SimpleAccessChecker, nullptr,
BuildWrappedObject<AccessCheckData>(isolate, &access_check_data), false);
context->Global()->Set(v8_str("intercepted_0"), intercepted_0->NewInstance());
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment