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

Unified Diff: src/objects.cc

Issue 1491743008: [proxies] Add all-can-read/String/Symbol filtering support to GetKeys() (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: critical correctness fix ;-) Created 5 years 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/key-accumulator.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index 3f028c62824a35653bdc4ef03b265f6eedd4413e..4876568ea474017d8a1decfa18489ac856468f90 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -8101,29 +8101,83 @@ Handle<FixedArray> JSObject::GetEnumPropertyKeys(Handle<JSObject> object,
}
+enum IndexedOrNamed { kIndexed, kNamed };
+
+
+// Returns false iff there was an exception.
+template <class Callback, IndexedOrNamed type>
+static bool GetKeysFromInterceptor(Isolate* isolate,
+ Handle<JSReceiver> receiver,
+ Handle<JSObject> object,
+ PropertyFilter filter,
+ KeyAccumulator* accumulator) {
+ if (type == kIndexed) {
+ if (!object->HasIndexedInterceptor()) return true;
+ } else {
+ if (!object->HasNamedInterceptor()) return true;
+ }
+ Handle<InterceptorInfo> interceptor(type == kIndexed
+ ? object->GetIndexedInterceptor()
+ : object->GetNamedInterceptor(),
+ isolate);
+ if ((filter & ONLY_ALL_CAN_READ) && !interceptor->all_can_read()) {
+ return true;
+ }
+ PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
+ *object);
+ v8::Local<v8::Object> result;
+ if (!interceptor->enumerator()->IsUndefined()) {
+ Callback enum_fun = v8::ToCData<Callback>(interceptor->enumerator());
+ const char* log_tag = type == kIndexed ? "interceptor-indexed-enum"
+ : "interceptor-named-enum";
+ LOG(isolate, ApiObjectAccess(log_tag, *object));
+ result = args.Call(enum_fun);
+ }
+ RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, false);
+ if (result.IsEmpty()) return true;
+ DCHECK(v8::Utils::OpenHandle(*result)->IsJSArray() ||
+ (v8::Utils::OpenHandle(*result)->IsJSObject() &&
+ Handle<JSObject>::cast(v8::Utils::OpenHandle(*result))
+ ->HasSloppyArgumentsElements()));
+ // The accumulator takes care of string/symbol filtering.
+ if (type == kIndexed) {
+ accumulator->AddElementKeysFromInterceptor(
+ Handle<JSObject>::cast(v8::Utils::OpenHandle(*result)));
+ } else {
+ accumulator->AddKeys(
+ Handle<JSObject>::cast(v8::Utils::OpenHandle(*result)));
+ }
+ return true;
+}
+
+
static bool GetKeysFromJSObject(Isolate* isolate, Handle<JSReceiver> receiver,
Handle<JSObject> object, PropertyFilter filter,
+ JSReceiver::KeyCollectionType type,
KeyAccumulator* accumulator) {
accumulator->NextPrototype();
+ bool keep_going = true;
// Check access rights if required.
if (object->IsAccessCheckNeeded() &&
!isolate->MayAccess(handle(isolate->context()), object)) {
- // TODO(jkummerow): Get whitelisted (all-can-read) keys.
- // It's probably best to implement a "GetKeysWithFailedAccessCheck"
- // helper, which will need to look at both interceptors and accessors.
- return false;
+ // The cross-origin spec says that [[Enumerate]] shall return an empty
+ // iterator when it doesn't have access...
+ if (type == JSReceiver::INCLUDE_PROTOS) {
+ return false;
+ }
+ // ...whereas [[OwnPropertyKeys]] shall return whitelisted properties.
+ DCHECK(type == JSReceiver::OWN_ONLY);
+ filter = static_cast<PropertyFilter>(filter | ONLY_ALL_CAN_READ);
+ keep_going = false;
}
JSObject::CollectOwnElementKeys(object, accumulator, filter);
// Add the element keys from the interceptor.
- if (object->HasIndexedInterceptor()) {
- Handle<JSObject> result;
- if (JSObject::GetKeysForIndexedInterceptor(object, receiver)
- .ToHandle(&result)) {
- accumulator->AddElementKeysFromInterceptor(result);
- }
- RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, false);
+ if (!GetKeysFromInterceptor<v8::IndexedPropertyEnumeratorCallback, kIndexed>(
+ isolate, receiver, object, filter, accumulator)) {
+ DCHECK(isolate->has_pending_exception());
+ return false;
}
if (filter == ENUMERABLE_STRINGS) {
@@ -8152,15 +8206,13 @@ static bool GetKeysFromJSObject(Isolate* isolate, Handle<JSReceiver> receiver,
}
// Add the property keys from the interceptor.
- if (object->HasNamedInterceptor()) {
- Handle<JSObject> result;
- if (JSObject::GetKeysForNamedInterceptor(object, receiver)
- .ToHandle(&result)) {
- accumulator->AddKeys(result);
- }
- RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, false);
+ if (!GetKeysFromInterceptor<v8::GenericNamedPropertyEnumeratorCallback,
+ kNamed>(isolate, receiver, object, filter,
+ accumulator)) {
+ DCHECK(isolate->has_pending_exception());
+ return false;
}
- return true;
+ return keep_going;
}
@@ -8194,7 +8246,7 @@ static bool GetKeys_Internal(Isolate* isolate, Handle<JSReceiver> receiver,
DCHECK(current->IsJSObject());
result = GetKeysFromJSObject(isolate, receiver,
Handle<JSObject>::cast(current), filter,
- accumulator);
+ type, accumulator);
}
if (!result) {
if (isolate->has_pending_exception()) {
@@ -15596,6 +15648,7 @@ MaybeHandle<Object> JSObject::GetPropertyWithInterceptor(LookupIterator* it,
// Compute the property keys from the interceptor.
+// TODO(jkummerow): Deprecated.
MaybeHandle<JSObject> JSObject::GetKeysForNamedInterceptor(
Handle<JSObject> object, Handle<JSReceiver> receiver) {
Isolate* isolate = receiver->GetIsolate();
@@ -15621,6 +15674,7 @@ MaybeHandle<JSObject> JSObject::GetKeysForNamedInterceptor(
// Compute the element keys from the interceptor.
+// TODO(jkummerow): Deprecated.
MaybeHandle<JSObject> JSObject::GetKeysForIndexedInterceptor(
Handle<JSObject> object, Handle<JSReceiver> receiver) {
Isolate* isolate = receiver->GetIsolate();
@@ -15837,7 +15891,14 @@ void JSObject::CollectOwnPropertyNames(KeyAccumulator* keys,
int real_size = map()->NumberOfOwnDescriptors();
Handle<DescriptorArray> descs(map()->instance_descriptors());
for (int i = 0; i < real_size; i++) {
- if ((descs->GetDetails(i).attributes() & filter) != 0) continue;
+ PropertyDetails details = descs->GetDetails(i);
+ if ((details.attributes() & filter) != 0) continue;
+ if (filter & ONLY_ALL_CAN_READ) {
+ if (details.kind() != kAccessor) continue;
+ Object* accessors = descs->GetValue(i);
+ if (!accessors->IsAccessorInfo()) continue;
+ if (!AccessorInfo::cast(accessors)->all_can_read()) continue;
+ }
Name* key = descs->GetKey(i);
if (key->FilterKey(filter)) continue;
keys->AddKey(key);
@@ -15873,6 +15934,7 @@ int JSObject::NumberOfEnumElements() {
void JSObject::CollectOwnElementKeys(Handle<JSObject> object,
KeyAccumulator* keys,
PropertyFilter filter) {
+ if (filter & SKIP_STRINGS) return;
uint32_t string_keys = 0;
// If this is a String wrapper, add the string indices first,
@@ -15880,7 +15942,7 @@ void JSObject::CollectOwnElementKeys(Handle<JSObject> object,
// and ascending order is required by ECMA-262, 6th, 9.1.12.
if (object->IsJSValue()) {
Object* val = JSValue::cast(*object)->value();
- if (val->IsString()) {
+ if (val->IsString() && (filter & ONLY_ALL_CAN_READ) == 0) {
String* str = String::cast(val);
string_keys = str->length();
for (uint32_t i = 0; i < string_keys; i++) {
@@ -17836,8 +17898,13 @@ void Dictionary<Derived, Shape, Key>::CollectKeysTo(
if (!raw_dict->IsKey(k) || k->FilterKey(filter)) continue;
if (raw_dict->IsDeleted(i)) continue;
PropertyDetails details = raw_dict->DetailsAt(i);
- PropertyAttributes attr = details.attributes();
- if ((attr & filter) != 0) continue;
+ if ((details.attributes() & filter) != 0) continue;
+ if (filter & ONLY_ALL_CAN_READ) {
+ if (details.kind() != kAccessor) continue;
+ Object* accessors = raw_dict->ValueAt(i);
+ if (!accessors->IsAccessorInfo()) continue;
+ if (!AccessorInfo::cast(accessors)->all_can_read()) continue;
+ }
array->set(array_size++, Smi::FromInt(i));
}
« no previous file with comments | « src/key-accumulator.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698