summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibJS/Runtime/Array.cpp
diff options
context:
space:
mode:
authordavidot <david.tuin@gmail.com>2021-06-25 16:57:12 +0200
committerLinus Groh <mail@linusgroh.de>2021-06-26 18:16:53 +0100
commitb1441a47b164f255e1613224c83e2ff68394b780 (patch)
treec41b02872ad426607868b05a12168da93de9663d /Userland/Libraries/LibJS/Runtime/Array.cpp
parentb38fb418f8bbecdc10500f8436ad613fb0e36f35 (diff)
downloadserenity-b1441a47b164f255e1613224c83e2ff68394b780.zip
LibJS: Allow setting the length of an object with prototype Array
Before this it would always go through the native setter thus modifying the array but now you can set length to anything
Diffstat (limited to 'Userland/Libraries/LibJS/Runtime/Array.cpp')
-rw-r--r--Userland/Libraries/LibJS/Runtime/Array.cpp39
1 files changed, 32 insertions, 7 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/Array.cpp b/Userland/Libraries/LibJS/Runtime/Array.cpp
index 232a5a42e2..314688df30 100644
--- a/Userland/Libraries/LibJS/Runtime/Array.cpp
+++ b/Userland/Libraries/LibJS/Runtime/Array.cpp
@@ -65,25 +65,50 @@ Array* Array::typed_this(VM& vm, GlobalObject& global_object)
JS_DEFINE_NATIVE_GETTER(Array::length_getter)
{
- auto* array = typed_this(vm, global_object);
- if (!array)
+ auto* this_object = vm.this_value(global_object).to_object(global_object);
+ if (!this_object)
return {};
- return Value(array->indexed_properties().array_like_size());
+
+ // TODO: could be incorrect if receiver/this_value is fixed or changed
+ if (!this_object->is_array()) {
+ Value val = this_object->get_own_property(vm.names.length.to_string_or_symbol(), this_object);
+ if (vm.exception())
+ return {};
+ return val;
+ }
+
+ return Value(this_object->indexed_properties().array_like_size());
}
JS_DEFINE_NATIVE_SETTER(Array::length_setter)
{
- auto* array = typed_this(vm, global_object);
- if (!array)
+ auto* this_object = vm.this_value(global_object).to_object(global_object);
+ if (!this_object)
return;
+
+ // TODO: could be incorrect if receiver/this_value is fixed or changed
+ if (!this_object->is_array()) {
+ this_object->define_property(vm.names.length.to_string_or_symbol(), value, default_attributes);
+ if (vm.exception())
+ return;
+ return;
+ }
+
auto length = value.to_number(global_object);
if (vm.exception())
return;
- if (length.is_nan() || length.is_infinity() || length.as_double() < 0) {
+
+ u32 val = length.as_double();
+
+ if (val != length.as_double()
+ || length.is_nan()
+ || length.is_infinity()
+ || length.as_double() < 0
+ || length.as_double() > NumericLimits<u32>::max()) {
vm.throw_exception<RangeError>(global_object, ErrorType::InvalidLength, "array");
return;
}
- array->indexed_properties().set_array_like_size(length.as_double());
+ this_object->indexed_properties().set_array_like_size(val);
}
}