summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIdan Horowitz <idan.horowitz@gmail.com>2021-07-06 23:53:34 +0300
committerLinus Groh <mail@linusgroh.de>2021-07-07 01:38:10 +0100
commitdd27490ee160f92aef4962e31ae7598ddd2fb26a (patch)
treeeb54b23a21052725a3e9a09b0f1fa5d21dde4bdd
parentd57767865882854406fd489cd38bf34bf1216ddd (diff)
downloadserenity-dd27490ee160f92aef4962e31ae7598ddd2fb26a.zip
LibJS: Throw if the trap result of OwnPropertyKeys contains duplicates
-rw-r--r--Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp8
-rw-r--r--Userland/Libraries/LibJS/Runtime/AbstractOperations.h2
-rw-r--r--Userland/Libraries/LibJS/Runtime/ErrorTypes.h2
-rw-r--r--Userland/Libraries/LibJS/Runtime/ProxyObject.cpp20
4 files changed, 21 insertions, 11 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp b/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp
index cfa0d90eaf..e5671eadef 100644
--- a/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp
+++ b/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp
@@ -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
-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& heap = global_object.heap();
@@ -76,11 +76,9 @@ MarkedValueList create_list_from_array_like(GlobalObject& global_object, Value v
if (vm.exception())
return MarkedValueList { heap };
if (check_value) {
- auto result = check_value(next);
- if (result.is_error()) {
- vm.throw_exception<TypeError>(global_object, result.release_error());
+ check_value(next);
+ if (vm.exception())
return MarkedValueList { heap };
- }
}
list.append(next);
}
diff --git a/Userland/Libraries/LibJS/Runtime/AbstractOperations.h b/Userland/Libraries/LibJS/Runtime/AbstractOperations.h
index f70f51654b..1be5683d3e 100644
--- a/Userland/Libraries/LibJS/Runtime/AbstractOperations.h
+++ b/Userland/Libraries/LibJS/Runtime/AbstractOperations.h
@@ -21,7 +21,7 @@ Object* get_super_constructor(VM&);
Reference make_super_property_reference(GlobalObject&, Value actual_this, StringOrSymbol const& property_key, bool strict);
Value require_object_coercible(GlobalObject&, Value);
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);
GlobalObject* get_function_realm(GlobalObject&, FunctionObject const&);
bool is_compatible_property_descriptor(bool extensible, PropertyDescriptor const&, Optional<PropertyDescriptor> const& current);
diff --git a/Userland/Libraries/LibJS/Runtime/ErrorTypes.h b/Userland/Libraries/LibJS/Runtime/ErrorTypes.h
index 12acdf9988..fb374a8f13 100644
--- a/Userland/Libraries/LibJS/Runtime/ErrorTypes.h
+++ b/Userland/Libraries/LibJS/Runtime/ErrorTypes.h
@@ -132,6 +132,8 @@
"return value must match the target's extensibility") \
M(ProxyOwnPropertyKeysNotStringOrSymbol, "Proxy handler's ownKeys trap violates invariant: " \
"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 " \
"invariant: cannot return true if the target object is extensible") \
M(ProxyRevoked, "An operation was performed on a revoked Proxy object") \
diff --git a/Userland/Libraries/LibJS/Runtime/ProxyObject.cpp b/Userland/Libraries/LibJS/Runtime/ProxyObject.cpp
index 8216918fd8..803ba3dd74 100644
--- a/Userland/Libraries/LibJS/Runtime/ProxyObject.cpp
+++ b/Userland/Libraries/LibJS/Runtime/ProxyObject.cpp
@@ -798,13 +798,23 @@ MarkedValueList ProxyObject::internal_own_property_keys() const
return MarkedValueList { heap() };
// 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> {
- if (!value.is_string() && !value.is_symbol())
- return ErrorType::ProxyOwnPropertyKeysNotStringOrSymbol;
- return {};
+ HashTable<StringOrSymbol> unique_keys;
+ auto trap_result = create_list_from_array_like(global_object, trap_result_array, [&](auto value) {
+ auto& vm = global_object.vm();
+ 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).
auto extensible_target = m_target.is_extensible();