From: Dmitry Volyntsev Date: Tue, 17 Jul 2018 17:25:47 +0000 (+0300) Subject: Fixed exception handling in njs_vm_value_to_ext_string(). X-Git-Tag: 0.2.3~16 X-Git-Url: http://git.kaiwu.me/sitemap.xml?a=commitdiff_plain;h=8e20d5db9809bd071a335647ecfd2a1f7e2cf63c;p=njs.git Fixed exception handling in njs_vm_value_to_ext_string(). --- diff --git a/njs/njs_vm.c b/njs/njs_vm.c index ec4fe2ea..bf2e7fc3 100644 --- a/njs/njs_vm.c +++ b/njs/njs_vm.c @@ -3273,8 +3273,9 @@ fail: static njs_ret_t njs_object_value_to_string(njs_vm_t *vm, njs_value_t *value) { - u_char *current; - njs_ret_t ret; + u_char *current; + njs_ret_t ret; + njs_native_frame_t *previous; static const njs_vmcode_1addr_t value_to_string[] = { { .code = { .operation = njs_vmcode_value_to_string, @@ -3298,6 +3299,14 @@ njs_object_value_to_string(njs_vm_t *vm, njs_value_t *value) njs_set_invalid(&vm->top_frame->trap_scratch); vm->top_frame->trap_values[0] = *value; + /* + * Prevent njs_vmcode_interpreter() to unwind the current frame if + * an exception happens. It preserves the current frame state if + * njs_vm_value_to_ext_string() is called from within njs_vm_run(). + */ + previous = vm->top_frame->previous; + vm->top_frame->previous = NULL; + ret = njs_vmcode_interpreter(vm); if (ret == NJS_STOP) { @@ -3306,6 +3315,7 @@ njs_object_value_to_string(njs_vm_t *vm, njs_value_t *value) } vm->current = current; + vm->top_frame->previous = previous; return ret; } diff --git a/njs/test/njs_expect_test.exp b/njs/test/njs_expect_test.exp index 81150a02..5247c7c6 100644 --- a/njs/test/njs_expect_test.exp +++ b/njs/test/njs_expect_test.exp @@ -203,6 +203,13 @@ njs_test { "JSON.parse(Error()\r\nSyntaxError: Unexpected token \"\" in 1"} } +njs_test { + {"try { console.log({ toString: function() { throw 'test'; } }) } catch (e) {}\r\n" + "undefined"} + {"function f() { throw 't' }; try { console.log({ toString: function() { return f() } }) } catch (e) {}\r\n" + "undefined"} +} + # Non-ASCII characters njs_test { {"'絵文字'\r\n"