[njs] Fixed aggregation methods of Promise ctor with array-like object.

Dmitry Volyntsev xeioex at nginx.com
Tue Apr 26 23:09:00 UTC 2022


details:   https://hg.nginx.org/njs/rev/744122b4dccf
branches:  
changeset: 1841:744122b4dccf
user:      Dmitry Volyntsev <xeioex at nginx.com>
date:      Tue Apr 26 16:07:02 2022 -0700
description:
Fixed aggregation methods of Promise ctor with array-like object.

Previously, while iterating over an array-like object the methods may be
resolved with INVALID values. INVALID value is a special internal type which
should never be visible by ordinary functions.

The fix is to ensure that absent elements are represented by undefined value.

The following methods were fixed Promise.all(), Promise.allSettled(),
    Promise.any(), Promise.race().

This closes #483 issue on Github.

diffstat:

 src/njs_promise.c        |  16 ++++++++++++++++
 src/test/njs_unit_test.c |   7 +++++++
 2 files changed, 23 insertions(+), 0 deletions(-)

diffs (64 lines):

diff -r 3fec53d722ef -r 744122b4dccf src/njs_promise.c
--- a/src/njs_promise.c	Fri Apr 22 17:02:36 2022 -0700
+++ b/src/njs_promise.c	Tue Apr 26 16:07:02 2022 -0700
@@ -1369,6 +1369,10 @@ njs_promise_perform_all_handler(njs_vm_t
     njs_promise_all_context_t    *context;
     njs_promise_iterator_args_t  *pargs;
 
+    if (!njs_is_valid(value)) {
+        value = njs_value_arg(&njs_value_undefined);
+    }
+
     pargs = (njs_promise_iterator_args_t *) args;
 
     capability = pargs->capability;
@@ -1459,6 +1463,10 @@ njs_promise_perform_all_settled_handler(
     njs_promise_all_context_t    *context;
     njs_promise_iterator_args_t  *pargs;
 
+    if (!njs_is_valid(value)) {
+        value = njs_value_arg(&njs_value_undefined);
+    }
+
     pargs = (njs_promise_iterator_args_t *) args;
 
     capability = pargs->capability;
@@ -1598,6 +1606,10 @@ njs_promise_perform_any_handler(njs_vm_t
     njs_promise_all_context_t    *context;
     njs_promise_iterator_args_t  *pargs;
 
+    if (!njs_is_valid(value)) {
+        value = njs_value_arg(&njs_value_undefined);
+    }
+
     pargs = (njs_promise_iterator_args_t *) args;
 
     capability = pargs->capability;
@@ -1745,6 +1757,10 @@ njs_promise_perform_race_handler(njs_vm_
     njs_promise_capability_t     *capability;
     njs_promise_iterator_args_t  *pargs;
 
+    if (!njs_is_valid(value)) {
+        value = njs_value_arg(&njs_value_undefined);
+    }
+
     pargs = (njs_promise_iterator_args_t *) args;
 
     ret = njs_function_call(vm, pargs->function, pargs->constructor, value,
diff -r 3fec53d722ef -r 744122b4dccf src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c	Fri Apr 22 17:02:36 2022 -0700
+++ b/src/test/njs_unit_test.c	Tue Apr 26 16:07:02 2022 -0700
@@ -21149,6 +21149,13 @@ static njs_unit_test_t  njs_externals_te
               "}))"
               ".then(v => $r.retval(v))"),
       njs_str("a:async:pr:async2:pr:r,b:async:pr:async2:pr:r,c:async:pr:async2:pr:r") },
+
+    { njs_str("async function f () {"
+              "    var p = await Promise.race({length:1});"
+              "    for (const v in 'test') { }"
+              "};"
+              "f().then(v => $r.retval('done'))"),
+      njs_str("done") },
 };
 
 



More information about the nginx-devel mailing list