Commit 112e924d authored by legendecas's avatar legendecas Committed by V8 LUCI CQ

[runtime] Prevent performing GetOwnPropertyDescriptor on excluded keys

Excluded keys should not be performed with GetOwnPropertyDescriptor on
source object in CopyDataProperties.

The key values fetch in CopyDataProperties might be arbitrary kind. It
may be smi, string, and symbol. Yet the proxy keys collected by
KeyAccumulator are not expected types for numeric keys. Those keys
should be converted to expected types.

Also updates a typo in comments of
BytecodeGenerator::BuildDestructuringObjectAssignment. The elements in
rest_runtime_callargs should be [value, ...excluded_properties].

Refs: https://tc39.es/ecma262/#sec-copydataproperties
Bug: v8:11532
Change-Id: If71bfedf8272ce8405e8566a016fae66b3007dd9
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3060275Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/master@{#76171}
parent 5acd927b
...@@ -4197,7 +4197,7 @@ void BytecodeGenerator::BuildDestructuringArrayAssignment( ...@@ -4197,7 +4197,7 @@ void BytecodeGenerator::BuildDestructuringArrayAssignment(
// var rest_runtime_callargs = new Array(3); // var rest_runtime_callargs = new Array(3);
// rest_runtime_callargs[0] = value; // rest_runtime_callargs[0] = value;
// //
// rest_runtime_callargs[1] = value; // rest_runtime_callargs[1] = "y";
// y = value.y; // y = value.y;
// //
// var temp1 = %ToName(x++); // var temp1 = %ToName(x++);
......
...@@ -303,6 +303,8 @@ V8_WARN_UNUSED_RESULT Maybe<bool> FastAssign( ...@@ -303,6 +303,8 @@ V8_WARN_UNUSED_RESULT Maybe<bool> FastAssign(
descriptors.PatchValue(map->instance_descriptors(isolate)); descriptors.PatchValue(map->instance_descriptors(isolate));
} }
} else { } else {
// No element indexes should get here or the exclusion check may
// yield false negatives for type mismatch.
if (excluded_properties != nullptr && if (excluded_properties != nullptr &&
HasExcludedProperty(excluded_properties, next_key)) { HasExcludedProperty(excluded_properties, next_key)) {
continue; continue;
...@@ -381,6 +383,11 @@ Maybe<bool> JSReceiver::SetOrCopyDataProperties( ...@@ -381,6 +383,11 @@ Maybe<bool> JSReceiver::SetOrCopyDataProperties(
// 4. Repeat for each element nextKey of keys in List order, // 4. Repeat for each element nextKey of keys in List order,
for (int i = 0; i < keys->length(); ++i) { for (int i = 0; i < keys->length(); ++i) {
Handle<Object> next_key(keys->get(i), isolate); Handle<Object> next_key(keys->get(i), isolate);
if (excluded_properties != nullptr &&
HasExcludedProperty(excluded_properties, next_key)) {
continue;
}
// 4a i. Let desc be ? from.[[GetOwnProperty]](nextKey). // 4a i. Let desc be ? from.[[GetOwnProperty]](nextKey).
PropertyDescriptor desc; PropertyDescriptor desc;
Maybe<bool> found = Maybe<bool> found =
...@@ -404,11 +411,6 @@ Maybe<bool> JSReceiver::SetOrCopyDataProperties( ...@@ -404,11 +411,6 @@ Maybe<bool> JSReceiver::SetOrCopyDataProperties(
Just(ShouldThrow::kThrowOnError)), Just(ShouldThrow::kThrowOnError)),
Nothing<bool>()); Nothing<bool>());
} else { } else {
if (excluded_properties != nullptr &&
HasExcludedProperty(excluded_properties, next_key)) {
continue;
}
// 4a ii 2. Perform ! CreateDataProperty(target, nextKey, propValue). // 4a ii 2. Perform ! CreateDataProperty(target, nextKey, propValue).
PropertyKey key(isolate, next_key); PropertyKey key(isolate, next_key);
LookupIterator it(isolate, target, key, LookupIterator::OWN); LookupIterator it(isolate, target, key, LookupIterator::OWN);
......
...@@ -100,10 +100,6 @@ Handle<FixedArray> KeyAccumulator::GetKeys(GetKeysConversion convert) { ...@@ -100,10 +100,6 @@ Handle<FixedArray> KeyAccumulator::GetKeys(GetKeysConversion convert) {
if (keys_.is_null()) { if (keys_.is_null()) {
return isolate_->factory()->empty_fixed_array(); return isolate_->factory()->empty_fixed_array();
} }
if (mode_ == KeyCollectionMode::kOwnOnly &&
keys_->map() == ReadOnlyRoots(isolate_).fixed_array_map()) {
return Handle<FixedArray>::cast(keys_);
}
USE(ContainsOnlyValidKeys); USE(ContainsOnlyValidKeys);
Handle<FixedArray> result = Handle<FixedArray> result =
OrderedHashSet::ConvertToKeysArray(isolate(), keys(), convert); OrderedHashSet::ConvertToKeysArray(isolate(), keys(), convert);
...@@ -224,14 +220,12 @@ Maybe<bool> KeyAccumulator::AddKeysFromJSProxy(Handle<JSProxy> proxy, ...@@ -224,14 +220,12 @@ Maybe<bool> KeyAccumulator::AddKeysFromJSProxy(Handle<JSProxy> proxy,
ASSIGN_RETURN_ON_EXCEPTION_VALUE( ASSIGN_RETURN_ON_EXCEPTION_VALUE(
isolate_, keys, FilterProxyKeys(this, proxy, keys, filter_), isolate_, keys, FilterProxyKeys(this, proxy, keys, filter_),
Nothing<bool>()); Nothing<bool>());
if (mode_ == KeyCollectionMode::kOwnOnly) {
// If we collect only the keys from a JSProxy do not sort or deduplicate.
keys_ = keys;
return Just(true);
}
} }
RETURN_NOTHING_IF_NOT_SUCCESSFUL( // https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-ownpropertykeys
AddKeys(keys, is_for_in_ ? CONVERT_TO_ARRAY_INDEX : DO_NOT_CONVERT)); // As of 10.5.11.9 says, the keys collected from Proxy should not contain
// any duplicates. And the order of the keys is preserved by the
// OrderedHashTable.
RETURN_NOTHING_IF_NOT_SUCCESSFUL(AddKeys(keys, CONVERT_TO_ARRAY_INDEX));
return Just(true); return Just(true);
} }
......
...@@ -141,10 +141,7 @@ class KeyAccumulator final { ...@@ -141,10 +141,7 @@ class KeyAccumulator final {
void set_may_have_elements(bool value) { may_have_elements_ = value; } void set_may_have_elements(bool value) { may_have_elements_ = value; }
Isolate* isolate_; Isolate* isolate_;
// keys_ is either an Handle<OrderedHashSet> or in the case of own JSProxy Handle<OrderedHashSet> keys_;
// keys a Handle<FixedArray>. The OrderedHashSet is in-place converted to the
// result list, a FixedArray containing all collected keys.
Handle<FixedArray> keys_;
Handle<Map> first_prototype_map_; Handle<Map> first_prototype_map_;
Handle<JSReceiver> receiver_; Handle<JSReceiver> receiver_;
Handle<JSReceiver> last_non_empty_prototype_; Handle<JSReceiver> last_non_empty_prototype_;
......
...@@ -89,7 +89,7 @@ var p = new Proxy({}, { ...@@ -89,7 +89,7 @@ var p = new Proxy({}, {
}); });
assertThrows(() => { var { ...y } = p }); assertThrows(() => { var { ...y } = p });
var z = { b: 1} var z = { b: 1};
var p = new Proxy(z, { var p = new Proxy(z, {
ownKeys() { return Object.keys(z); }, ownKeys() { return Object.keys(z); },
get(_, prop) { return z[prop]; }, get(_, prop) { return z[prop]; },
...@@ -97,9 +97,20 @@ var p = new Proxy(z, { ...@@ -97,9 +97,20 @@ var p = new Proxy(z, {
return Object.getOwnPropertyDescriptor(z, prop); return Object.getOwnPropertyDescriptor(z, prop);
}, },
}); });
var { ...y } = p ; var { ...y } = p;
assertEquals(z, y); assertEquals(z, y);
var z = { 1: 1, 2: 2, 3: 3 };
var p = new Proxy(z, {
ownKeys() { return ['1', '2']; },
getOwnPropertyDescriptor(_, prop) {
return Object.getOwnPropertyDescriptor(z, prop);
},
});
var { 1: x, ...y } = p;
assertEquals(1, x);
assertEquals({ 2: 2 }, y);
var z = { b: 1} var z = { b: 1}
var { ...y } = { ...z} ; var { ...y } = { ...z} ;
assertEquals(z, y); assertEquals(z, y);
......
...@@ -546,9 +546,6 @@ ...@@ -546,9 +546,6 @@
# http://crbug/v8/11531 # http://crbug/v8/11531
'built-ins/RegExp/prototype/flags/get-order': [FAIL], 'built-ins/RegExp/prototype/flags/get-order': [FAIL],
# http://crbug/v8/11532
'language/expressions/object/dstr/object-rest-proxy-gopd-not-called-on-excluded-keys': [FAIL],
# http://crbug/v8/11533 # http://crbug/v8/11533
'language/statements/class/subclass/default-constructor-spread-override': [FAIL], 'language/statements/class/subclass/default-constructor-spread-override': [FAIL],
......
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