From: Dmitry Volyntsev Date: Tue, 26 Apr 2022 23:07:02 +0000 (-0700) Subject: Fixed aggregation methods of Promise ctor with array-like object. X-Git-Tag: 0.7.4~23 X-Git-Url: http://www.kaiwu.me/postgresql/commit/?a=commitdiff_plain;h=31ed93a5623f24ca94e6d47e895ba735d9d97d46;p=njs.git 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. --- diff --git a/src/njs_promise.c b/src/njs_promise.c index 52ae5b57..ea162d53 100644 --- a/src/njs_promise.c +++ b/src/njs_promise.c @@ -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, diff --git a/src/test/njs_unit_test.c b/src/test/njs_unit_test.c index b28e34fe..def152aa 100644 --- a/src/test/njs_unit_test.c +++ b/src/test/njs_unit_test.c @@ -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") }, };