Commit: 0312d0a262e4e15ce49dddaa1b10492aba08ec38 Author: Xinchen Hui <larue...@php.net> Thu, 16 Aug 2012 18:17:26 +0800 Parents: 018395efafeb8cbce0b8864ca4a1eac232db1cbb Branches: master
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=0312d0a262e4e15ce49dddaa1b10492aba08ec38 Log: Prevents `goto` out of a finally block Changed paths: A Zend/tests/try_finally_005.phpt A Zend/tests/try_finally_006.phpt M Zend/zend_compile.c Diff: diff --git a/Zend/tests/try_finally_005.phpt b/Zend/tests/try_finally_005.phpt new file mode 100644 index 0000000..e0937f1 --- /dev/null +++ b/Zend/tests/try_finally_005.phpt @@ -0,0 +1,17 @@ +--TEST-- +Finally with long goto +--FILE-- +<?php +function foo () { + try { + } finally { + goto label; + } +label: + return 1; +} + +foo(); +?> +--EXPECTF-- +Fatal error: 'goto' out of a finally block is disallowed in %stry_finally_005.php on line %d diff --git a/Zend/tests/try_finally_006.phpt b/Zend/tests/try_finally_006.phpt new file mode 100644 index 0000000..ba1c183 --- /dev/null +++ b/Zend/tests/try_finally_006.phpt @@ -0,0 +1,18 @@ +--TEST-- +Finally with near goto +--FILE-- +<?php +function foo () { + try { + } finally { + goto label; + echo "dummy"; +label: + echo "label"; + } +} + +foo(); +?> +--EXPECTF-- +label diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 48b85f0..378cf17 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -2277,6 +2277,25 @@ void zend_resolve_goto_label(zend_op_array *op_array, zend_op *opline, int pass2 zval_dtor(label); Z_TYPE_P(label) = IS_NULL; + if (op_array->last_try_catch) { + zend_uint i, op_num = opline - CG(active_op_array)->opcodes; + for (i=0; i<op_array->last_try_catch; i++) { + if (op_array->try_catch_array[i].try_op > op_num) { + break; + } + if (op_num >= op_array->try_catch_array[i].finally_op) { + zend_op *p, *end; + p = opline; + end = op_array->opcodes + opline->op1.opline_num; + while (++p < end) { + if (p->opcode == ZEND_LEAVE) { + zend_error(E_COMPILE_ERROR, "'goto' out of a finally block is disallowed"); + } + } + } + } + } + /* Check that we are not moving into loop or switch */ current = opline->extended_value; for (distance = 0; current != dest->brk_cont; distance++) { -- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php