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

Reply via email to