]> git.kaiwu.me - njs.git/commitdiff
Fixed exception handling in njs_vm_value_to_ext_string().
authorDmitry Volyntsev <xeioex@nginx.com>
Tue, 17 Jul 2018 17:25:47 +0000 (20:25 +0300)
committerDmitry Volyntsev <xeioex@nginx.com>
Tue, 17 Jul 2018 17:25:47 +0000 (20:25 +0300)
njs/njs_vm.c
njs/test/njs_expect_test.exp

index ec4fe2ead97dd83da036b7ff5e87edd9d51ad0f4..bf2e7fc342d26800ddccc0177a272370ab33bab1 100644 (file)
@@ -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;
 }
index 81150a029a55b8b6aa171ebc1286873f8a0e2d08..5247c7c6f2c446311febe4ac65de824e64b36b05 100644 (file)
@@ -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"