Skip to content

Commit 0312d0a

Browse files
committed
Prevents goto out of a finally block
1 parent 018395e commit 0312d0a

File tree

3 files changed

+54
-0
lines changed

3 files changed

+54
-0
lines changed

Zend/tests/try_finally_005.phpt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
--TEST--
2+
Finally with long goto
3+
--FILE--
4+
<?php
5+
function foo () {
6+
try {
7+
} finally {
8+
goto label;
9+
}
10+
label:
11+
return 1;
12+
}
13+
14+
foo();
15+
?>
16+
--EXPECTF--
17+
Fatal error: 'goto' out of a finally block is disallowed in %stry_finally_005.php on line %d

Zend/tests/try_finally_006.phpt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
--TEST--
2+
Finally with near goto
3+
--FILE--
4+
<?php
5+
function foo () {
6+
try {
7+
} finally {
8+
goto label;
9+
echo "dummy";
10+
label:
11+
echo "label";
12+
}
13+
}
14+
15+
foo();
16+
?>
17+
--EXPECTF--
18+
label

Zend/zend_compile.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2277,6 +2277,25 @@ void zend_resolve_goto_label(zend_op_array *op_array, zend_op *opline, int pass2
22772277
zval_dtor(label);
22782278
Z_TYPE_P(label) = IS_NULL;
22792279

2280+
if (op_array->last_try_catch) {
2281+
zend_uint i, op_num = opline - CG(active_op_array)->opcodes;
2282+
for (i=0; i<op_array->last_try_catch; i++) {
2283+
if (op_array->try_catch_array[i].try_op > op_num) {
2284+
break;
2285+
}
2286+
if (op_num >= op_array->try_catch_array[i].finally_op) {
2287+
zend_op *p, *end;
2288+
p = opline;
2289+
end = op_array->opcodes + opline->op1.opline_num;
2290+
while (++p < end) {
2291+
if (p->opcode == ZEND_LEAVE) {
2292+
zend_error(E_COMPILE_ERROR, "'goto' out of a finally block is disallowed");
2293+
}
2294+
}
2295+
}
2296+
}
2297+
}
2298+
22802299
/* Check that we are not moving into loop or switch */
22812300
current = opline->extended_value;
22822301
for (distance = 0; current != dest->brk_cont; distance++) {

0 commit comments

Comments
 (0)