diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2020-06-09 15:51:05 +0200 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2020-06-09 15:51:05 +0200 |
commit | 2447fd9f84a484fbce8cd79e8e85b1fdf6ad7431 (patch) | |
tree | f943b979249e2cbe0c8677ae0d3d72aa3471798f | |
parent | ee4683cf28bd2c28bd73c6bc546279ebe1054000 (diff) | |
download | php-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-- | NEWS | 1 | ||||
-rw-r--r-- | Zend/zend_object_handlers.c | 3 | ||||
-rw-r--r-- | ext/reflection/tests/bug79683.phpt | 35 |
3 files changed, 39 insertions, 0 deletions
@@ -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" +} |