diff options
author | davidot <david.tuin@gmail.com> | 2021-06-25 16:57:12 +0200 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2021-06-26 18:16:53 +0100 |
commit | b1441a47b164f255e1613224c83e2ff68394b780 (patch) | |
tree | c41b02872ad426607868b05a12168da93de9663d /Userland/Libraries/LibJS/Runtime/Array.cpp | |
parent | b38fb418f8bbecdc10500f8436ad613fb0e36f35 (diff) | |
download | serenity-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.cpp | 39 |
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); } } |