Skip to content

Commit 94f5037

Browse files
committed
Merge branch 'PHP-8.4'
* PHP-8.4: Fix GH-18567: Preloading with internal class alias triggers assertion failure
2 parents a3fa5ae + 43915b3 commit 94f5037

File tree

3 files changed

+59
-5
lines changed

3 files changed

+59
-5
lines changed

ext/opcache/ZendAccelerator.c

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3624,7 +3624,7 @@ static void preload_shutdown(void)
36243624
if (EG(class_table)) {
36253625
ZEND_HASH_MAP_REVERSE_FOREACH_VAL(EG(class_table), zv) {
36263626
zend_class_entry *ce = Z_PTR_P(zv);
3627-
if (ce->type == ZEND_INTERNAL_CLASS) {
3627+
if (ce->type == ZEND_INTERNAL_CLASS && Z_TYPE_P(zv) != IS_ALIAS_PTR) {
36283628
break;
36293629
}
36303630
} ZEND_HASH_MAP_FOREACH_END_DEL();
@@ -3712,7 +3712,15 @@ static void preload_move_user_classes(HashTable *src, HashTable *dst)
37123712
zend_hash_extend(dst, dst->nNumUsed + src->nNumUsed, 0);
37133713
ZEND_HASH_MAP_FOREACH_BUCKET_FROM(src, p, EG(persistent_classes_count)) {
37143714
zend_class_entry *ce = Z_PTR(p->val);
3715-
ZEND_ASSERT(ce->type == ZEND_USER_CLASS);
3715+
3716+
/* Possible with internal class aliases */
3717+
if (ce->type == ZEND_INTERNAL_CLASS) {
3718+
ZEND_ASSERT(Z_TYPE(p->val) == IS_ALIAS_PTR);
3719+
_zend_hash_append(dst, p->key, &p->val);
3720+
zend_hash_del_bucket(src, p);
3721+
continue;
3722+
}
3723+
37163724
if (ce->info.user.filename != filename) {
37173725
filename = ce->info.user.filename;
37183726
if (filename) {
@@ -4015,7 +4023,12 @@ static void preload_link(void)
40154023

40164024
ZEND_HASH_MAP_FOREACH_STR_KEY_VAL_FROM(EG(class_table), key, zv, EG(persistent_classes_count)) {
40174025
ce = Z_PTR_P(zv);
4018-
ZEND_ASSERT(ce->type != ZEND_INTERNAL_CLASS);
4026+
4027+
/* Possible with internal class aliases */
4028+
if (ce->type == ZEND_INTERNAL_CLASS) {
4029+
ZEND_ASSERT(Z_TYPE_P(zv) == IS_ALIAS_PTR);
4030+
continue;
4031+
}
40194032

40204033
if (!(ce->ce_flags & (ZEND_ACC_TOP_LEVEL|ZEND_ACC_ANON_CLASS))
40214034
|| (ce->ce_flags & ZEND_ACC_LINKED)) {
@@ -4101,9 +4114,15 @@ static void preload_link(void)
41014114

41024115
ZEND_HASH_MAP_REVERSE_FOREACH_VAL(EG(class_table), zv) {
41034116
ce = Z_PTR_P(zv);
4117+
4118+
/* Possible with internal class aliases */
41044119
if (ce->type == ZEND_INTERNAL_CLASS) {
4105-
break;
4120+
if (Z_TYPE_P(zv) != IS_ALIAS_PTR) {
4121+
break; /* can stop already */
4122+
}
4123+
continue;
41064124
}
4125+
41074126
if ((ce->ce_flags & ZEND_ACC_LINKED) && !(ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED)) {
41084127
if (!(ce->ce_flags & ZEND_ACC_TRAIT)) { /* don't update traits */
41094128
CG(in_compilation) = true; /* prevent autoloading */
@@ -4120,7 +4139,13 @@ static void preload_link(void)
41204139
ZEND_HASH_MAP_FOREACH_STR_KEY_VAL_FROM(
41214140
EG(class_table), key, zv, EG(persistent_classes_count)) {
41224141
ce = Z_PTR_P(zv);
4123-
ZEND_ASSERT(ce->type != ZEND_INTERNAL_CLASS);
4142+
4143+
/* Possible with internal class aliases */
4144+
if (ce->type == ZEND_INTERNAL_CLASS) {
4145+
ZEND_ASSERT(Z_TYPE_P(zv) == IS_ALIAS_PTR);
4146+
continue;
4147+
}
4148+
41244149
if ((ce->ce_flags & (ZEND_ACC_TOP_LEVEL|ZEND_ACC_ANON_CLASS))
41254150
&& !(ce->ce_flags & ZEND_ACC_LINKED)) {
41264151
zend_string *lcname = zend_string_tolower(ce->name);

ext/opcache/tests/gh18567.phpt

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
--TEST--
2+
GH-18567 (Preloading with internal class alias triggers assertion failure)
3+
--INI--
4+
opcache.enable=1
5+
opcache.enable_cli=1
6+
opcache.preload={PWD}/preload_gh18567.inc
7+
--EXTENSIONS--
8+
opcache
9+
--SKIPIF--
10+
<?php
11+
if (PHP_OS_FAMILY == 'Windows') die('skip Preloading is not supported on Windows');
12+
?>
13+
--FILE--
14+
<?php
15+
abstract class Test implements MyStringable {
16+
}
17+
$rc = new ReflectionClass(Test::class);
18+
var_dump($rc->getInterfaces());
19+
?>
20+
--EXPECT--
21+
array(1) {
22+
["Stringable"]=>
23+
object(ReflectionClass)#2 (1) {
24+
["name"]=>
25+
string(10) "Stringable"
26+
}
27+
}

ext/opcache/tests/preload_gh18567.inc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<?php
2+
class_alias('Stringable', 'MyStringable');

0 commit comments

Comments
 (0)