[builtins] take slow path in IsConcatSpreadable if proxy in prototype
BUG=v8:5134 R=cbruni@chromium.org, littledan@chromium.org, neis@chromium.org Review-Url: https://codereview.chromium.org/2131383002 Cr-Commit-Position: refs/heads/master@{#37987}
This commit is contained in:
parent
7883414e8b
commit
122a9b7af0
@ -938,7 +938,7 @@ bool IterateElements(Isolate* isolate, Handle<JSReceiver> receiver,
|
||||
static Maybe<bool> IsConcatSpreadable(Isolate* isolate, Handle<Object> obj) {
|
||||
HandleScope handle_scope(isolate);
|
||||
if (!obj->IsJSReceiver()) return Just(false);
|
||||
if (!isolate->IsIsConcatSpreadableLookupChainIntact()) {
|
||||
if (!isolate->IsIsConcatSpreadableLookupChainIntact(JSReceiver::cast(*obj))) {
|
||||
// Slow path if @@isConcatSpreadable has been used.
|
||||
Handle<Symbol> key(isolate->factory()->is_concat_spreadable_symbol());
|
||||
Handle<Object> value;
|
||||
|
@ -2685,6 +2685,11 @@ bool Isolate::IsIsConcatSpreadableLookupChainIntact() {
|
||||
return !is_is_concat_spreadable_set;
|
||||
}
|
||||
|
||||
bool Isolate::IsIsConcatSpreadableLookupChainIntact(JSReceiver* receiver) {
|
||||
if (!IsIsConcatSpreadableLookupChainIntact()) return false;
|
||||
return !receiver->HasProxyInPrototype(this);
|
||||
}
|
||||
|
||||
void Isolate::UpdateArrayProtectorOnSetElement(Handle<JSObject> object) {
|
||||
DisallowHeapAllocation no_gc;
|
||||
if (!object->map()->is_prototype_map()) return;
|
||||
|
@ -985,6 +985,7 @@ class Isolate {
|
||||
inline bool IsArraySpeciesLookupChainIntact();
|
||||
inline bool IsHasInstanceLookupChainIntact();
|
||||
bool IsIsConcatSpreadableLookupChainIntact();
|
||||
bool IsIsConcatSpreadableLookupChainIntact(JSReceiver* receiver);
|
||||
|
||||
// On intent to set an element in object, make sure that appropriate
|
||||
// notifications occur if the set is on the elements of the array or
|
||||
|
@ -18986,5 +18986,14 @@ AccessCheckInfo* AccessCheckInfo::Get(Isolate* isolate,
|
||||
return AccessCheckInfo::cast(data_obj);
|
||||
}
|
||||
|
||||
bool JSReceiver::HasProxyInPrototype(Isolate* isolate) {
|
||||
for (PrototypeIterator iter(isolate, this, kStartAtReceiver,
|
||||
PrototypeIterator::END_AT_NULL);
|
||||
!iter.IsAtEnd(); iter.AdvanceIgnoringProxies()) {
|
||||
if (iter.GetCurrent<Object>()->IsJSProxy()) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
@ -2008,6 +2008,8 @@ class JSReceiver: public HeapObject {
|
||||
static const int kPropertiesOffset = HeapObject::kHeaderSize;
|
||||
static const int kHeaderSize = HeapObject::kHeaderSize + kPointerSize;
|
||||
|
||||
bool HasProxyInPrototype(Isolate* isolate);
|
||||
|
||||
private:
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(JSReceiver);
|
||||
};
|
||||
|
@ -872,3 +872,25 @@ logger.get = function(t, trap, r) {
|
||||
assertThrows(() => [].concat(obj), TypeError);
|
||||
assertThrows(() => Array.prototype.concat.apply(obj), TypeError);
|
||||
})();
|
||||
|
||||
(function testConcatRevokedProxy() {
|
||||
"use strict";
|
||||
var target = [];
|
||||
var handler = {
|
||||
get(_, name) {
|
||||
if (name === Symbol.isConcatSpreadable) {
|
||||
p.revoke();
|
||||
}
|
||||
return target[name];
|
||||
}
|
||||
}
|
||||
|
||||
p = Proxy.revocable(target, handler);
|
||||
target = {};
|
||||
target.__proto__ = p.proxy;
|
||||
assertThrows(function() { [].concat({ __proto__: p.proxy }); }, TypeError);
|
||||
|
||||
target = [];
|
||||
var p = Proxy.revocable(target, handler);
|
||||
assertThrows(function() { [].concat(p.proxy); }, TypeError);
|
||||
})();
|
||||
|
@ -406,9 +406,6 @@
|
||||
'annexB/built-ins/Object/prototype/__lookupSetter__/lookup-proto-get-err': [FAIL],
|
||||
'annexB/built-ins/Object/prototype/__lookupSetter__/lookup-proto-proto-err': [FAIL],
|
||||
|
||||
# https://bugs.chromium.org/p/v8/issues/detail?id=5134
|
||||
'built-ins/Array/prototype/concat/is-concat-spreadable-is-array-proxy-revoked': [FAIL],
|
||||
|
||||
# https://bugs.chromium.org/p/v8/issues/detail?id=4451
|
||||
'annexB/language/eval-code/direct/global-block-decl-eval-global-exsting-global-init': [FAIL],
|
||||
'annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-exsting-global-init': [FAIL],
|
||||
|
Loading…
Reference in New Issue
Block a user