Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Refactor examing of jumping out of finally block

  • Loading branch information...
commit f2a8912e618d4bd8ff5be266e37f2b6e2280e994 1 parent 2449365
Xinchen Hui laruence authored
2  Zend/tests/try_finally_005.phpt
@@ -14,4 +14,4 @@ label:
14 14 foo();
15 15 ?>
16 16 --EXPECTF--
17   -Fatal error: 'goto' out of a finally block is disallowed in %stry_finally_005.php on line %d
  17 +Fatal error: jump out of a finally block is disallowed in %stry_finally_005.php on line %d
14 Zend/tests/try_finally_006.phpt
@@ -3,12 +3,19 @@ Finally with near goto
3 3 --FILE--
4 4 <?php
5 5 function foo () {
  6 + $jmp = 1;
6 7 try {
7 8 } finally {
8   - goto label;
9   - echo "dummy";
  9 +previous:
  10 + if ($jmp) {
  11 + goto label;
  12 + echo "dummy";
10 13 label:
11   - echo "label";
  14 + echo "label\n";
  15 + $jmp = 0;
  16 + goto previous;
  17 + }
  18 + echo "okey";
12 19 }
13 20 }
14 21
@@ -16,3 +23,4 @@ foo();
16 23 ?>
17 24 --EXPECTF--
18 25 label
  26 +okey
22 Zend/tests/try_finally_007.phpt
... ... @@ -0,0 +1,22 @@
  1 +--TEST--
  2 +Finally with goto previous label
  3 +--FILE--
  4 +<?php
  5 +function foo () {
  6 + try {
  7 +label:
  8 + echo "label";
  9 + try {
  10 + } finally {
  11 + goto label;
  12 + echo "dummy";
  13 + }
  14 + } catch (Exception $e) {
  15 + } finally {
  16 + }
  17 +}
  18 +
  19 +foo();
  20 +?>
  21 +--EXPECTF--
  22 +Fatal error: jump out of a finally block is disallowed in %stry_finally_007.php on line %d
24 Zend/tests/try_finally_008.phpt
... ... @@ -0,0 +1,24 @@
  1 +--TEST--
  2 +Finally with jmp (do while)
  3 +--FILE--
  4 +<?php
  5 +function foo () {
  6 + do {
  7 + try {
  8 + try {
  9 + } finally {
  10 + goto label;
  11 + echo "dummy";
  12 + }
  13 + } catch (Exception $e) {
  14 + } finally {
  15 + }
  16 + } while (0);
  17 +label:
  18 + echo "label";
  19 +}
  20 +
  21 +foo();
  22 +?>
  23 +--EXPECTF--
  24 +Fatal error: jump out of a finally block is disallowed in %stry_finally_008.php on line %d
30 Zend/zend_compile.c
@@ -2277,30 +2277,6 @@ void zend_resolve_goto_label(zend_op_array *op_array, zend_op *opline, int pass2
2277 2277 zval_dtor(label);
2278 2278 Z_TYPE_P(label) = IS_NULL;
2279 2279
2280   - if (op_array->last_try_catch) {
2281   - zend_uint i, op_num = opline - 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   - if (pass2) {
2293   - CG(in_compilation) = 1;
2294   - CG(active_op_array) = op_array;
2295   - CG(zend_lineno) = opline->lineno;
2296   - }
2297   - zend_error(E_COMPILE_ERROR, "'goto' out of a finally block is disallowed");
2298   - }
2299   - }
2300   - }
2301   - }
2302   - }
2303   -
2304 2280 /* Check that we are not moving into loop or switch */
2305 2281 current = opline->extended_value;
2306 2282 for (distance = 0; current != dest->brk_cont; distance++) {
@@ -2686,6 +2662,7 @@ static int zend_add_try_element(zend_uint try_op TSRMLS_DC) /* {{{ */
2686 2662 CG(active_op_array)->try_catch_array = erealloc(CG(active_op_array)->try_catch_array, sizeof(zend_try_catch_element)*CG(active_op_array)->last_try_catch);
2687 2663 CG(active_op_array)->try_catch_array[try_catch_offset].try_op = try_op;
2688 2664 CG(active_op_array)->try_catch_array[try_catch_offset].finally_op = 0;
  2665 + CG(active_op_array)->try_catch_array[try_catch_offset].finally_end = 0;
2689 2666 return try_catch_offset;
2690 2667 }
2691 2668 /* }}} */
@@ -2808,14 +2785,13 @@ void zend_do_bind_catch(znode *try_token, znode *catch_token TSRMLS_DC) /* {{{ *
2808 2785
2809 2786 void zend_do_end_finally(znode *try_token, znode* catch_token, znode *finally_token TSRMLS_DC) /* {{{ */
2810 2787 {
2811   - zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
2812   -
2813 2788 if (catch_token->op_type == IS_UNUSED && finally_token->op_type == IS_UNUSED) {
2814 2789 zend_error(E_COMPILE_ERROR, "Cannot use try without catch or finally");
2815 2790 }
2816 2791 if (finally_token->op_type != IS_UNUSED) {
  2792 + zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
2817 2793 CG(active_op_array)->try_catch_array[try_token->u.op.opline_num].finally_op = finally_token->u.op.opline_num;
2818   - //try_token->u.op.opline_num = catch_token->u.op.opline_num;
  2794 + CG(active_op_array)->try_catch_array[try_token->u.op.opline_num].finally_end = get_next_op_number(CG(active_op_array));
2819 2795
2820 2796 opline->opcode = ZEND_LEAVE;
2821 2797 SET_UNUSED(opline->op1);
3  Zend/zend_compile.h
@@ -132,7 +132,8 @@ typedef struct _zend_label {
132 132 typedef struct _zend_try_catch_element {
133 133 zend_uint try_op;
134 134 zend_uint catch_op; /* ketchup! */
135   - zend_uint finally_op;
  135 + zend_uint finally_op;
  136 + zend_uint finally_end;
136 137 } zend_try_catch_element;
137 138
138 139 #if SIZEOF_LONG == 8
17 Zend/zend_opcode.c
@@ -528,6 +528,23 @@ ZEND_API int pass_two(zend_op_array *op_array TSRMLS_DC)
528 528 }
529 529 /* break omitted intentionally */
530 530 case ZEND_JMP:
  531 + if (op_array->last_try_catch) {
  532 + zend_uint i, op_num = opline - op_array->opcodes;
  533 + for (i=0; i < op_array->last_try_catch; i++) {
  534 + if (op_array->try_catch_array[i].try_op > op_num) {
  535 + break;
  536 + }
  537 + if ((op_num >= op_array->try_catch_array[i].finally_op
  538 + && op_num < op_array->try_catch_array[i].finally_end)
  539 + && (opline->op1.opline_num >= op_array->try_catch_array[i].finally_end
  540 + || opline->op1.opline_num < op_array->try_catch_array[i].finally_op)) {
  541 + CG(in_compilation) = 1;
  542 + CG(active_op_array) = op_array;
  543 + CG(zend_lineno) = opline->lineno;
  544 + zend_error(E_COMPILE_ERROR, "jump out of a finally block is disallowed");
  545 + }
  546 + }
  547 + }
531 548 opline->op1.jmp_addr = &op_array->opcodes[opline->op1.opline_num];
532 549 break;
533 550 case ZEND_JMPZ:

0 comments on commit f2a8912

Please sign in to comment.
Something went wrong with that request. Please try again.