From: Nikita Popov Date: Sat, 4 Jul 2020 07:59:42 +0000 (+0200) Subject: Fixed bug #79777 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=49396f817a07c791f3bdfa4d301072425e0e9363;p=php Fixed bug #79777 --- diff --git a/Zend/tests/die_string_cast_exception.phpt b/Zend/tests/die_string_cast_exception.phpt new file mode 100644 index 0000000000..9893c3389f --- /dev/null +++ b/Zend/tests/die_string_cast_exception.phpt @@ -0,0 +1,13 @@ +--TEST-- +Bug #79777: String cast exception during die should be handled gracefully +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught Error: Object of class stdClass could not be converted to string in %s:%d +Stack trace: +#0 {main} + thrown in %s on line %d diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 241c56851c..c316795450 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -6893,7 +6893,10 @@ ZEND_VM_COLD_HANDLER(79, ZEND_EXIT, ANY, ANY) } while (0); FREE_OP1(); } - zend_throw_unwind_exit(); + + if (!EG(exception)) { + zend_throw_unwind_exit(); + } HANDLE_EXCEPTION(); } diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index c1975fd0b9..67f1c0d615 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -2322,7 +2322,10 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_EXIT_SPEC_HANDLER } while (0); FREE_OP(opline->op1_type, opline->op1.var); } - zend_throw_unwind_exit(); + + if (!EG(exception)) { + zend_throw_unwind_exit(); + } HANDLE_EXCEPTION(); } @@ -2476,7 +2479,6 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_dispatch_try { /* May be NULL during generator closing (only finally blocks are executed) */ zend_object *ex = EG(exception); - zend_bool is_unwind_exit = ex && zend_is_unwind_exit(ex); /* Walk try/catch/finally structures upwards, performing the necessary actions */ for (; try_catch_offset != (uint32_t) -1; try_catch_offset--) { @@ -2489,7 +2491,7 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_dispatch_try ZEND_VM_JMP_EX(&EX(func)->op_array.opcodes[try_catch->catch_op], 0); } else if (op_num < try_catch->finally_op) { - if (is_unwind_exit) { + if (ex && zend_is_unwind_exit(ex)) { /* Don't execute finally blocks on exit (for now) */ continue; }