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

Side by Side 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, 5 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 unified diff | Download patch
« no previous file with comments | « src/keys.h ('k') | src/lookup.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/keys.h" 5 #include "src/keys.h"
6 6
7 #include "src/api-arguments.h" 7 #include "src/api-arguments.h"
8 #include "src/elements.h" 8 #include "src/elements.h"
9 #include "src/factory.h" 9 #include "src/factory.h"
10 #include "src/identity-map.h" 10 #include "src/identity-map.h"
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 MaybeHandle<FixedArray>()); 423 MaybeHandle<FixedArray>());
424 return accumulator.GetKeys(keys_conversion); 424 return accumulator.GetKeys(keys_conversion);
425 } 425 }
426 426
427 namespace { 427 namespace {
428 428
429 enum IndexedOrNamed { kIndexed, kNamed }; 429 enum IndexedOrNamed { kIndexed, kNamed };
430 430
431 // Returns |true| on success, |nothing| on exception. 431 // Returns |true| on success, |nothing| on exception.
432 template <class Callback, IndexedOrNamed type> 432 template <class Callback, IndexedOrNamed type>
433 Maybe<bool> CollectInterceptorKeysInternal(Handle<JSReceiver> receiver,
434 Handle<JSObject> object,
435 Handle<InterceptorInfo> interceptor,
436 KeyAccumulator* accumulator) {
437 Isolate* isolate = accumulator->isolate();
438 PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
439 *object, Object::DONT_THROW);
440 Handle<JSObject> result;
441 if (!interceptor->enumerator()->IsUndefined(isolate)) {
442 Callback enum_fun = v8::ToCData<Callback>(interceptor->enumerator());
443 const char* log_tag = type == kIndexed ? "interceptor-indexed-enum"
444 : "interceptor-named-enum";
445 LOG(isolate, ApiObjectAccess(log_tag, *object));
446 result = args.Call(enum_fun);
447 }
448 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
449 if (result.is_null()) return Just(true);
450 accumulator->AddKeys(
451 result, type == kIndexed ? CONVERT_TO_ARRAY_INDEX : DO_NOT_CONVERT);
452 return Just(true);
453 }
454
455 template <class Callback, IndexedOrNamed type>
433 Maybe<bool> CollectInterceptorKeys(Handle<JSReceiver> receiver, 456 Maybe<bool> CollectInterceptorKeys(Handle<JSReceiver> receiver,
434 Handle<JSObject> object, 457 Handle<JSObject> object,
435 KeyAccumulator* accumulator) { 458 KeyAccumulator* accumulator) {
436 Isolate* isolate = accumulator->isolate(); 459 Isolate* isolate = accumulator->isolate();
437 if (type == kIndexed) { 460 if (type == kIndexed) {
438 if (!object->HasIndexedInterceptor()) return Just(true); 461 if (!object->HasIndexedInterceptor()) return Just(true);
439 } else { 462 } else {
440 if (!object->HasNamedInterceptor()) return Just(true); 463 if (!object->HasNamedInterceptor()) return Just(true);
441 } 464 }
442 Handle<InterceptorInfo> interceptor(type == kIndexed 465 Handle<InterceptorInfo> interceptor(type == kIndexed
443 ? object->GetIndexedInterceptor() 466 ? object->GetIndexedInterceptor()
444 : object->GetNamedInterceptor(), 467 : object->GetNamedInterceptor(),
445 isolate); 468 isolate);
446 if ((accumulator->filter() & ONLY_ALL_CAN_READ) && 469 if ((accumulator->filter() & ONLY_ALL_CAN_READ) &&
447 !interceptor->all_can_read()) { 470 !interceptor->all_can_read()) {
448 return Just(true); 471 return Just(true);
449 } 472 }
450 PropertyCallbackArguments args(isolate, interceptor->data(), *receiver, 473 return CollectInterceptorKeysInternal<Callback, type>(
451 *object, Object::DONT_THROW); 474 receiver, object, interceptor, accumulator);
452 Handle<JSObject> result;
453 if (!interceptor->enumerator()->IsUndefined(isolate)) {
454 Callback enum_fun = v8::ToCData<Callback>(interceptor->enumerator());
455 const char* log_tag = type == kIndexed ? "interceptor-indexed-enum"
456 : "interceptor-named-enum";
457 LOG(isolate, ApiObjectAccess(log_tag, *object));
458 result = args.Call(enum_fun);
459 }
460 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
461 if (result.is_null()) return Just(true);
462 accumulator->AddKeys(
463 result, type == kIndexed ? CONVERT_TO_ARRAY_INDEX : DO_NOT_CONVERT);
464 return Just(true);
465 } 475 }
466 476
467 } // namespace 477 } // namespace
468 478
469 Maybe<bool> KeyAccumulator::CollectOwnElementIndices( 479 Maybe<bool> KeyAccumulator::CollectOwnElementIndices(
470 Handle<JSReceiver> receiver, Handle<JSObject> object) { 480 Handle<JSReceiver> receiver, Handle<JSObject> object) {
471 if (filter_ & SKIP_STRINGS || skip_indices_) return Just(true); 481 if (filter_ & SKIP_STRINGS || skip_indices_) return Just(true);
472 482
473 ElementsAccessor* accessor = object->GetElementsAccessor(); 483 ElementsAccessor* accessor = object->GetElementsAccessor();
474 accessor->CollectElementIndices(object, this); 484 accessor->CollectElementIndices(object, this);
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
532 } else { 542 } else {
533 NameDictionary::CollectKeysTo( 543 NameDictionary::CollectKeysTo(
534 handle(object->property_dictionary(), isolate_), this, filter_); 544 handle(object->property_dictionary(), isolate_), this, filter_);
535 } 545 }
536 } 546 }
537 // Add the property keys from the interceptor. 547 // Add the property keys from the interceptor.
538 return CollectInterceptorKeys<v8::GenericNamedPropertyEnumeratorCallback, 548 return CollectInterceptorKeys<v8::GenericNamedPropertyEnumeratorCallback,
539 kNamed>(receiver, object, this); 549 kNamed>(receiver, object, this);
540 } 550 }
541 551
552 Maybe<bool> KeyAccumulator::CollectAccessCheckInterceptorKeys(
553 Handle<AccessCheckInfo> access_check_info, Handle<JSReceiver> receiver,
554 Handle<JSObject> object) {
555 MAYBE_RETURN(
556 (CollectInterceptorKeysInternal<v8::IndexedPropertyEnumeratorCallback,
557 kIndexed>(
558 receiver, object,
559 handle(
560 InterceptorInfo::cast(access_check_info->indexed_interceptor()),
561 isolate_),
562 this)),
563 Nothing<bool>());
564 MAYBE_RETURN(
565 (CollectInterceptorKeysInternal<
566 v8::GenericNamedPropertyEnumeratorCallback, kNamed>(
567 receiver, object,
568 handle(InterceptorInfo::cast(access_check_info->named_interceptor()),
569 isolate_),
570 this)),
571 Nothing<bool>());
572 return Just(true);
573 }
574
542 // Returns |true| on success, |false| if prototype walking should be stopped, 575 // Returns |true| on success, |false| if prototype walking should be stopped,
543 // |nothing| if an exception was thrown. 576 // |nothing| if an exception was thrown.
544 Maybe<bool> KeyAccumulator::CollectOwnKeys(Handle<JSReceiver> receiver, 577 Maybe<bool> KeyAccumulator::CollectOwnKeys(Handle<JSReceiver> receiver,
545 Handle<JSObject> object) { 578 Handle<JSObject> object) {
546 // Check access rights if required. 579 // Check access rights if required.
547 if (object->IsAccessCheckNeeded() && 580 if (object->IsAccessCheckNeeded() &&
548 !isolate_->MayAccess(handle(isolate_->context()), object)) { 581 !isolate_->MayAccess(handle(isolate_->context()), object)) {
549 // The cross-origin spec says that [[Enumerate]] shall return an empty 582 // The cross-origin spec says that [[Enumerate]] shall return an empty
550 // iterator when it doesn't have access... 583 // iterator when it doesn't have access...
551 if (mode_ == KeyCollectionMode::kIncludePrototypes) { 584 if (mode_ == KeyCollectionMode::kIncludePrototypes) {
552 return Just(false); 585 return Just(false);
553 } 586 }
554 // ...whereas [[OwnPropertyKeys]] shall return whitelisted properties. 587 // ...whereas [[OwnPropertyKeys]] shall return whitelisted properties.
555 DCHECK(KeyCollectionMode::kOwnOnly == mode_); 588 DCHECK(KeyCollectionMode::kOwnOnly == mode_);
589 Handle<AccessCheckInfo> access_check_info;
590 {
591 DisallowHeapAllocation no_gc;
592 AccessCheckInfo* maybe_info = AccessCheckInfo::Get(isolate_, object);
593 if (maybe_info) access_check_info = handle(maybe_info, isolate_);
594 }
595 // We always have both kinds of interceptors or none.
596 if (!access_check_info.is_null() &&
597 access_check_info->named_interceptor()) {
598 MAYBE_RETURN(CollectAccessCheckInterceptorKeys(access_check_info,
599 receiver, object),
600 Nothing<bool>());
601 return Just(false);
602 }
556 filter_ = static_cast<PropertyFilter>(filter_ | ONLY_ALL_CAN_READ); 603 filter_ = static_cast<PropertyFilter>(filter_ | ONLY_ALL_CAN_READ);
557 } 604 }
558 MAYBE_RETURN(CollectOwnElementIndices(receiver, object), Nothing<bool>()); 605 MAYBE_RETURN(CollectOwnElementIndices(receiver, object), Nothing<bool>());
559 MAYBE_RETURN(CollectOwnPropertyNames(receiver, object), Nothing<bool>()); 606 MAYBE_RETURN(CollectOwnPropertyNames(receiver, object), Nothing<bool>());
560 return Just(true); 607 return Just(true);
561 } 608 }
562 609
563 // static 610 // static
564 Handle<FixedArray> KeyAccumulator::GetEnumPropertyKeys( 611 Handle<FixedArray> KeyAccumulator::GetEnumPropertyKeys(
565 Isolate* isolate, Handle<JSObject> object) { 612 Isolate* isolate, Handle<JSObject> object) {
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
741 isolate_, keys, JSReceiver::OwnPropertyKeys(target), Nothing<bool>()); 788 isolate_, keys, JSReceiver::OwnPropertyKeys(target), Nothing<bool>());
742 bool prev_filter_proxy_keys_ = filter_proxy_keys_; 789 bool prev_filter_proxy_keys_ = filter_proxy_keys_;
743 filter_proxy_keys_ = false; 790 filter_proxy_keys_ = false;
744 Maybe<bool> result = AddKeysFromJSProxy(proxy, keys); 791 Maybe<bool> result = AddKeysFromJSProxy(proxy, keys);
745 filter_proxy_keys_ = prev_filter_proxy_keys_; 792 filter_proxy_keys_ = prev_filter_proxy_keys_;
746 return result; 793 return result;
747 } 794 }
748 795
749 } // namespace internal 796 } // namespace internal
750 } // namespace v8 797 } // namespace v8
OLDNEW
« no previous file with comments | « src/keys.h ('k') | src/lookup.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698