[njs] Fixed handling of unhandled promise rejection.

Dmitry Volyntsev xeioex at nginx.com
Wed Sep 28 02:30:48 UTC 2022


details:   https://hg.nginx.org/njs/rev/1137ad409fee
branches:  
changeset: 1967:1137ad409fee
user:      Dmitry Volyntsev <xeioex at nginx.com>
date:      Tue Sep 27 16:52:31 2022 -0700
description:
Fixed handling of unhandled promise rejection.

Previously, a direct pointer to the first element of an array of
rejected promise values was used to convert that element to a string.
This is not correct because that pointer may become invalid if rejected
promise values array is resized between invocation of "toString" and
"valueOf" methods which are called while converting the element to a
string.

The fix is to ensure that the rejected promise value is never changed.

This closes #580 issue on Github.

diffstat:

 src/njs_vm.c                                     |   4 ++--
 test/js/promise_rejection_tracker_recursive.t.js |  14 ++++++++++++++
 2 files changed, 16 insertions(+), 2 deletions(-)

diffs (32 lines):

diff -r 770f64020ada -r 1137ad409fee src/njs_vm.c
--- a/src/njs_vm.c	Tue Sep 27 16:40:06 2022 -0700
+++ b/src/njs_vm.c	Tue Sep 27 16:52:31 2022 -0700
@@ -579,8 +579,8 @@ njs_vm_handle_events(njs_vm_t *vm)
         }
 
         if (njs_vm_unhandled_rejection(vm)) {
-            ret = njs_value_to_string(vm, &string,
-                                      &vm->promise_reason->start[0]);
+            njs_value_assign(&string, &vm->promise_reason->start[0]);
+            ret = njs_value_to_string(vm, &string, &string);
             if (njs_slow_path(ret != NJS_OK)) {
                 return ret;
             }
diff -r 770f64020ada -r 1137ad409fee test/js/promise_rejection_tracker_recursive.t.js
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/js/promise_rejection_tracker_recursive.t.js	Tue Sep 27 16:52:31 2022 -0700
@@ -0,0 +1,14 @@
+/*---
+includes: []
+flags: []
+negative:
+  phase: runtime
+---*/
+
+String.toString = async () => {
+    String.prototype.concat([String, {toString(){ throw String; }}]);
+    throw 1;
+};
+String.valueOf = String;
+
+(async function() { throw String; })()



More information about the nginx-devel mailing list