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)
+}