cvs: ZendEngine2(PHP_5_2) / zend_compile.c zend_compile.h zend_language_parser.y zend_vm_def.h zend_vm_execute.h /tests bug45178.phpt php-src NEWS

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

  Added files:                 (Branch: PHP_5_2)
    /ZendEngine2/tests	bug45178.phpt 

  Modified files:              
    /php-src	NEWS 
    /ZendEngine2	zend_compile.c zend_compile.h zend_language_parser.y 
                	zend_vm_def.h zend_vm_execute.h 
  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-20080724114717.txt (text/plain, 10.9 KB)
http://cvs.php.net/viewvc.cgi/php-src/NEWS?r1=1.2027.2.547.2.1181&r2=1.2027.2.547.2.1182&diff_format=u
Index: php-src/NEWS
diff -u php-src/NEWS:1.2027.2.547.2.1181 php-src/NEWS:1.2027.2.547.2.1182
--- php-src/NEWS:1.2027.2.547.2.1181	Wed Jul 23 12:05:21 2008
+++ php-src/NEWS	Thu Jul 24 11:47:12 2008
@@ -33,6 +33,8 @@
 - Fixed bug #45251 (double free or corruption with setAttributeNode()). (Rob)
 - Fixed bug #45220 (curl_read callback returns -1 when needs to return 
   size_t (unsigned)). (Felipe)
+- Fixed bug #45178 (memory corruption on assignment result of "new" by
+  reference). (Dmitry)
 - Fixed bug #45151 (Crash with URI/file..php (filename contains 2 dots)).
   (Dmitry)
 - Fixed bug #45139 (ReflectionProperty returns incorrect declaring class).
http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_compile.c?r1=1.647.2.27.2.49&r2=1.647.2.27.2.50&diff_format=u
Index: ZendEngine2/zend_compile.c
diff -u ZendEngine2/zend_compile.c:1.647.2.27.2.49 ZendEngine2/zend_compile.c:1.647.2.27.2.50
--- ZendEngine2/zend_compile.c:1.647.2.27.2.49	Sun Jun 15 18:31:10 2008
+++ ZendEngine2/zend_compile.c	Thu Jul 24 11:47:12 2008
@@ -17,7 +17,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: zend_compile.c,v 1.647.2.27.2.49 2008/06/15 18:31:10 felipe Exp $ */
+/* $Id: zend_compile.c,v 1.647.2.27.2.50 2008/07/24 11:47:12 dmitry Exp $ */
 
 #include <zend_language_parser.h>
 #include "zend.h"
@@ -655,6 +655,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_compile.h?r1=1.316.2.8.2.13&r2=1.316.2.8.2.14&diff_format=u
Index: ZendEngine2/zend_compile.h
diff -u ZendEngine2/zend_compile.h:1.316.2.8.2.13 ZendEngine2/zend_compile.h:1.316.2.8.2.14
--- ZendEngine2/zend_compile.h:1.316.2.8.2.13	Mon Dec 31 07:20:02 2007
+++ ZendEngine2/zend_compile.h	Thu Jul 24 11:47:12 2008
@@ -17,7 +17,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: zend_compile.h,v 1.316.2.8.2.13 2007/12/31 07:20:02 sebastian Exp $ */
+/* $Id: zend_compile.h,v 1.316.2.8.2.14 2008/07/24 11:47:12 dmitry Exp $ */
 
 #ifndef ZEND_COMPILE_H
 #define ZEND_COMPILE_H
@@ -600,6 +600,7 @@
 #define ZEND_PARSED_FUNCTION_CALL		(1<<3)
 #define ZEND_PARSED_VARIABLE			(1<<4)
 #define ZEND_PARSED_REFERENCE_VARIABLE	(1<<5)
+#define ZEND_PARSED_NEW					(1<<6)
 
 
 /* unset types */
@@ -685,6 +686,7 @@
 
 
 #define ZEND_RETURNS_FUNCTION 1<<0
+#define ZEND_RETURNS_NEW      1<<1
 
 END_EXTERN_C()
 
