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