Njs: the Array.length property setter should perform a type conversion

Created on 1 Jul 2018  路  2Comments  路  Source: nginx/njs

as explained here: https://www.ecma-international.org/ecma-262/6.0/#sec-arraysetlength
steps 2-8

bug

All 2 comments

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("[]") },

27 is also fixed

Was this page helpful?
0 / 5 - 0 ratings

Related issues

drsm picture drsm  路  4Comments

laith-leo picture laith-leo  路  5Comments

drsm picture drsm  路  5Comments

drsm picture drsm  路  4Comments

drsm picture drsm  路  4Comments