dmitry Thu May 5 13:37:25 2005 EDT
Modified files:
/ZendEngine2 zend_compile.c zend_vm_def.h zend_vm_execute.h
zend_vm_opcodes.h
/ZendEngine2/tests bug31525.phpt
/php-src/tests/lang bug20175.phpt bug21600.phpt
Log:
Fixed bug #31525 (object reference being dropped. $this getting lost)
http://cvs.php.net/diff.php/ZendEngine2/zend_compile.c?r1=1.622&r2=1.623&ty=u
Index: ZendEngine2/zend_compile.c
diff -u ZendEngine2/zend_compile.c:1.622 ZendEngine2/zend_compile.c:1.623
--- ZendEngine2/zend_compile.c:1.622 Wed Apr 27 09:30:53 2005
+++ ZendEngine2/zend_compile.c Thu May 5 13:37:24 2005
@@ -17,7 +17,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: zend_compile.c,v 1.622 2005/04/27 13:30:53 dmitry Exp $ */
+/* $Id: zend_compile.c,v 1.623 2005/05/05 17:37:24 dmitry Exp $ */
#include <zend_language_parser.h>
#include "zend.h"
@@ -562,6 +562,12 @@
}
}
+static inline zend_bool zend_is_function_or_method_call(znode *variable)
+{
+ zend_uint type = variable->u.EA.type;
+
+ return ((type & ZEND_PARSED_METHOD_CALL) || (type ==
ZEND_PARSED_FUNCTION_CALL));
+}
void zend_do_assign_ref(znode *result, znode *lvar, znode *rvar TSRMLS_DC)
{
@@ -573,6 +579,11 @@
if (opline_is_fetch_this(last_op TSRMLS_CC)) {
zend_error(E_COMPILE_ERROR, "Cannot re-assign $this");
}
+ if (zend_is_function_or_method_call(rvar)) {
+ opline->extended_value = ZEND_RETURNS_FUNCTION;
+ } else {
+ opline->extended_value = 0;
+ }
if (result) {
opline->result.op_type = IS_VAR;
opline->result.u.EA.type = 0;
@@ -796,13 +807,6 @@
}
}
-static inline zend_bool zend_is_function_or_method_call(znode *variable)
-{
- zend_uint type = variable->u.EA.type;
-
- return ((type & ZEND_PARSED_METHOD_CALL) || (type ==
ZEND_PARSED_FUNCTION_CALL));
-}
-
void zend_do_begin_variable_parse(TSRMLS_D)
{
zend_llist fetch_list;
http://cvs.php.net/diff.php/ZendEngine2/zend_vm_def.h?r1=1.25&r2=1.26&ty=u
Index: ZendEngine2/zend_vm_def.h
diff -u ZendEngine2/zend_vm_def.h:1.25 ZendEngine2/zend_vm_def.h:1.26
--- ZendEngine2/zend_vm_def.h:1.25 Wed May 4 07:17:28 2005
+++ ZendEngine2/zend_vm_def.h Thu May 5 13:37:24 2005
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: zend_vm_def.h,v 1.25 2005/05/04 11:17:28 dmitry Exp $ */
+/* $Id: zend_vm_def.h,v 1.26 2005/05/05 17:37:24 dmitry Exp $ */
ZEND_VM_HANDLER(1, ZEND_ADD, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
{
@@ -1329,9 +1329,21 @@
{
zend_op *opline = EX(opline);
zend_free_op free_op1, free_op2;
- zval **variable_ptr_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
+ zval **variable_ptr_ptr;
zval **value_ptr_ptr = GET_OP2_ZVAL_PTR_PTR(BP_VAR_W);
+ if (OP2_TYPE == IS_VAR &&
+ !(*value_ptr_ptr)->is_ref &&
+ opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !EX_T(opline->op2.u.var).var.fcall_returned_reference) {
+ zend_error(E_STRICT, "Only variables should be assigned by
reference");
+ if (free_op2.var == NULL) {
+ PZVAL_LOCK(*value_ptr_ptr); /* undo the effect of
get_zval_ptr_ptr() */
+ }
+ ZEND_VM_DISPATCH_TO_HANDLER(ZEND_ASSIGN);
+ }
+
+ 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 (!RETURN_VALUE_UNUSED(&opline->result)) {
http://cvs.php.net/diff.php/ZendEngine2/zend_vm_execute.h?r1=1.27&r2=1.28&ty=u
Index: ZendEngine2/zend_vm_execute.h
diff -u ZendEngine2/zend_vm_execute.h:1.27 ZendEngine2/zend_vm_execute.h:1.28
--- ZendEngine2/zend_vm_execute.h:1.27 Wed May 4 07:17:28 2005
+++ ZendEngine2/zend_vm_execute.h Thu May 5 13:37:24 2005
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: zend_vm_execute.h,v 1.27 2005/05/04 11:17:28 dmitry Exp $ */
+/* $Id: zend_vm_execute.h,v 1.28 2005/05/05 17:37:24 dmitry Exp $ */
#define ZEND_VM_CONTINUE() return 0
@@ -11505,9 +11505,21 @@
{
zend_op *opline = EX(opline);
zend_free_op free_op1, free_op2;
- zval **variable_ptr_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts),
&free_op1 TSRMLS_CC);
+ zval **variable_ptr_ptr;
zval **value_ptr_ptr = _get_zval_ptr_ptr_var(&opline->op2, EX(Ts),
&free_op2 TSRMLS_CC);
+ if (IS_VAR == IS_VAR &&
+ !(*value_ptr_ptr)->is_ref &&
+ opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !EX_T(opline->op2.u.var).var.fcall_returned_reference) {
+ zend_error(E_STRICT, "Only variables should be assigned by
reference");
+ if (free_op2.var == NULL) {
+ PZVAL_LOCK(*value_ptr_ptr); /* undo the effect of
get_zval_ptr_ptr() */
+ }
+ return
ZEND_ASSIGN_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ }
+
+ 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 (!RETURN_VALUE_UNUSED(&opline->result)) {
@@ -13267,9 +13279,21 @@
{
zend_op *opline = EX(opline);
zend_free_op free_op1, free_op2;
- zval **variable_ptr_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts),
&free_op1 TSRMLS_CC);
+ zval **variable_ptr_ptr;
zval **value_ptr_ptr = _get_zval_ptr_ptr_cv(&opline->op2, EX(Ts),
&free_op2, BP_VAR_W TSRMLS_CC);
+ if (IS_CV == IS_VAR &&
+ !(*value_ptr_ptr)->is_ref &&
+ opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !EX_T(opline->op2.u.var).var.fcall_returned_reference) {
+ zend_error(E_STRICT, "Only variables should be assigned by
reference");
+ if (free_op2.var == NULL) {
+ PZVAL_LOCK(*value_ptr_ptr); /* undo the effect of
get_zval_ptr_ptr() */
+ }
+ return
ZEND_ASSIGN_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ }
+
+ 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 (!RETURN_VALUE_UNUSED(&opline->result)) {
@@ -22945,9 +22969,21 @@
{
zend_op *opline = EX(opline);
zend_free_op free_op1, free_op2;
- zval **variable_ptr_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts),
&free_op1, BP_VAR_W TSRMLS_CC);
+ zval **variable_ptr_ptr;
zval **value_ptr_ptr = _get_zval_ptr_ptr_var(&opline->op2, EX(Ts),
&free_op2 TSRMLS_CC);
+ if (IS_VAR == IS_VAR &&
+ !(*value_ptr_ptr)->is_ref &&
+ opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !EX_T(opline->op2.u.var).var.fcall_returned_reference) {
+ zend_error(E_STRICT, "Only variables should be assigned by
reference");
+ if (free_op2.var == NULL) {
+ PZVAL_LOCK(*value_ptr_ptr); /* undo the effect of
get_zval_ptr_ptr() */
+ }
+ return
ZEND_ASSIGN_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ }
+
+ variable_ptr_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts),
&free_op1, BP_VAR_W TSRMLS_CC);
zend_assign_to_variable_reference(variable_ptr_ptr, value_ptr_ptr
TSRMLS_CC);
if (!RETURN_VALUE_UNUSED(&opline->result)) {
@@ -24707,9 +24743,21 @@
{
zend_op *opline = EX(opline);
zend_free_op free_op1, free_op2;
- zval **variable_ptr_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts),
&free_op1, BP_VAR_W TSRMLS_CC);
+ zval **variable_ptr_ptr;
zval **value_ptr_ptr = _get_zval_ptr_ptr_cv(&opline->op2, EX(Ts),
&free_op2, BP_VAR_W TSRMLS_CC);
+ if (IS_CV == IS_VAR &&
+ !(*value_ptr_ptr)->is_ref &&
+ opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !EX_T(opline->op2.u.var).var.fcall_returned_reference) {
+ zend_error(E_STRICT, "Only variables should be assigned by
reference");
+ if (free_op2.var == NULL) {
+ PZVAL_LOCK(*value_ptr_ptr); /* undo the effect of
get_zval_ptr_ptr() */
+ }
+ return
ZEND_ASSIGN_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ }
+
+ variable_ptr_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts),
&free_op1, BP_VAR_W TSRMLS_CC);
zend_assign_to_variable_reference(variable_ptr_ptr, value_ptr_ptr
TSRMLS_CC);
if (!RETURN_VALUE_UNUSED(&opline->result)) {
@@ -30271,9 +30319,21 @@
{
zend_op *opline = EX(opline);
zend_free_op free_op1, free_op2;
- zval **variable_ptr_ptr = get_zval_ptr_ptr(&opline->op1, EX(Ts),
&free_op1, BP_VAR_W);
+ zval **variable_ptr_ptr;
zval **value_ptr_ptr = get_zval_ptr_ptr(&opline->op2, EX(Ts),
&free_op2, BP_VAR_W);
+ if (opline->op2.op_type == IS_VAR &&
+ !(*value_ptr_ptr)->is_ref &&
+ opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !EX_T(opline->op2.u.var).var.fcall_returned_reference) {
+ zend_error(E_STRICT, "Only variables should be assigned by
reference");
+ if (free_op2.var == NULL) {
+ PZVAL_LOCK(*value_ptr_ptr); /* undo the effect of
get_zval_ptr_ptr() */
+ }
+ return ZEND_ASSIGN_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ }
+
+ variable_ptr_ptr = get_zval_ptr_ptr(&opline->op1, EX(Ts), &free_op1,
BP_VAR_W);
zend_assign_to_variable_reference(variable_ptr_ptr, value_ptr_ptr
TSRMLS_CC);
if (!RETURN_VALUE_UNUSED(&opline->result)) {
http://cvs.php.net/diff.php/ZendEngine2/zend_vm_opcodes.h?r1=1.14&r2=1.15&ty=u
Index: ZendEngine2/zend_vm_opcodes.h
diff -u ZendEngine2/zend_vm_opcodes.h:1.14 ZendEngine2/zend_vm_opcodes.h:1.15
--- ZendEngine2/zend_vm_opcodes.h:1.14 Wed May 4 07:17:30 2005
+++ ZendEngine2/zend_vm_opcodes.h Thu May 5 13:37:25 2005
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: zend_vm_opcodes.h,v 1.14 2005/05/04 11:17:30 dmitry Exp $ */
+/* $Id: zend_vm_opcodes.h,v 1.15 2005/05/05 17:37:25 dmitry Exp $ */
#define ZEND_NOP 0
#define ZEND_ADD 1
http://cvs.php.net/diff.php/ZendEngine2/tests/bug31525.phpt?r1=1.1&r2=1.2&ty=u
Index: ZendEngine2/tests/bug31525.phpt
diff -u /dev/null ZendEngine2/tests/bug31525.phpt:1.2
--- /dev/null Thu May 5 13:37:25 2005
+++ ZendEngine2/tests/bug31525.phpt Thu May 5 13:37:25 2005
@@ -0,0 +1,22 @@
+--TEST--
+Bug #31525 (object reference being dropped. $this getting lost)
+--INI--
+error_reporting=4095
+--FILE--
+<?php
+class Foo {
+ function getThis() {
+ return $this;
+ }
+ function destroyThis() {
+ $baz =& $this->getThis();
+ }
+}
+$bar = new Foo();
+$bar->destroyThis();
+var_dump($bar);
+?>
+--EXPECTF--
+Strict Standards: Only variables should be assigned by reference in
%sbug31525.php on line 7
+object(Foo)#1 (0) {
+}
http://cvs.php.net/diff.php/php-src/tests/lang/bug20175.phpt?r1=1.7&r2=1.8&ty=u
Index: php-src/tests/lang/bug20175.phpt
diff -u php-src/tests/lang/bug20175.phpt:1.7
php-src/tests/lang/bug20175.phpt:1.8
--- php-src/tests/lang/bug20175.phpt:1.7 Mon Feb 3 11:33:13 2003
+++ php-src/tests/lang/bug20175.phpt Thu May 5 13:37:25 2005
@@ -2,6 +2,8 @@
Bug #20175 (Static vars can't store ref to new instance)
--SKIPIF--
<?php if (version_compare(zend_version(),'2.0.0-dev','<')) die('skip ZE1 does
not have static class members'); ?>
+--INI--
+error_reporting=4095
--FILE--
<?php
print zend_version()."\n";
@@ -145,10 +147,11 @@
foo:1
bar_static()
bar_global()
+
+Strict Standards: Only variables should be assigned by reference in
%sbug20175.php on line 47
bar:1
bar_static()
-bar_global()
-bar:2
+bar:1
wow_static()
wow_global()
wow:1
http://cvs.php.net/diff.php/php-src/tests/lang/bug21600.phpt?r1=1.3&r2=1.4&ty=u
Index: php-src/tests/lang/bug21600.phpt
diff -u php-src/tests/lang/bug21600.phpt:1.3
php-src/tests/lang/bug21600.phpt:1.4
--- php-src/tests/lang/bug21600.phpt:1.3 Mon Feb 24 11:50:35 2003
+++ php-src/tests/lang/bug21600.phpt Thu May 5 13:37:25 2005
@@ -1,5 +1,7 @@
--TEST--
Bug #21600 (assign by reference function call changes variable contents)
+--INI--
+error_reporting=4095
--FILE--
<?php
$tmp = array();
@@ -23,11 +25,14 @@
return $text;
}
?>
---EXPECT--
+--EXPECTF--
+Strict Standards: Only variables should be assigned by reference in
%sbug21600.php on line 4
array(1) {
["foo"]=>
- &string(4) "test"
+ string(4) "test"
}
+
+Strict Standards: Only variables should be assigned by reference in
%sbug21600.php on line 11
array(1) {
["foo"]=>
string(4) "test"
--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php