Welcome! Log In Create A New Profile

Advanced

[njs] Propertly handling NJS_DECLINE in promise native functions.

Dmitry Volyntsev
June 15, 2022 08:14PM
details: https://hg.nginx.org/njs/rev/be631766cc1f
branches:
changeset: 1890:be631766cc1f
user: Dmitry Volyntsev <xeioex@nginx.com>
date: Wed Jun 15 17:10:39 2022 -0700
description:
Propertly handling NJS_DECLINE in promise native functions.

Previously, NJS_DECLINE was returned from a Promise.all() and friends
when "resolve" property was not found in a promise constructor.
NJS_DECLINE was treated as NJS_ERROR in one place, but as NJS_OK in a
different place during the promise function evaluation. As a result,
the VM was left in inconsistent state during stack unwinding which
resulted in a garbage return value.

The fix is to ensure that only NJS_ERROR or NJS_OK is returned
from ordinary native functions.

This closes #545 issue on Github.

diffstat:

src/njs_promise.c | 6 +++---
src/test/njs_unit_test.c | 22 ++++++++++++++++++++++
2 files changed, 25 insertions(+), 3 deletions(-)

diffs (62 lines):

diff -r 461b1a030acb -r be631766cc1f src/njs_promise.c
--- a/src/njs_promise.c Tue Jun 14 17:48:54 2022 -0700
+++ b/src/njs_promise.c Wed Jun 15 17:10:39 2022 -0700
@@ -389,7 +389,7 @@ njs_promise_value_constructor(njs_vm_t *

ret = njs_value_property(vm, value, njs_value_arg(&string_constructor),
dst);
- if (njs_slow_path(ret != NJS_OK)) {
+ if (njs_slow_path(ret == NJS_ERROR)) {
return ret;
}

@@ -1255,7 +1255,7 @@ njs_promise_all(njs_vm_t *vm, njs_value_

ret = njs_value_property(vm, promise_ctor, njs_value_arg(&string_resolve),
&resolve);
- if (njs_slow_path(ret != NJS_OK)) {
+ if (njs_slow_path(ret == NJS_ERROR)) {
return ret;
}

@@ -1715,7 +1715,7 @@ njs_promise_race(njs_vm_t *vm, njs_value

ret = njs_value_property(vm, promise_ctor, njs_value_arg(&string_resolve),
&resolve);
- if (njs_slow_path(ret != NJS_OK)) {
+ if (njs_slow_path(ret == NJS_ERROR)) {
return ret;
}

diff -r 461b1a030acb -r be631766cc1f src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c Tue Jun 14 17:48:54 2022 -0700
+++ b/src/test/njs_unit_test.c Wed Jun 15 17:10:39 2022 -0700
@@ -21211,6 +21211,28 @@ static njs_unit_test_t njs_externals_te
{ njs_str("$r.retval(Promise.all([async () => [await x('X')]]))"),
njs_str("[object Promise]") },

+ { njs_str("var r = [1].map(v => {"
+ " function C(a) {"
+ " a(a, parseInt);"
+ " };"
+ ""
+ " Promise.all.apply(C);"
+ "});"
+ "r[0]"),
+ /* TODO: RejectAbrupt() exception should not percolate */
+ njs_str("TypeError: resolve is not callable") },
+
+ { njs_str("var r = [1].map(v => {"
+ " function C(a) {"
+ " a(a, parseInt);"
+ " };"
+ ""
+ " Promise.race.apply(C);"
+ "});"
+ "r[0]"),
+ /* TODO: RejectAbrupt() exception should not percolate */
+ njs_str("TypeError: resolve is not callable") },
+
{ njs_str("let obj = { a: 1, b: 2};"
"function cb(r) { r.retval(obj.a); }"
"$r.subrequest($r)"
_______________________________________________
nginx-devel mailing list -- nginx-devel@nginx.org
To unsubscribe send an email to nginx-devel-leave@nginx.org
Subject Author Views Posted

[njs] Propertly handling NJS_DECLINE in promise native functions.

Dmitry Volyntsev 150 June 15, 2022 08:14PM



Sorry, you do not have permission to post/reply in this forum.

Online Users

Guests: 118
Record Number of Users: 6 on February 13, 2018
Record Number of Guests: 421 on December 02, 2018
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready