summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Zend/zend_builtin_functions.c3
-rw-r--r--ext/reflection/tests/ReflectionClass_isSubclassOf_error2.phpt35
2 files changed, 37 insertions, 1 deletions
diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c
index c59b08b583..626cbea6da 100644
--- a/Zend/zend_builtin_functions.c
+++ b/Zend/zend_builtin_functions.c
@@ -1715,7 +1715,8 @@ ZEND_FUNCTION(get_declared_classes)
ZEND_HASH_FOREACH_STR_KEY_PTR(EG(class_table), key, ce) {
if (key
&& ZSTR_VAL(key)[0] != 0
- && !(ce->ce_flags & (ZEND_ACC_INTERFACE | ZEND_ACC_TRAIT))) {
+ && !(ce->ce_flags & (ZEND_ACC_INTERFACE | ZEND_ACC_TRAIT))
+ && (ce->ce_flags & ZEND_ACC_LINKED)) {
copy_class_or_interface_name(return_value, key, ce);
}
} ZEND_HASH_FOREACH_END();
diff --git a/ext/reflection/tests/ReflectionClass_isSubclassOf_error2.phpt b/ext/reflection/tests/ReflectionClass_isSubclassOf_error2.phpt
new file mode 100644
index 0000000000..8671c2500b
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_isSubclassOf_error2.phpt
@@ -0,0 +1,35 @@
+--TEST--
+ReflectionClass::isSubclassOf() - fixed crash for unbound anonymous class
+--FILE--
+<?php
+class X {
+ public static function main() {
+ return new class() extends Base {};
+ }
+}
+class Base {}
+$check = function () {
+ $base = Base::class;
+ foreach (get_declared_classes() as $class) {
+ if (strpos($class, 'class@anonymous') === false) {
+ continue;
+ }
+ echo "Checking for $class\n";
+ flush();
+ $rc = new ReflectionClass($class);
+ var_export($rc->isSubclassOf($base));
+ echo "\n";
+ }
+};
+// Should not show up in get_declared_classes until the anonymous class is bound.
+$check();
+echo "After first check\n";
+X::main();
+$check();
+echo "Done\n";
+?>
+--EXPECTF--
+After first check
+Checking for class@%s
+true
+Done