mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 13:17:35 +00:00
LibJS: Throw if the trap result of OwnPropertyKeys contains duplicates
This commit is contained in:
parent
d577678658
commit
dd27490ee1
4 changed files with 21 additions and 11 deletions
|
@ -57,7 +57,7 @@ size_t length_of_array_like(GlobalObject& global_object, Object const& object)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 7.3.19 CreateListFromArrayLike ( obj [ , elementTypes ] ), https://tc39.es/ecma262/#sec-createlistfromarraylike
|
// 7.3.19 CreateListFromArrayLike ( obj [ , elementTypes ] ), https://tc39.es/ecma262/#sec-createlistfromarraylike
|
||||||
MarkedValueList create_list_from_array_like(GlobalObject& global_object, Value value, Function<Result<void, ErrorType>(Value)> check_value)
|
MarkedValueList create_list_from_array_like(GlobalObject& global_object, Value value, Function<void(Value)> check_value)
|
||||||
{
|
{
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
auto& heap = global_object.heap();
|
auto& heap = global_object.heap();
|
||||||
|
@ -76,11 +76,9 @@ MarkedValueList create_list_from_array_like(GlobalObject& global_object, Value v
|
||||||
if (vm.exception())
|
if (vm.exception())
|
||||||
return MarkedValueList { heap };
|
return MarkedValueList { heap };
|
||||||
if (check_value) {
|
if (check_value) {
|
||||||
auto result = check_value(next);
|
check_value(next);
|
||||||
if (result.is_error()) {
|
if (vm.exception())
|
||||||
vm.throw_exception<TypeError>(global_object, result.release_error());
|
|
||||||
return MarkedValueList { heap };
|
return MarkedValueList { heap };
|
||||||
}
|
|
||||||
}
|
}
|
||||||
list.append(next);
|
list.append(next);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ Object* get_super_constructor(VM&);
|
||||||
Reference make_super_property_reference(GlobalObject&, Value actual_this, StringOrSymbol const& property_key, bool strict);
|
Reference make_super_property_reference(GlobalObject&, Value actual_this, StringOrSymbol const& property_key, bool strict);
|
||||||
Value require_object_coercible(GlobalObject&, Value);
|
Value require_object_coercible(GlobalObject&, Value);
|
||||||
size_t length_of_array_like(GlobalObject&, Object const&);
|
size_t length_of_array_like(GlobalObject&, Object const&);
|
||||||
MarkedValueList create_list_from_array_like(GlobalObject&, Value, Function<Result<void, ErrorType>(Value)> = {});
|
MarkedValueList create_list_from_array_like(GlobalObject&, Value, Function<void(Value)> = {});
|
||||||
FunctionObject* species_constructor(GlobalObject&, Object const&, FunctionObject& default_constructor);
|
FunctionObject* species_constructor(GlobalObject&, Object const&, FunctionObject& default_constructor);
|
||||||
GlobalObject* get_function_realm(GlobalObject&, FunctionObject const&);
|
GlobalObject* get_function_realm(GlobalObject&, FunctionObject const&);
|
||||||
bool is_compatible_property_descriptor(bool extensible, PropertyDescriptor const&, Optional<PropertyDescriptor> const& current);
|
bool is_compatible_property_descriptor(bool extensible, PropertyDescriptor const&, Optional<PropertyDescriptor> const& current);
|
||||||
|
|
|
@ -132,6 +132,8 @@
|
||||||
"return value must match the target's extensibility") \
|
"return value must match the target's extensibility") \
|
||||||
M(ProxyOwnPropertyKeysNotStringOrSymbol, "Proxy handler's ownKeys trap violates invariant: " \
|
M(ProxyOwnPropertyKeysNotStringOrSymbol, "Proxy handler's ownKeys trap violates invariant: " \
|
||||||
"the type of each result list element is either String or Symbol") \
|
"the type of each result list element is either String or Symbol") \
|
||||||
|
M(ProxyOwnPropertyKeysDuplicates, "Proxy handler's ownKeys trap violates invariant: " \
|
||||||
|
"the result list may not contain duplicate elements") \
|
||||||
M(ProxyPreventExtensionsReturn, "Proxy handler's preventExtensions trap violates " \
|
M(ProxyPreventExtensionsReturn, "Proxy handler's preventExtensions trap violates " \
|
||||||
"invariant: cannot return true if the target object is extensible") \
|
"invariant: cannot return true if the target object is extensible") \
|
||||||
M(ProxyRevoked, "An operation was performed on a revoked Proxy object") \
|
M(ProxyRevoked, "An operation was performed on a revoked Proxy object") \
|
||||||
|
|
|
@ -798,13 +798,23 @@ MarkedValueList ProxyObject::internal_own_property_keys() const
|
||||||
return MarkedValueList { heap() };
|
return MarkedValueList { heap() };
|
||||||
|
|
||||||
// 8. Let trapResult be ? CreateListFromArrayLike(trapResultArray, « String, Symbol »).
|
// 8. Let trapResult be ? CreateListFromArrayLike(trapResultArray, « String, Symbol »).
|
||||||
auto trap_result = create_list_from_array_like(global_object, trap_result_array, [](auto value) -> Result<void, ErrorType> {
|
HashTable<StringOrSymbol> unique_keys;
|
||||||
if (!value.is_string() && !value.is_symbol())
|
auto trap_result = create_list_from_array_like(global_object, trap_result_array, [&](auto value) {
|
||||||
return ErrorType::ProxyOwnPropertyKeysNotStringOrSymbol;
|
auto& vm = global_object.vm();
|
||||||
return {};
|
if (!value.is_string() && !value.is_symbol()) {
|
||||||
|
vm.throw_exception<TypeError>(global_object, ErrorType::ProxyOwnPropertyKeysNotStringOrSymbol);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto property_key = value.to_property_key(global_object);
|
||||||
|
VERIFY(!vm.exception());
|
||||||
|
unique_keys.set(property_key, AK::HashSetExistingEntryBehavior::Keep);
|
||||||
});
|
});
|
||||||
|
|
||||||
// FIXME: 9. If trapResult contains any duplicate entries, throw a TypeError exception.
|
// 9. If trapResult contains any duplicate entries, throw a TypeError exception.
|
||||||
|
if (unique_keys.size() != trap_result.size()) {
|
||||||
|
vm.throw_exception<TypeError>(global_object, ErrorType::ProxyOwnPropertyKeysDuplicates);
|
||||||
|
return MarkedValueList { heap() };
|
||||||
|
}
|
||||||
|
|
||||||
// 10. Let extensibleTarget be ? IsExtensible(target).
|
// 10. Let extensibleTarget be ? IsExtensible(target).
|
||||||
auto extensible_target = m_target.is_extensible();
|
auto extensible_target = m_target.is_extensible();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue