cvs: ZendEngine2 / zend_compile.c zend_vm_def.h zend_vm_execute.h /tests bug44184.phpt

[email protected] ("Dmitry Stogov")
Newsgroups php.zend-engine.cvs
Message-ID <cvsdmitry1203509189@cvsserver>
dmitry		Wed Feb 20 12:06:29 2008 UTC

  Modified files:              
    /ZendEngine2	zend_compile.c zend_vm_def.h zend_vm_execute.h 
    /ZendEngine2/tests	bug44184.phpt 
  Log:
  Fixed bug #44184 (Double free of loop-variable on exception)
  
  
http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_compile.c?r1=1.801&r2=1.802&diff_format=u
Index: ZendEngine2/zend_compile.c
diff -u ZendEngine2/zend_compile.c:1.801 ZendEngine2/zend_compile.c:1.802
--- ZendEngine2/zend_compile.c:1.801	Tue Feb 12 09:28:17 2008
+++ ZendEngine2/zend_compile.c	Wed Feb 20 12:06:28 2008
@@ -17,7 +17,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: zend_compile.c,v 1.801 2008/02/12 09:28:17 dmitry Exp $ */
+/* $Id: zend_compile.c,v 1.802 2008/02/20 12:06:28 dmitry Exp $ */
 
 #include <zend_language_parser.h>
 #include "zend.h"
@@ -752,8 +752,14 @@
 }
 /* }}} */
 
-static inline void do_end_loop(int cont_addr TSRMLS_DC) /* {{{ */
+static inline void do_end_loop(int cont_addr, int has_loop_var TSRMLS_DC) /* {{{ */
 {
+	if (!has_loop_var) {
+		/* The start fileld is used to free temporary variables in case of exceptions.
+		 * We won't try to free something of we don't have loop variable.
+		 */
+		CG(active_op_array)->brk_cont_array[CG(active_op_array)->current_brk_cont].start = -1;
+	}
 	CG(active_op_array)->brk_cont_array[CG(active_op_array)->current_brk_cont].cont = cont_addr;
 	CG(active_op_array)->brk_cont_array[CG(active_op_array)->current_brk_cont].brk = get_next_op_number(CG(active_op_array));
 	CG(active_op_array)->current_brk_cont = CG(active_op_array)->brk_cont_array[CG(active_op_array)->current_brk_cont].parent;
@@ -788,7 +794,7 @@
 	/* update while's conditional jmp */
 	CG(active_op_array)->opcodes[close_bracket_token->u.opline_num].op2.u.opline_num = get_next_op_number(CG(active_op_array));
 
-	do_end_loop(while_token->u.opline_num TSRMLS_CC);
+	do_end_loop(while_token->u.opline_num, 0 TSRMLS_CC);
 
 	DEC_BPC(CG(active_op_array));
 }
@@ -832,7 +838,7 @@
 	SET_UNUSED(opline->op1);
 	SET_UNUSED(opline->op2);
 
-	do_end_loop(second_semicolon_token->u.opline_num+1 TSRMLS_CC);
+	do_end_loop(second_semicolon_token->u.opline_num+1, 0 TSRMLS_CC);
 
 	DEC_BPC(CG(active_op_array));
 }
@@ -3151,7 +3157,7 @@
 	opline->op2.u.opline_num = do_token->u.opline_num;
 	SET_UNUSED(opline->op2);
 
-	do_end_loop(expr_open_bracket->u.opline_num TSRMLS_CC);
+	do_end_loop(expr_open_bracket->u.opline_num, 0 TSRMLS_CC);
 
 	DEC_BPC(CG(active_op_array));
 }
@@ -4661,7 +4667,7 @@
 	CG(active_op_array)->opcodes[foreach_token->u.opline_num].op2.u.opline_num = get_next_op_number(CG(active_op_array)); /* FE_RESET */
 	CG(active_op_array)->opcodes[as_token->u.opline_num].op2.u.opline_num = get_next_op_number(CG(active_op_array)); /* FE_FETCH */
 
