summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2020-06-09 15:51:05 +0200
committerNikita Popov <nikita.ppv@gmail.com>2020-06-09 15:51:05 +0200
commit2447fd9f84a484fbce8cd79e8e85b1fdf6ad7431 (patch)
treef943b979249e2cbe0c8677ae0d3d72aa3471798f
parentee4683cf28bd2c28bd73c6bc546279ebe1054000 (diff)
downloadphp-git-2447fd9f84a484fbce8cd79e8e85b1fdf6ad7431.tar.gz
Fixed bug #79683
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.
-rw-r--r--NEWS1
-rw-r--r--Zend/zend_object_handlers.c3
-rw-r--r--ext/reflection/tests/bug79683.phpt35
3 files changed, 39 insertions, 0 deletions
diff --git a/NEWS b/NEWS
index d647eabb1a..472577937b 100644
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,7 @@ PHP NEWS
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)
diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c
index 610b15c6aa..5be63b4cd7 100644
--- a/Zend/zend_object_handlers.c
+++ b/Zend/zend_object_handlers.c
@@ -1796,7 +1796,10 @@ ZEND_API int zend_std_cast_object_tostring(zval *readobj, zval *writeobj, int ty
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;
diff --git a/ext/reflection/tests/bug79683.phpt b/ext/reflection/tests/bug79683.phpt
new file mode 100644
index 0000000000..766571918a
--- /dev/null
+++ b/ext/reflection/tests/bug79683.phpt
@@ -0,0 +1,35 @@
+--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"
+}