summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS2
-rwxr-xr-xZend/tests/bug32660.phpt36
-rw-r--r--Zend/zend_vm_def.h3
-rw-r--r--Zend/zend_vm_execute.h14
4 files changed, 54 insertions, 1 deletions
diff --git a/NEWS b/NEWS
index 8b80643167..724ca6fa8a 100644
--- 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
index 0000000000..f173b287e1
--- /dev/null
+++ b/Zend/tests/bug32660.phpt
@@ -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
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index e5673550b0..d484ee853c 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -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);
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index d0779b978c..46ee7fa7c1 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -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);