Reset fake_scope during __toString() call.
I'll check if we can solve this more globally in master, by
resetting fake_scope in zend_call_function.
Nikita)
. Fixed bug #79657 ("yield from" hangs when invalid value encountered).
(Nikita)
+ . Fixed bug #79683 (Fake reflection scope affects __toString()). (Nikita)
- Filter:
. Fixed bug #73527 (Invalid memory access in php_filter_strip). (cmb)
case IS_STRING:
ce = Z_OBJCE_P(readobj);
if (ce->__tostring) {
+ zend_class_entry *fake_scope = EG(fake_scope);
+ EG(fake_scope) = NULL;
zend_call_method_with_0_params(readobj, ce, &ce->__tostring, "__tostring", &retval);
+ EG(fake_scope) = fake_scope;
if (EXPECTED(Z_TYPE(retval) == IS_STRING)) {
ZVAL_COPY_VALUE(writeobj, &retval);
return SUCCESS;
--- /dev/null
+--TEST--
+Bug #79683: Fake reflection scope affects __toString()
+--FILE--
+<?php
+
+class A
+{
+ private string $prop1 = '123';
+
+ public function __toString()
+ {
+ return $this->prop1;
+ }
+}
+
+class B
+{
+ private string $prop2;
+}
+
+$b = new B();
+
+$reflector = new ReflectionClass($b);
+$property = $reflector->getProperty('prop2');
+$property->setAccessible(true);
+$property->setValue($b, new A());
+
+var_dump($b);
+
+?>
+--EXPECT--
+object(B)#1 (1) {
+ ["prop2":"B":private]=>
+ string(3) "123"
+}