[njs] Fixed exception handling in njs_vm_value_to_ext_string().

Dmitry Volyntsev xeioex at nginx.com
Tue Jul 17 17:25:52 UTC 2018


details:   http://hg.nginx.org/njs/rev/729072cc162f
branches:  
changeset: 559:729072cc162f
user:      Dmitry Volyntsev <xeioex at nginx.com>
date:      Tue Jul 17 20:25:47 2018 +0300
description:
Fixed exception handling in njs_vm_value_to_ext_string().

diffstat:

 njs/njs_vm.c                 |  14 ++++++++++++--
 njs/test/njs_expect_test.exp |   7 +++++++
 2 files changed, 19 insertions(+), 2 deletions(-)

diffs (55 lines):

diff -r 04dc301f7d5a -r 729072cc162f njs/njs_vm.c
--- a/njs/njs_vm.c	Mon Jul 16 14:30:41 2018 +0300
+++ b/njs/njs_vm.c	Tue Jul 17 20:25:47 2018 +0300
@@ -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_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,
     }
 
     vm->current = current;
+    vm->top_frame->previous = previous;
 
     return ret;
 }
diff -r 04dc301f7d5a -r 729072cc162f njs/test/njs_expect_test.exp
--- a/njs/test/njs_expect_test.exp	Mon Jul 16 14:30:41 2018 +0300
+++ b/njs/test/njs_expect_test.exp	Tue Jul 17 20:25:47 2018 +0300
@@ -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"


More information about the nginx-devel mailing list