]> git.kaiwu.me - njs.git/commitdiff
Fixed handling of unhandled promise rejection.
authorDmitry Volyntsev <xeioex@nginx.com>
Tue, 27 Sep 2022 23:52:31 +0000 (16:52 -0700)
committerDmitry Volyntsev <xeioex@nginx.com>
Tue, 27 Sep 2022 23:52:31 +0000 (16:52 -0700)
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.

src/njs_vm.c
test/js/promise_rejection_tracker_recursive.t.js [new file with mode: 0644]

index a16d2c82d16b072a5a4277d255d206fb53ad5241..278f60662aae5abb20277e8c5909928d5fe0920a 100644 (file)
@@ -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 --git a/test/js/promise_rejection_tracker_recursive.t.js b/test/js/promise_rejection_tracker_recursive.t.js
new file mode 100644 (file)
index 0000000..ba72353
--- /dev/null
@@ -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; })()