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

Reply via email to