-	do_end_loop(as_token->u.opline_num TSRMLS_CC);
+	do_end_loop(as_token->u.opline_num, 1 TSRMLS_CC);
 
 	zend_stack_top(&CG(foreach_copy_stack), (void **) &container_ptr);
 	generate_free_foreach_copy(container_ptr TSRMLS_CC);
http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_vm_def.h?r1=1.213&r2=1.214&diff_format=u
Index: ZendEngine2/zend_vm_def.h
diff -u ZendEngine2/zend_vm_def.h:1.213 ZendEngine2/zend_vm_def.h:1.214
--- ZendEngine2/zend_vm_def.h:1.213	Mon Feb 11 15:54:46 2008
+++ ZendEngine2/zend_vm_def.h	Wed Feb 20 12:06:28 2008
@@ -18,7 +18,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: zend_vm_def.h,v 1.213 2008/02/11 15:54:46 bjori Exp $ */
+/* $Id: zend_vm_def.h,v 1.214 2008/02/20 12:06:28 dmitry Exp $ */
 
 /* If you change this file, please regenerate the zend_vm_execute.h and
  * zend_vm_opcodes.h files by running:
@@ -4219,11 +4219,12 @@
 	}
 
 	for (i=0; i<EX(op_array)->last_brk_cont; i++) {
-		if (EX(op_array)->brk_cont_array[i].start > op_num) {
+		if (EX(op_array)->brk_cont_array[i].start < 0) {
+			continue;
+		} else if (EX(op_array)->brk_cont_array[i].start > op_num) {
 			/* further blocks will not be relevant... */
 			break;
-		}
-		if (op_num < EX(op_array)->brk_cont_array[i].brk) {
+		} else if (op_num < EX(op_array)->brk_cont_array[i].brk) {
 			if (!catched ||
 			    catch_op_num >= EX(op_array)->brk_cont_array[i].brk) {
 				zend_op *brk_opline = &EX(op_array)->opcodes[EX(op_array)->brk_cont_array[i].brk];
http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_vm_execute.h?r1=1.217&r2=1.218&diff_format=u
Index: ZendEngine2/zend_vm_execute.h
diff -u ZendEngine2/zend_vm_execute.h:1.217 ZendEngine2/zend_vm_execute.h:1.218
--- ZendEngine2/zend_vm_execute.h:1.217	Mon Feb 11 15:54:46 2008
+++ ZendEngine2/zend_vm_execute.h	Wed Feb 20 12:06:28 2008
@@ -564,11 +564,12 @@
 	}
 
 	for (i=0; i<EX(op_array)->last_brk_cont; i++) {
-		if (EX(op_array)->brk_cont_array[i].start > op_num) {
+		if (EX(op_array)->brk_cont_array[i].start < 0) {
+			continue;
+		} else if (EX(op_array)->brk_cont_array[i].start > op_num) {
 			/* further blocks will not be relevant... */
 			break;
-		}
-		if (op_num < EX(op_array)->brk_cont_array[i].brk) {
+		} else if (op_num < EX(op_array)->brk_cont_array[i].brk) {
 			if (!catched ||
 			    catch_op_num >= EX(op_array)->brk_cont_array[i].brk) {
 				zend_op *brk_opline = &EX(op_array)->opcodes[EX(op_array)->brk_cont_array[i].brk];
http://cvs.php.net/viewvc.cgi/ZendEngine2/tests/bug44184.phpt?r1=1.1&r2=1.2&diff_format=u
Index: ZendEngine2/tests/bug44184.phpt
diff -u /dev/null ZendEngine2/tests/bug44184.phpt:1.2
--- /dev/null	Wed Feb 20 12:06:29 2008
+++ ZendEngine2/tests/bug44184.phpt	Wed Feb 20 12:06:29 2008
@@ -0,0 +1,21 @@
+--TEST--
+Bug #44184 (Double free of loop-variable on exception)
+--FILE--
+<?php
+function foo() {
+	$x = array(1,2,3);
+	foreach ($x as $a) {
+		while (1) {
+			throw new Exception();
+		}
+	    return;
+	}
+}
+try {
+	foo();
+} catch (Exception $ex) {
+	echo "ok\n";
+}
+?>
+--EXPECT--
+ok
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.