]> git.kaiwu.me - njs.git/commitdiff
Fixed iterator for Array.prototype.find/findIndex() functions.
authorAlexander Borisov <alexander.borisov@nginx.com>
Wed, 30 Oct 2019 13:43:09 +0000 (16:43 +0300)
committerAlexander Borisov <alexander.borisov@nginx.com>
Wed, 30 Oct 2019 13:43:09 +0000 (16:43 +0300)
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.

src/njs_array.c
src/test/njs_unit_test.c

index dbe9c805366af49d2628915d19b36d400abc1337..b00575fe3ff3d7f41ce0a14d8fd92659f649139e 100644 (file)
@@ -1380,7 +1380,7 @@ njs_array_iterator(njs_vm_t *vm, njs_array_iterator_args_t *args,
     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_array_iterator_args_t *args,
         }
 
         for (i = from; i < to; i++) {
-            entry = &njs_array_start(value)[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);
+            }
 
-            ret = handler(vm, args, entry, 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_array_iterator_args_t *args,
 
                 return NJS_ERROR;
             }
-
-            to = njs_min(to, njs_array_len(value));
         }
 
         return NJS_OK;
index 738555bdb23bb1fc48c803c191aea1d6b32c760c..31f7c5b593154bdab4c8c5942ce44b1572e89ea5 100644 (file)
@@ -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("") },