]> git.kaiwu.me - njs.git/commitdiff
Fixed Array.length setter.
authorArtem S. Povalyukhin <artem.povaluhin@gmail.com>
Fri, 26 Jul 2019 04:24:36 +0000 (07:24 +0300)
committerArtem S. Povalyukhin <artem.povaluhin@gmail.com>
Fri, 26 Jul 2019 04:24:36 +0000 (07:24 +0300)
This closes #26 and closes #27 issues on Github.

njs/njs_array.c
njs/test/njs_unit_test.c

index 7b43153fcf5e85f4627c1995e5d079e9254261bf..dbeb00142c849e2f0094ddebb81861ff1233a5cf 100644 (file)
@@ -318,10 +318,11 @@ njs_array_length(njs_vm_t *vm, njs_value_t *value, njs_value_t *setval,
     njs_value_t  *val;
     njs_array_t  *array;
     njs_object_t *proto;
+    njs_value_t  val_length;
 
     proto = njs_object(value);
 
-    if (setval == NULL) {
+    if (nxt_fast_path(setval == NULL)) {
         do {
             if (nxt_fast_path(proto->type == NJS_ARRAY)) {
                 break;
@@ -345,13 +346,19 @@ njs_array_length(njs_vm_t *vm, njs_value_t *value, njs_value_t *setval,
         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;
+    length = njs_number_to_uint32(num);
 
     if ((double) length != num) {
         njs_range_error(vm, "Invalid array length");
@@ -379,7 +386,7 @@ njs_array_length(njs_vm_t *vm, njs_value_t *value, njs_value_t *setval,
 
     array->length = length;
 
-    njs_set_number(retval, length);
+    *retval = *setval;
     return NJS_OK;
 }
 
index b0d5b6697fbab3926daccdf829dc0e7313a5fcc2..dcf35a2be1fb96c1c73cf36507a6c32176263e5c 100644 (file)
@@ -3531,6 +3531,26 @@ static njs_unit_test_t  njs_test[] =
     { 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("[]") },