cvs: ZendEngine2 / zend_compile.c zend_language_parser.y zend_vm_def.h zend_vm_execute.h /tests bug45178.phpt

"Dmitry Stogov" <[email protected]>
Newsgroups gmane.comp.php.cvs.zend
Message-ID <cvsdmitry1216900111@cvsserver>
dmitry		Thu Jul 24 11:48:31 2008 UTC

  Modified files:              
    /ZendEngine2	zend_compile.c zend_language_parser.y zend_vm_def.h 
                	zend_vm_execute.h 
    /ZendEngine2/tests	bug45178.phpt 
  Log:
  Fixed bug #45178 (memory corruption on assignment result of "new" by reference)

-- 
Zend Engine CVS Mailing List (http://cvs.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php
dmitry-20080724114831.txt (text/plain, 9.4 KB)
http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_compile.c?r1=1.829&r2=1.830&diff_format=u
Index: ZendEngine2/zend_compile.c
diff -u ZendEngine2/zend_compile.c:1.829 ZendEngine2/zend_compile.c:1.830
--- ZendEngine2/zend_compile.c:1.829	Mon Jul 14 12:17:16 2008
+++ ZendEngine2/zend_compile.c	Thu Jul 24 11:48:30 2008
@@ -17,7 +17,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: zend_compile.c,v 1.829 2008/07/14 12:17:16 dmitry Exp $ */
+/* $Id: zend_compile.c,v 1.830 2008/07/24 11:48:30 dmitry Exp $ */
 
 #include <zend_language_parser.h>
 #include "zend.h"
@@ -737,6 +737,8 @@
 	opline->opcode = ZEND_ASSIGN_REF;
 	if (zend_is_function_or_method_call(rvar)) {
 		opline->extended_value = ZEND_RETURNS_FUNCTION;
+	} else if (rvar->u.EA.type & ZEND_PARSED_NEW) {
+		opline->extended_value = ZEND_RETURNS_NEW;
 	} else {
 		opline->extended_value = 0;
 	}
http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_language_parser.y?r1=1.207&r2=1.208&diff_format=u
Index: ZendEngine2/zend_language_parser.y
diff -u ZendEngine2/zend_language_parser.y:1.207 ZendEngine2/zend_language_parser.y:1.208
--- ZendEngine2/zend_language_parser.y:1.207	Tue Jul  8 07:05:03 2008
+++ ZendEngine2/zend_language_parser.y	Thu Jul 24 11:48:30 2008
@@ -18,7 +18,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: zend_language_parser.y,v 1.207 2008/07/08 07:05:03 dmitry Exp $ */
+/* $Id: zend_language_parser.y,v 1.208 2008/07/24 11:48:30 dmitry Exp $ */
 
 /*
  * LALR shift/reduce conflicts and how they are resolved:
@@ -578,7 +578,7 @@
 		T_LIST '(' { zend_do_list_init(TSRMLS_C); } assignment_list ')' '=' expr { zend_do_list_end(&$$, &$7 TSRMLS_CC); }
 	|	variable '=' expr		{ zend_check_writable_variable(&$1); zend_do_assign(&$$, &$1, &$3 TSRMLS_CC); }
 	|	variable '=' '&' variable { zend_check_writable_variable(&$1); zend_do_end_variable_parse(&$4, BP_VAR_W, 1 TSRMLS_CC); zend_do_end_variable_parse(&$1, BP_VAR_W, 0 TSRMLS_CC); zend_do_assign_ref(&$$, &$1, &$4 TSRMLS_CC); }
-	|	variable '=' '&' T_NEW class_name_reference { zend_error(E_DEPRECATED, "Assigning the return value of new by reference is deprecated");  zend_check_writable_variable(&$1); zend_do_extended_fcall_begin(TSRMLS_C); zend_do_begin_new_object(&$4, &$5 TSRMLS_CC); } ctor_arguments { zend_do_end_new_object(&$3, &$4, &$7 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C); zend_do_end_variable_parse(&$1, BP_VAR_W, 0 TSRMLS_CC); zend_do_assign_ref(&$$, &$1, &$3 TSRMLS_CC); }
+	|	variable '=' '&' T_NEW class_name_reference { zend_error(E_DEPRECATED, "Assigning the return value of new by reference is deprecated");  zend_check_writable_variable(&$1); zend_do_extended_fcall_begin(TSRMLS_C); zend_do_begin_new_object(&$4, &$5 TSRMLS_CC); } ctor_arguments { zend_do_end_new_object(&$3, &$4, &$7 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C); zend_do_end_variable_parse(&$1, BP_VAR_W, 0 TSRMLS_CC); $3.u.EA.type = ZEND_PARSED_NEW; zend_do_assign_ref(&$$, &$1, &$3 TSRMLS_CC); }
 	|	T_NEW class_name_reference { zend_do_extended_fcall_begin(TSRMLS_C); zend_do_begin_new_object(&$1, &$2 TSRMLS_CC); } ctor_arguments { zend_do_end_new_object(&$$, &$1, &$4 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C); $$.u.EA.type = ZEND_PARSED_NEW; }
 	|	T_CLONE expr { zend_do_clone(&$$, &$2 TSRMLS_CC); }
 	|	variable T_PLUS_EQUAL expr 	{ zend_check_writable_variable(&$1); zend_do_end_variable_parse(&$1, BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_ADD, &$$, &$1, &$3 TSRMLS_CC); }
http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_vm_def.h?r1=1.235&r2=1.236&diff_format=u
Index: ZendEngine2/zend_vm_def.h
diff -u ZendEngine2/zend_vm_def.h:1.235 ZendEngine2/zend_vm_def.h:1.236
--- ZendEngine2/zend_vm_def.h:1.235	Thu Jul 24 10:13:59 2008
+++ ZendEngine2/zend_vm_def.h	Thu Jul 24 11:48:30 2008
@@ -18,7 +18,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: zend_vm_def.h,v 1.235 2008/07/24 10:13:59 dmitry Exp $ */
+/* $Id: zend_vm_def.h,v 1.236 2008/07/24 11:48:30 dmitry Exp $ */
 
 /* If you change this file, please regenerate the zend_vm_execute.h and
  * zend_vm_opcodes.h files by running:
@@ -1665,6 +1665,8 @@
 		}
 		zend_error(E_STRICT, "Only variables should be assigned by reference");
 		ZEND_VM_DISPATCH_TO_HANDLER(ZEND_ASSIGN);
+	} else if (OP2_TYPE == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
+		PZVAL_LOCK(*value_ptr_ptr);
 	}
 	if (OP1_TYPE == IS_VAR && EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr) {
 		zend_error(E_ERROR, "Cannot assign by reference to overloaded object");
@@ -1677,6 +1679,10 @@
 	}
 	zend_assign_to_variable_reference(variable_ptr_ptr, value_ptr_ptr TSRMLS_CC);
 
+	if (OP2_TYPE == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
+		Z_DELREF_PP(variable_ptr_ptr);
+	}
+
 	if (!RETURN_VALUE_UNUSED(&opline->result)) {
 		AI_SET_PTR(EX_T(opline->result.u.var).var, *variable_ptr_ptr);
 		PZVAL_LOCK(*variable_ptr_ptr);
http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_vm_execute.h?r1=1.239&r2=1.240&diff_format=u
Index: ZendEngine2/zend_vm_execute.h
diff -u ZendEngine2/zend_vm_execute.h:1.239 ZendEngine2/zend_vm_execute.h:1.240
--- ZendEngine2/zend_vm_execute.h:1.239	Thu Jul 24 10:13:59 2008
+++ ZendEngine2/zend_vm_execute.h	Thu Jul 24 11:48:30 2008
@@ -14338,6 +14338,8 @@
 		}
 		zend_error(E_STRICT, "Only variables should be assigned by reference");
 		return ZEND_ASSIGN_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+	} else if (IS_VAR == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
+		PZVAL_LOCK(*value_ptr_ptr);
 	}
 	if (IS_VAR == IS_VAR && EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr) {
 		zend_error(E_ERROR, "Cannot assign by reference to overloaded object");
@@ -14350,6 +14352,10 @@
 	}
 	zend_assign_to_variable_reference(variable_ptr_ptr, value_ptr_ptr TSRMLS_CC);
 
+	if (IS_VAR == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
+		Z_DELREF_PP(variable_ptr_ptr);
+	}
+
 	if (!RETURN_VALUE_UNUSED(&opline->result)) {
 		AI_SET_PTR(EX_T(opline->result.u.var).var, *variable_ptr_ptr);
 		PZVAL_LOCK(*variable_ptr_ptr);
@@ -16820,6 +16826,8 @@
 		}
 		zend_error(E_STRICT, "Only variables should be assigned by reference");
 		return ZEND_ASSIGN_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+	} else if (IS_CV == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
+		PZVAL_LOCK(*value_ptr_ptr);
 	}
 	if (IS_VAR == IS_VAR && EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr) {
 		zend_error(E_ERROR, "Cannot assign by reference to overloaded object");
@@ -16832,6 +16840,10 @@
 	}
 	zend_assign_to_variable_reference(variable_ptr_ptr, value_ptr_ptr TSRMLS_CC);
 
+	if (IS_CV == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
+		Z_DELREF_PP(variable_ptr_ptr);
+	}
+
 	if (!RETURN_VALUE_UNUSED(&opline->result)) {
 		AI_SET_PTR(EX_T(opline->result.u.var).var, *variable_ptr_ptr);
 		PZVAL_LOCK(*variable_ptr_ptr);
@@ -28214,6 +28226,8 @@
 		}
 		zend_error(E_STRICT, "Only variables should be assigned by reference");
 		return ZEND_ASSIGN_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+	} else if (IS_VAR == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
+		PZVAL_LOCK(*value_ptr_ptr);
 	}
 	if (IS_CV == IS_VAR && EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr) {
 		zend_error(E_ERROR, "Cannot assign by reference to overloaded object");
@@ -28226,6 +28240,10 @@
 	}
 	zend_assign_to_variable_reference(variable_ptr_ptr, value_ptr_ptr TSRMLS_CC);
 
+	if (IS_VAR == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
+		Z_DELREF_PP(variable_ptr_ptr);
+	}
+
 	if (!RETURN_VALUE_UNUSED(&opline->result)) {
 		AI_SET_PTR(EX_T(opline->result.u.var).var, *variable_ptr_ptr);
 		PZVAL_LOCK(*variable_ptr_ptr);
@@ -30467,6 +30485,8 @@
 		}
 		zend_error(E_STRICT, "Only variables should be assigned by reference");
 		return ZEND_ASSIGN_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+	} else if (IS_CV == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
+		PZVAL_LOCK(*value_ptr_ptr);
 	}
 	if (IS_CV == IS_VAR && EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr) {
 		zend_error(E_ERROR, "Cannot assign by reference to overloaded object");
@@ -30479,6 +30499,10 @@
 	}
 	zend_assign_to_variable_reference(variable_ptr_ptr, value_ptr_ptr TSRMLS_CC);
 
+	if (IS_CV == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
+		Z_DELREF_PP(variable_ptr_ptr);
+	}
+
 	if (!RETURN_VALUE_UNUSED(&opline->result)) {
 		AI_SET_PTR(EX_T(opline->result.u.var).var, *variable_ptr_ptr);
 		PZVAL_LOCK(*variable_ptr_ptr);
http://cvs.php.net/viewvc.cgi/ZendEngine2/tests/bug45178.phpt?r1=1.1&r2=1.2&diff_format=u
Index: ZendEngine2/tests/bug45178.phpt
diff -u /dev/null ZendEngine2/tests/bug45178.phpt:1.2
--- /dev/null	Thu Jul 24 11:48:31 2008
+++ ZendEngine2/tests/bug45178.phpt	Thu Jul 24 11:48:30 2008
@@ -0,0 +1,29 @@
+--TEST--
+Bug #45178 memory corruption on assignment result of "new" by reference
+--FILE--
+<?php
+class Foo {
+    function __construct() {
+    	$this->error = array($this,$this);
+    }
+}
+$a =& new Foo();
+
+class Bar {
+	function __construct() {
+		$this->_rme2 = $this;
+	}
+}
+
+$b =& new Bar();
+$b->_rme2 = 0;
+var_dump($b);
+?>
+--EXPECTF--
+Deprecated: Assigning the return value of new by reference is deprecated in %sbug45178.php on line 7
+
+Deprecated: Assigning the return value of new by reference is deprecated in %sbug45178.php on line 15
+object(Bar)#%d (1) {
+  [u"_rme2"]=>
+  int(0)
+}
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.