[njs] Added array length setter.

Dmitry Volyntsev xeioex at nginx.com
Fri Apr 20 13:42:38 UTC 2018


details:   http://hg.nginx.org/njs/rev/7f75ccba396e
branches:  
changeset: 502:7f75ccba396e
user:      Dmitry Volyntsev <xeioex at nginx.com>
date:      Fri Apr 20 16:42:12 2018 +0300
description:
Added array length setter.

This fixes #1 issue on GitHub.

diffstat:

 njs/njs_array.c          |  49 ++++++++++++++++++++++++++++++++++++++++++-----
 njs/test/njs_unit_test.c |  35 ++++++++++++++++++++++++++++++++++
 2 files changed, 78 insertions(+), 6 deletions(-)

diffs (106 lines):

diff -r a65deb4c2e03 -r 7f75ccba396e njs/njs_array.c
--- a/njs/njs_array.c	Fri Apr 20 16:42:10 2018 +0300
+++ b/njs/njs_array.c	Fri Apr 20 16:42:12 2018 +0300
@@ -381,14 +381,51 @@ const njs_object_init_t  njs_array_const
 
 
 static njs_ret_t
-njs_array_prototype_length(njs_vm_t *vm, njs_value_t *array,
+njs_array_prototype_length(njs_vm_t *vm, njs_value_t *value,
     njs_value_t *setval, njs_value_t *retval)
 {
-    njs_value_number_set(retval, array->data.u.array->length);
-
-    njs_release(vm, array);
-
-    return NXT_OK;
+    double       num;
+    int32_t      size;
+    uint32_t     length;
+    njs_ret_t    ret;
+    njs_value_t  *val;
+    njs_array_t  *array;
+
+    array = value->data.u.array;
+
+    if (setval != NULL) {
+        num = setval->data.u.number;
+        length = (uint32_t) num;
+
+        if ((double) length != num) {
+            njs_range_error(vm, "Invalid array length", NULL);
+            return NJS_ERROR;
+        }
+
+        size = (int32_t) (length - array->length);
+
+        if (size > 0) {
+            ret = njs_array_expand(vm, array, 0, size);
+            if (nxt_slow_path(ret != NXT_OK)) {
+                njs_memory_error(vm);
+                return NJS_ERROR;
+            }
+
+            val = &array->start[array->length];
+
+            do {
+                njs_set_invalid(val);
+                val++;
+                size--;
+            } while (size != 0);
+        }
+
+        array->length = length;
+    }
+
+    njs_value_number_set(retval, array->length);
+
+    return NJS_OK;
 }
 
 
diff -r a65deb4c2e03 -r 7f75ccba396e njs/test/njs_unit_test.c
--- a/njs/test/njs_unit_test.c	Fri Apr 20 16:42:10 2018 +0300
+++ b/njs/test/njs_unit_test.c	Fri Apr 20 16:42:12 2018 +0300
@@ -2700,6 +2700,41 @@ static njs_unit_test_t  njs_test[] =
     { nxt_string("var a = [1,2]; a.length"),
       nxt_string("2") },
 
+    /* Array.length setter */
+
+    { nxt_string("[].length = {}"),
+      nxt_string("RangeError: Invalid array length") },
+
+    { nxt_string("[].length = 2**32"),
+      nxt_string("RangeError: Invalid array length") },
+
+    { nxt_string("[].length = -1"),
+      nxt_string("RangeError: Invalid array length") },
+
+    { nxt_string("var a = []; a.length = 0; JSON.stringify(a)"),
+      nxt_string("[]") },
+
+    { nxt_string("var a = []; a.length = 1; JSON.stringify(a)"),
+      nxt_string("[null]") },
+
+    { nxt_string("var a = [1]; a.length = 1; JSON.stringify(a)"),
+      nxt_string("[1]") },
+
+    { nxt_string("var a = [1]; a.length = 2; JSON.stringify(a)"),
+      nxt_string("[1,null]") },
+
+    { nxt_string("var a = [1]; a.length = 4; a.length = 0; JSON.stringify(a)"),
+      nxt_string("[]") },
+
+    { nxt_string("var a = [1,2,3]; a.length = 2; JSON.stringify(a)"),
+      nxt_string("[1,2]") },
+
+    { nxt_string("var a = [1,2,3]; a.length = 3; a"),
+      nxt_string("1,2,3") },
+
+    { nxt_string("var a = [1,2,3]; a.length = 16; a"),
+      nxt_string("1,2,3,,,,,,,,,,,,,") },
+
     { nxt_string("var a = [1,2,3]; a.join()"),
       nxt_string("1,2,3") },
 


More information about the nginx-devel mailing list