summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2019-11-25 14:05:43 +0300
committerDmitry Stogov <dmitry@zend.com>2019-11-25 14:05:43 +0300
commitbb30fe9e2b86a46a167c88daaae0c650cb01afa2 (patch)
tree3e4045f70481b96dcde8d584daf43e6322ee8067
parente1da72bdf18aa3d413c5324bccfd8dc521c217e3 (diff)
downloadphp-git-bb30fe9e2b86a46a167c88daaae0c650cb01afa2.tar.gz
Fixed bug #78868 (Calling __autoload() with incorrect EG(fake_scope) value)
-rw-r--r--NEWS2
-rw-r--r--Zend/tests/bug78868.phpt33
-rw-r--r--Zend/zend_API.c6
3 files changed, 41 insertions, 0 deletions
diff --git a/NEWS b/NEWS
index 53ad0a7a4d..2961969c61 100644
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,8 @@ PHP NEWS
- Core:
. Fixed bug #78787 (Segfault with trait overriding inherited private shadow
property). (Nikita)
+ . Fixed bug #78868 (Calling __autoload() with incorrect EG(fake_scope) value).
+ (Antony Dovgal, Dmitry)
- GD:
. Fixed bug #78849 (GD build broken with -D SIGNED_COMPARE_SLOW). (cmb)
diff --git a/Zend/tests/bug78868.phpt b/Zend/tests/bug78868.phpt
new file mode 100644
index 0000000000..172af2a930
--- /dev/null
+++ b/Zend/tests/bug78868.phpt
@@ -0,0 +1,33 @@
+--TEST--
+Bug #78868: Calling __autoload() with incorrect EG(fake_scope) value
+--FILE--
+<?php
+class C {
+ private $private = 1;
+
+ function foo() {
+ $this->private++; //fails with EG(fake_scope) != NULL && EG(fake_scope) != "C"
+ }
+}
+
+class A {
+ static $foo = B::foo; //not resolved on include()
+}
+
+function main_autoload($class_name) {
+ $c = new C;
+ $c->foo();
+ //doesn't affect the error
+ eval("class B {const foo = 1;}");
+}
+
+spl_autoload_register('main_autoload', false);
+
+$classA = new ReflectionClass("A");
+$props = $classA->getProperties();
+$props[0]->setValue(2); //causes constant resolving, which runs autoload, all with EG(fake_scope) == "A"
+
+echo "OK\n";
+?>
+--EXPECT--
+OK
diff --git a/Zend/zend_API.c b/Zend/zend_API.c
index 3d94fd5986..bc67c6a1b6 100644
--- a/Zend/zend_API.c
+++ b/Zend/zend_API.c
@@ -4082,6 +4082,12 @@ ZEND_API int zend_update_static_property_ex(zend_class_entry *scope, zend_string
zval *property;
zend_class_entry *old_scope = EG(fake_scope);
+ if (UNEXPECTED(!(scope->ce_flags & ZEND_ACC_CONSTANTS_UPDATED))) {
+ if (UNEXPECTED(zend_update_class_constants(scope)) != SUCCESS) {
+ return FAILURE;
+ }
+ }
+
EG(fake_scope) = scope;
property = zend_std_get_static_property(scope, name, 0);
EG(fake_scope) = old_scope;