as explained here: https://www.ecma-international.org/ecma-262/6.0/#sec-arraysetlength
steps 2-8
Here is the patch:
# HG changeset patch
# User Artem S. Povalyukhin <[email protected]>
# Date 1564115076 -10800
# Fri Jul 26 07:24:36 2019 +0300
# Node ID ee960f6f15c67b99d715fbf947fae864d11cd4a2
# Parent 89082cb0bc84e9004f80efdc70c2510790b4edb6
Fixed Array.length setter.
diff -r 89082cb0bc84 -r ee960f6f15c6 njs/njs_array.c
--- a/njs/njs_array.c Thu Jul 25 22:07:57 2019 +0300
+++ b/njs/njs_array.c Fri Jul 26 07:24:36 2019 +0300
@@ -318,6 +318,7 @@
njs_value_t *val;
njs_array_t *array;
njs_object_t *proto;
+ njs_value_t val_length;
proto = njs_object(value);
@@ -345,12 +346,18 @@
return NJS_DECLINED;
}
- if (!njs_is_number(setval)) {
- njs_range_error(vm, "Invalid array length");
- return NJS_ERROR;
+ if (nxt_slow_path(!njs_is_number(setval))) {
+ ret = njs_value_to_numeric(vm, &val_length, setval);
+ if (ret != NXT_OK) {
+ return ret;
+ }
+
+ num = njs_number(&val_length);
+
+ } else {
+ num = njs_number(setval);
}
- num = njs_number(setval);
length = (uint32_t) num;
if ((double) length != num) {
@@ -379,7 +386,7 @@
array->length = length;
- njs_set_number(retval, length);
+ *retval = *setval;
return NJS_OK;
}
diff -r 89082cb0bc84 -r ee960f6f15c6 njs/test/njs_unit_test.c
--- a/njs/test/njs_unit_test.c Thu Jul 25 22:07:57 2019 +0300
+++ b/njs/test/njs_unit_test.c Fri Jul 26 07:24:36 2019 +0300
@@ -3531,6 +3531,26 @@
{ nxt_string("[].length = -1"),
nxt_string("RangeError: Invalid array length") },
+ { nxt_string("var a = [1];"
+ "typeof (a.length = '') == 'string' && a.length == 0"),
+ nxt_string("true") },
+
+ { nxt_string("var a = [1]; "
+ "typeof (a.length = Object(2)) == 'object' && a.length == 2"),
+ nxt_string("true") },
+
+ { nxt_string("var a = [1]; "
+ "typeof (a.length = Object('2')) == 'object'"),
+ nxt_string("true") },
+
+ { nxt_string("var a = [1]; "
+ "a.length = { valueOf: () => 2 }; a.length == 2"),
+ nxt_string("true") },
+
+ { nxt_string("var a = [1]; "
+ "a.length = { toString: () => '2' }; a.length == 2"),
+ nxt_string("true") },
+
{ nxt_string("var a = []; a.length = 0; JSON.stringify(a)"),
nxt_string("[]") },