Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1625)

Unified Diff: src/keys.cc

Issue 2087823002: Optionally invoke an interceptor on failed access checks (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: updates Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/isolate.cc ('k') | src/lookup.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/keys.cc
diff --git a/src/keys.cc b/src/keys.cc
index eee015075a584871fcb0aba448d63aca94601740..61e0589fffff25259a11897e4d6711a7c46f1c85 100644
--- a/src/keys.cc
+++ b/src/keys.cc
@@ -434,18 +434,30 @@ Maybe<bool> CollectInterceptorKeys(Handle<JSReceiver> receiver,
Handle<JSObject> object,
KeyAccumulator* accumulator) {
Isolate* isolate = accumulator->isolate();
- if (type == kIndexed) {
- if (!object->HasIndexedInterceptor()) return Just(true);
+ Handle<InterceptorInfo> interceptor;
+ if ((accumulator->filter() & USE_ACCESS_CHECK_INTERCEPTOR) &&
+ object->IsAccessCheckNeeded()) {
+ DisallowHeapAllocation no_gc;
+ AccessCheckInfo* access_check_info = AccessCheckInfo::Get(isolate, object);
+ if (!access_check_info) return Just(true);
+ Object* maybe_interceptor = type == kIndexed
+ ? access_check_info->indexed_interceptor()
+ : access_check_info->named_interceptor();
+ if (!maybe_interceptor) return Just(true);
+ interceptor = handle(InterceptorInfo::cast(maybe_interceptor), isolate);
} else {
- if (!object->HasNamedInterceptor()) return Just(true);
- }
- Handle<InterceptorInfo> interceptor(type == kIndexed
- ? object->GetIndexedInterceptor()
+ if (type == kIndexed) {
+ if (!object->HasIndexedInterceptor()) return Just(true);
+ } else {
+ if (!object->HasNamedInterceptor()) return Just(true);
+ }
+ interceptor = handle(type == kIndexed ? object->GetIndexedInterceptor()
: object->GetNamedInterceptor(),
- isolate);
- if ((accumulator->filter() & ONLY_ALL_CAN_READ) &&
- !interceptor->all_can_read()) {
- return Just(true);
+ isolate);
+ if ((accumulator->filter() & ONLY_ALL_CAN_READ) &&
+ !interceptor->all_can_read()) {
+ return Just(true);
+ }
}
PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
*object, Object::DONT_THROW);
@@ -484,6 +496,7 @@ int CollectOwnPropertyNamesInternal(Handle<JSObject> object,
KeyAccumulator* keys,
Handle<DescriptorArray> descs,
int start_index, int limit) {
+ DCHECK(!(keys->filter() & USE_ACCESS_CHECK_INTERCEPTOR));
int first_skipped = -1;
for (int i = start_index; i < limit; i++) {
PropertyDetails details = descs->GetDetails(i);
@@ -513,7 +526,7 @@ Maybe<bool> KeyAccumulator::CollectOwnPropertyNames(Handle<JSReceiver> receiver,
Handle<FixedArray> enum_keys =
KeyAccumulator::GetEnumPropertyKeys(isolate_, object);
AddKeys(enum_keys, DO_NOT_CONVERT);
- } else {
+ } else if (!(filter_ & USE_ACCESS_CHECK_INTERCEPTOR)) {
if (object->HasFastProperties()) {
int limit = object->map()->NumberOfOwnDescriptors();
Handle<DescriptorArray> descs(object->map()->instance_descriptors(),
@@ -546,6 +559,8 @@ Maybe<bool> KeyAccumulator::CollectOwnKeys(Handle<JSReceiver> receiver,
// Check access rights if required.
if (object->IsAccessCheckNeeded() &&
!isolate_->MayAccess(handle(isolate_->context()), object)) {
+ DisallowHeapAllocation no_gc;
+
// The cross-origin spec says that [[Enumerate]] shall return an empty
// iterator when it doesn't have access...
if (mode_ == KeyCollectionMode::kIncludePrototypes) {
@@ -553,7 +568,14 @@ Maybe<bool> KeyAccumulator::CollectOwnKeys(Handle<JSReceiver> receiver,
}
// ...whereas [[OwnPropertyKeys]] shall return whitelisted properties.
DCHECK(KeyCollectionMode::kOwnOnly == mode_);
- filter_ = static_cast<PropertyFilter>(filter_ | ONLY_ALL_CAN_READ);
+ AccessCheckInfo* access_check_info = AccessCheckInfo::Get(isolate_, object);
+ // We always either have both a named and an indexed interceptor or none.
+ if (!access_check_info || !access_check_info->named_interceptor()) {
+ filter_ = static_cast<PropertyFilter>(filter_ | ONLY_ALL_CAN_READ);
+ } else {
+ filter_ =
+ static_cast<PropertyFilter>(filter_ | USE_ACCESS_CHECK_INTERCEPTOR);
Toon Verwaest 2016/06/27 09:34:58 We should get rid of these filters. Just duplicate
Toon Verwaest 2016/06/27 09:37:59 I think you basically want to reuse the lower half
+ }
}
MAYBE_RETURN(CollectOwnElementIndices(receiver, object), Nothing<bool>());
MAYBE_RETURN(CollectOwnPropertyNames(receiver, object), Nothing<bool>());
@@ -563,6 +585,8 @@ Maybe<bool> KeyAccumulator::CollectOwnKeys(Handle<JSReceiver> receiver,
// static
Handle<FixedArray> KeyAccumulator::GetEnumPropertyKeys(
Isolate* isolate, Handle<JSObject> object) {
+ DCHECK(!object->IsAccessCheckNeeded() ||
+ isolate->MayAccess(handle(isolate->context()), object));
if (object->HasFastProperties()) {
return GetFastEnumPropertyKeys(isolate, object);
} else if (object->IsJSGlobalObject()) {
« no previous file with comments | « src/isolate.cc ('k') | src/lookup.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698