http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_language_parser.y?r1=1.160.2.4.2.10&r2=1.160.2.4.2.11&diff_format=u
Index: ZendEngine2/zend_language_parser.y
diff -u ZendEngine2/zend_language_parser.y:1.160.2.4.2.10 ZendEngine2/zend_language_parser.y:1.160.2.4.2.11
--- ZendEngine2/zend_language_parser.y:1.160.2.4.2.10	Mon Mar 10 14:54:47 2008
+++ ZendEngine2/zend_language_parser.y	Thu Jul 24 11:47:12 2008
@@ -18,7 +18,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: zend_language_parser.y,v 1.160.2.4.2.10 2008/03/10 14:54:47 felipe Exp $ */
+/* $Id: zend_language_parser.y,v 1.160.2.4.2.11 2008/07/24 11:47:12 dmitry Exp $ */
 
 /*
  * LALR shift/reduce conflicts and how they are resolved:
@@ -553,7 +553,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(BP_VAR_W, 0 TSRMLS_CC); zend_do_end_variable_parse(BP_VAR_W, 0 TSRMLS_CC); zend_do_assign_ref(&$$, &$1, &$4 TSRMLS_CC); }
-	|	variable '=' '&' T_NEW class_name_reference { zend_error(E_STRICT, "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(BP_VAR_W, 0 TSRMLS_CC); zend_do_assign_ref(&$$, &$1, &$3 TSRMLS_CC); }
+	|	variable '=' '&' T_NEW class_name_reference { zend_error(E_STRICT, "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(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);}
 	|	T_CLONE expr { zend_do_clone(&$$, &$2 TSRMLS_CC); }
 	|	variable T_PLUS_EQUAL expr 	{ zend_check_writable_variable(&$1); zend_do_end_variable_parse(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.59.2.29.2.56&r2=1.59.2.29.2.57&diff_format=u
Index: ZendEngine2/zend_vm_def.h
diff -u ZendEngine2/zend_vm_def.h:1.59.2.29.2.56 ZendEngine2/zend_vm_def.h:1.59.2.29.2.57
--- ZendEngine2/zend_vm_def.h:1.59.2.29.2.56	Tue Mar  4 11:46:09 2008
+++ ZendEngine2/zend_vm_def.h	Thu Jul 24 11:47:12 2008
@@ -18,7 +18,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: zend_vm_def.h,v 1.59.2.29.2.56 2008/03/04 11:46:09 dmitry Exp $ */
+/* $Id: zend_vm_def.h,v 1.59.2.29.2.57 2008/07/24 11:47:12 dmitry Exp $ */
 
 /* If you change this file, please regenerate the zend_vm_execute.h and
  * zend_vm_opcodes.h files by running:
@@ -1483,6 +1483,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");
@@ -1491,6 +1493,10 @@
 	variable_ptr_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
 	zend_assign_to_variable_reference(variable_ptr_ptr, value_ptr_ptr TSRMLS_CC);
 
+	if (OP2_TYPE == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
+		(*variable_ptr_ptr)->refcount--;
+	}
+
 	if (!RETURN_VALUE_UNUSED(&opline->result)) {
 		EX_T(opline->result.u.var).var.ptr_ptr = variable_ptr_ptr;
 		PZVAL_LOCK(*variable_ptr_ptr);
http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_vm_execute.h?r1=1.62.2.30.2.59&r2=1.62.2.30.2.60&diff_format=u
Index: ZendEngine2/zend_vm_execute.h
diff -u ZendEngine2/zend_vm_execute.h:1.62.2.30.2.59 ZendEngine2/zend_vm_execute.h:1.62.2.30.2.60
--- ZendEngine2/zend_vm_execute.h:1.62.2.30.2.59	Tue Mar  4 11:46:09 2008
+++ ZendEngine2/zend_vm_execute.h	Thu Jul 24 11:47:12 2008
@@ -12386,6 +12386,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");
@@ -12394,6 +12396,10 @@
 	variable_ptr_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
 	zend_assign_to_variable_reference(variable_ptr_ptr, value_ptr_ptr TSRMLS_CC);
 
+	if (IS_VAR == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
+		(*variable_ptr_ptr)->refcount--;
+	}
+
 	if (!RETURN_VALUE_UNUSED(&opline->result)) {
 		EX_T(opline->result.u.var).var.ptr_ptr = variable_ptr_ptr;
 		PZVAL_LOCK(*variable_ptr_ptr);
@@ -14388,6 +14394,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");
@@ -14396,6 +14404,10 @@
 	variable_ptr_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
 	zend_assign_to_variable_reference(variable_ptr_ptr, value_ptr_ptr TSRMLS_CC);
 
+	if (IS_CV == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
+		(*variable_ptr_ptr)->refcount--;
+	}
+
 	if (!RETURN_VALUE_UNUSED(&opline->result)) {
 		EX_T(opline->result.u.var).var.ptr_ptr = variable_ptr_ptr;
 		PZVAL_LOCK(*variable_ptr_ptr);
@@ -24495,6 +24507,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");
@@ -24503,6 +24517,10 @@
 	variable_ptr_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
 	zend_assign_to_variable_reference(variable_ptr_ptr, value_ptr_ptr TSRMLS_CC);
 
+	if (IS_VAR == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
+		(*variable_ptr_ptr)->refcount--;
+	}
+
 	if (!RETURN_VALUE_UNUSED(&opline->result)) {
 		EX_T(opline->result.u.var).var.ptr_ptr = variable_ptr_ptr;
 		PZVAL_LOCK(*variable_ptr_ptr);
@@ -26487,6 +26505,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");
@@ -26495,6 +26515,10 @@
 	variable_ptr_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
 	zend_assign_to_variable_reference(variable_ptr_ptr, value_ptr_ptr TSRMLS_CC);
 
+	if (IS_CV == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
+		(*variable_ptr_ptr)->refcount--;
+	}
+
 	if (!RETURN_VALUE_UNUSED(&opline->result)) {
 		EX_T(opline->result.u.var).var.ptr_ptr = variable_ptr_ptr;
 		PZVAL_LOCK(*variable_ptr_ptr);

http://cvs.php.net/viewvc.cgi/ZendEngine2/tests/bug45178.phpt?view=markup&rev=1.1
Index: ZendEngine2/tests/bug45178.phpt
+++ ZendEngine2/tests/bug45178.phpt
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.