summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS2
-rwxr-xr-xZend/tests/bug31525.phpt22
-rw-r--r--Zend/zend_compile.c18
-rw-r--r--Zend/zend_execute.c9
-rw-r--r--tests/lang/bug20175.phpt7
-rw-r--r--tests/lang/bug21600.phpt9
6 files changed, 56 insertions, 11 deletions
diff --git a/NEWS b/NEWS
index 80752ea67c..75958eecb7 100644
--- a/NEWS
+++ b/NEWS
@@ -68,6 +68,8 @@ PHP NEWS
- Fixed bug #31636 (another crash when echoing a COM object). (Wez)
- Fixed bug #31583 (php_std_date() uses short day names in non-y2k_compliance
mode). (mike at php dot net)
+- Fixed bug #31525 (object reference being dropped. $this getting lost).
+ (Stas, Dmitry)
- Fixed bug #31502 (Wrong deserialization from session when using WDDX
serializer). (Dmitry)
- Fixed bug #31363 (broken non-blocking flock()). ian at snork dot net
diff --git a/Zend/tests/bug31525.phpt b/Zend/tests/bug31525.phpt
new file mode 100755
index 0000000000..b1a01b61ef
--- /dev/null
+++ b/Zend/tests/bug31525.phpt
@@ -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) {
+}
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index a9bcaf5f55..b1805298f7 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -483,6 +483,12 @@ void zend_do_assign(znode *result, znode *variable, znode *value TSRMLS_DC)
}
}
+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)
{
@@ -494,6 +500,11 @@ void zend_do_assign_ref(znode *result, znode *lvar, znode *rvar TSRMLS_DC)
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;
@@ -717,13 +728,6 @@ void zend_check_writable_variable(znode *variable)
}
}
-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;
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index 86413efc13..e6e14150f8 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -2281,6 +2281,15 @@ int zend_assign_ref_handler(ZEND_OPCODE_HANDLER_ARGS)
{
zval **value_ptr_ptr = get_zval_ptr_ptr(&opline->op2, EX(Ts), 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");
+ PZVAL_LOCK(*value_ptr_ptr); /* undo the effect of get_zval_ptr_ptr() */
+ return zend_assign_handler(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ }
+
zend_assign_to_variable_reference(&opline->result, get_zval_ptr_ptr(&opline->op1, EX(Ts), BP_VAR_W), value_ptr_ptr, EX(Ts) TSRMLS_CC);
NEXT_OPCODE();
diff --git a/tests/lang/bug20175.phpt b/tests/lang/bug20175.phpt
index 55ff7d82b8..d2248e6f0e 100644
--- a/tests/lang/bug20175.phpt
+++ b/tests/lang/bug20175.phpt
@@ -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_static()
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
diff --git a/tests/lang/bug21600.phpt b/tests/lang/bug21600.phpt
index c3f832b9ea..6ecf69a11f 100644
--- a/tests/lang/bug21600.phpt
+++ b/tests/lang/bug21600.phpt
@@ -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 @@ function fubar($text){
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"