]> granicus.if.org Git - php/commitdiff
Fixed bug #32660 (Assignment by reference causes crash when field access is overloade...
authorDmitry Stogov <dmitry@php.net>
Thu, 23 Jun 2005 11:04:35 +0000 (11:04 +0000)
committerDmitry Stogov <dmitry@php.net>
Thu, 23 Jun 2005 11:04:35 +0000 (11:04 +0000)
NEWS
Zend/tests/bug32660.phpt [new file with mode: 0755]
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

diff --git a/NEWS b/NEWS
index 8b80643167e153bc7001e4244078ec8f7760079d..724ca6fa8a3a430edca5c0f334df8297d04dfd01 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,8 @@
 PHP                                                                        NEWS
 |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 ?? ??? 2005, PHP 5.1 Beta 3
+- Fixed bug #32660 (Assignment by reference causes crash when field access is
+  overloaded (__get)). (Dmitry)
 - Fixed bug #30828 (debug_backtrace() reports incorrect class in overridden
   methods). (Dmitry)
 - Fixed bug #27268 (Bad references accentuated by clone). (Dmitry)
diff --git a/Zend/tests/bug32660.phpt b/Zend/tests/bug32660.phpt
new file mode 100755 (executable)
index 0000000..f173b28
--- /dev/null
@@ -0,0 +1,36 @@
+--TEST--
+Bug #32660 Assignment by reference causes crash when field access is overloaded (__get) 
+--FILE--
+<?php
+class A
+{
+       public $q;
+
+       function __construct()
+       {
+               $this->q = 3;//array();
+       }
+
+       function __get($name)
+       {
+               return $this->q;
+       }
+}
+
+$a = new A;
+
+$b = "short";
+$c =& $a->whatever;
+$c = "long";
+print_r($a);
+$a->whatever =& $b;
+$b = "much longer";
+print_r($a);
+?>
+--EXPECTF--
+A Object
+(
+    [q] => long
+)
+
+Fatal error: Cannot assign by reference to overloaded object in %sbug32660.php on line 23
index e5673550b07ebd4f796e844e82069aed024d7048..d484ee853c291b840c563531e0847cae17d67408 100644 (file)
@@ -1382,6 +1382,9 @@ ZEND_VM_HANDLER(39, ZEND_ASSIGN_REF, VAR|CV, VAR|CV)
                zend_error(E_STRICT, "Only variables should be assigned by reference");
                ZEND_VM_DISPATCH_TO_HANDLER(ZEND_ASSIGN);
        }
+       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");
+       }
 
        variable_ptr_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
        zend_assign_to_variable_reference(variable_ptr_ptr, value_ptr_ptr TSRMLS_CC);
index d0779b978cd84780713ef54a310d651f9c69c0cd..46ee7fa7c1cf108e0fad7074291a765e448f2bc7 100644 (file)
@@ -117,7 +117,7 @@ static int ZEND_INIT_STRING_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        ZEND_VM_NEXT_OPCODE();
 }
 
- int zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
+static int zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
 {
        zend_op *opline = EX(opline);
        zval **original_return_value;
@@ -11599,6 +11599,9 @@ static int ZEND_ASSIGN_REF_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                zend_error(E_STRICT, "Only variables should be assigned by reference");
                return ZEND_ASSIGN_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
        }
+       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");
+       }
 
        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);
@@ -13426,6 +13429,9 @@ static int ZEND_ASSIGN_REF_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                zend_error(E_STRICT, "Only variables should be assigned by reference");
                return ZEND_ASSIGN_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
        }
+       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");
+       }
 
        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);
@@ -23447,6 +23453,9 @@ static int ZEND_ASSIGN_REF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                zend_error(E_STRICT, "Only variables should be assigned by reference");
                return ZEND_ASSIGN_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
        }
+       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");
+       }
 
        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);
@@ -25264,6 +25273,9 @@ static int ZEND_ASSIGN_REF_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                zend_error(E_STRICT, "Only variables should be assigned by reference");
                return ZEND_ASSIGN_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
        }
+       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");
+       }
 
        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);