From: Dmitry Stogov Date: Thu, 23 Jun 2005 11:04:35 +0000 (+0000) Subject: Fixed bug #32660 (Assignment by reference causes crash when field access is overloade... X-Git-Tag: php-5.1.0b3~336 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=cfe01e1b0601850b4d3313d7d327f53b513f14e5;p=php Fixed bug #32660 (Assignment by reference causes crash when field access is overloaded (__get)) --- 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-- +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);