[njs] Fixed iterator for Array.prototype.find/findIndex() functions.

Alexander Borisov alexander.borisov at nginx.com
Wed Oct 30 13:43:43 UTC 2019


details:   https://hg.nginx.org/njs/rev/926dfdd7a34c
branches:  
changeset: 1206:926dfdd7a34c
user:      Alexander Borisov <alexander.borisov at nginx.com>
date:      Wed Oct 30 16:43:09 2019 +0300
description:
Fixed iterator for Array.prototype.find/findIndex() functions.

Array might be changed in callback function.  If an array became smaller than
the initial one, it is necessary to iterate the missing values as invalid.

This closes #229 issue on GitHub.

diffstat:

 src/njs_array.c          |  14 ++++++++------
 src/test/njs_unit_test.c |  10 ++++++++++
 2 files changed, 18 insertions(+), 6 deletions(-)

diffs (65 lines):

diff -r fedc4ad583c8 -r 926dfdd7a34c src/njs_array.c
--- a/src/njs_array.c	Tue Oct 29 15:24:58 2019 +0300
+++ b/src/njs_array.c	Wed Oct 30 16:43:09 2019 +0300
@@ -1380,7 +1380,7 @@ njs_array_iterator(njs_vm_t *vm, njs_arr
     uint32_t           length, i, from, to;
     njs_int_t          ret;
     njs_array_t        *keys;
-    njs_value_t        *entry, *value, character, index, string_obj;
+    njs_value_t        *value, character, index, string_obj;
     njs_object_t       *object;
     const u_char       *p, *end, *pos;
     njs_string_prop_t  string_prop;
@@ -1395,9 +1395,13 @@ njs_array_iterator(njs_vm_t *vm, njs_arr
         }
 
         for (i = from; i < to; i++) {
-            entry = &njs_array_start(value)[i];
-
-            ret = handler(vm, args, entry, i);
+            if (i < njs_array_len(value)) {
+                ret = handler(vm, args, &njs_array_start(value)[i], i);
+
+            } else {
+                ret = handler(vm, args, njs_value_arg(&njs_value_invalid), i);
+            }
+
             if (njs_slow_path(ret != NJS_OK)) {
                 if (ret > 0) {
                     return NJS_DECLINED;
@@ -1405,8 +1409,6 @@ njs_array_iterator(njs_vm_t *vm, njs_arr
 
                 return NJS_ERROR;
             }
-
-            to = njs_min(to, njs_array_len(value));
         }
 
         return NJS_OK;
diff -r fedc4ad583c8 -r 926dfdd7a34c src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c	Tue Oct 29 15:24:58 2019 +0300
+++ b/src/test/njs_unit_test.c	Wed Oct 30 16:43:09 2019 +0300
@@ -4813,6 +4813,11 @@ static njs_unit_test_t  njs_test[] =
               "catch (e) {i += '; ' + e} i"),
       njs_str("1; TypeError: unexpected iterator arguments") },
 
+    { njs_str("var callz = 0, res = [], arr = 'abc'.split('');"
+              "void arr.find((k) => { if (0 == callz++) { arr.splice(1,1); } res.push(k) });"
+              "res.join(',')"),
+      njs_str("a,c,") },
+
     { njs_str("var a = [];"
                  "a.findIndex(function(v, i, a) { return v > 1 })"),
       njs_str("-1") },
@@ -4872,6 +4877,11 @@ static njs_unit_test_t  njs_test[] =
               "catch (e) {i += '; ' + e} i"),
       njs_str("1; TypeError: unexpected iterator arguments") },
 
+    { njs_str("var callz = 0, res = [], arr = 'abc'.split('');"
+              "void arr.findIndex((k) => { if (0 == callz++) { arr.splice(1,1); } res.push(k) });"
+              "res.join(',')"),
+      njs_str("a,c,") },
+
     { njs_str("var a = [];"
                  "a.map(function(v, i, a) { return v + 1 })"),
       njs_str("") },


More information about the nginx-devel mailing list