]> git.kaiwu.me - njs.git/commitdiff
Fixed aggregation methods of Promise ctor with array-like object.
authorDmitry Volyntsev <xeioex@nginx.com>
Tue, 26 Apr 2022 23:07:02 +0000 (16:07 -0700)
committerDmitry Volyntsev <xeioex@nginx.com>
Tue, 26 Apr 2022 23:07:02 +0000 (16:07 -0700)
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.

src/njs_promise.c
src/test/njs_unit_test.c

index 52ae5b570091989e75bd8b1f8db7be08b4e8a6c2..ea162d533243a8465ba773dd6d45bf3f33b4ce34 100644 (file)
@@ -1369,6 +1369,10 @@ njs_promise_perform_all_handler(njs_vm_t *vm, njs_iterator_args_t *args,
     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_vm_t *vm, njs_iterator_args_t *args,
     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 *vm, njs_iterator_args_t *args,
     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_t *vm, njs_iterator_args_t *args,
     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,
index b28e34fef98bb76c8f08c55da6905fb7281ec480..def152aa8e3fca2f86e16d3946b117bb5729a571 100644 (file)
@@ -21149,6 +21149,13 @@ static njs_unit_test_t  njs_externals_test[] =
               "}))"
               ".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") },
 };