From 6a11bf3763ccd36bf7137777799ab4ebcaa19500 Mon Sep 17 00:00:00 2001 From: Dmitry Volyntsev Date: Tue, 27 Sep 2022 16:52:31 -0700 Subject: [PATCH] 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. --- src/njs_vm.c | 4 ++-- test/js/promise_rejection_tracker_recursive.t.js | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 test/js/promise_rejection_tracker_recursive.t.js diff --git a/src/njs_vm.c b/src/njs_vm.c index a16d2c82..278f6066 100644 --- a/src/njs_vm.c +++ b/src/njs_vm.c @@ -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 index 00000000..ba723534 --- /dev/null +++ b/test/js/promise_rejection_tracker_recursive.t.js @@ -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; })() -- 2.47.3