mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
Merge branch 'PHP-8.4'
* PHP-8.4: Fix GH-18567: Preloading with internal class alias triggers assertion failure
This commit is contained in:
commit
94f5037ac3
3 changed files with 59 additions and 5 deletions
|
@ -3624,7 +3624,7 @@ static void preload_shutdown(void)
|
||||||
if (EG(class_table)) {
|
if (EG(class_table)) {
|
||||||
ZEND_HASH_MAP_REVERSE_FOREACH_VAL(EG(class_table), zv) {
|
ZEND_HASH_MAP_REVERSE_FOREACH_VAL(EG(class_table), zv) {
|
||||||
zend_class_entry *ce = Z_PTR_P(zv);
|
zend_class_entry *ce = Z_PTR_P(zv);
|
||||||
if (ce->type == ZEND_INTERNAL_CLASS) {
|
if (ce->type == ZEND_INTERNAL_CLASS && Z_TYPE_P(zv) != IS_ALIAS_PTR) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} ZEND_HASH_MAP_FOREACH_END_DEL();
|
} ZEND_HASH_MAP_FOREACH_END_DEL();
|
||||||
|
@ -3712,7 +3712,15 @@ static void preload_move_user_classes(HashTable *src, HashTable *dst)
|
||||||
zend_hash_extend(dst, dst->nNumUsed + src->nNumUsed, 0);
|
zend_hash_extend(dst, dst->nNumUsed + src->nNumUsed, 0);
|
||||||
ZEND_HASH_MAP_FOREACH_BUCKET_FROM(src, p, EG(persistent_classes_count)) {
|
ZEND_HASH_MAP_FOREACH_BUCKET_FROM(src, p, EG(persistent_classes_count)) {
|
||||||
zend_class_entry *ce = Z_PTR(p->val);
|
zend_class_entry *ce = Z_PTR(p->val);
|
||||||
ZEND_ASSERT(ce->type == ZEND_USER_CLASS);
|
|
||||||
|
/* Possible with internal class aliases */
|
||||||
|
if (ce->type == ZEND_INTERNAL_CLASS) {
|
||||||
|
ZEND_ASSERT(Z_TYPE(p->val) == IS_ALIAS_PTR);
|
||||||
|
_zend_hash_append(dst, p->key, &p->val);
|
||||||
|
zend_hash_del_bucket(src, p);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (ce->info.user.filename != filename) {
|
if (ce->info.user.filename != filename) {
|
||||||
filename = ce->info.user.filename;
|
filename = ce->info.user.filename;
|
||||||
if (filename) {
|
if (filename) {
|
||||||
|
@ -4015,7 +4023,12 @@ static void preload_link(void)
|
||||||
|
|
||||||
ZEND_HASH_MAP_FOREACH_STR_KEY_VAL_FROM(EG(class_table), key, zv, EG(persistent_classes_count)) {
|
ZEND_HASH_MAP_FOREACH_STR_KEY_VAL_FROM(EG(class_table), key, zv, EG(persistent_classes_count)) {
|
||||||
ce = Z_PTR_P(zv);
|
ce = Z_PTR_P(zv);
|
||||||
ZEND_ASSERT(ce->type != ZEND_INTERNAL_CLASS);
|
|
||||||
|
/* Possible with internal class aliases */
|
||||||
|
if (ce->type == ZEND_INTERNAL_CLASS) {
|
||||||
|
ZEND_ASSERT(Z_TYPE_P(zv) == IS_ALIAS_PTR);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(ce->ce_flags & (ZEND_ACC_TOP_LEVEL|ZEND_ACC_ANON_CLASS))
|
if (!(ce->ce_flags & (ZEND_ACC_TOP_LEVEL|ZEND_ACC_ANON_CLASS))
|
||||||
|| (ce->ce_flags & ZEND_ACC_LINKED)) {
|
|| (ce->ce_flags & ZEND_ACC_LINKED)) {
|
||||||
|
@ -4101,9 +4114,15 @@ static void preload_link(void)
|
||||||
|
|
||||||
ZEND_HASH_MAP_REVERSE_FOREACH_VAL(EG(class_table), zv) {
|
ZEND_HASH_MAP_REVERSE_FOREACH_VAL(EG(class_table), zv) {
|
||||||
ce = Z_PTR_P(zv);
|
ce = Z_PTR_P(zv);
|
||||||
|
|
||||||
|
/* Possible with internal class aliases */
|
||||||
if (ce->type == ZEND_INTERNAL_CLASS) {
|
if (ce->type == ZEND_INTERNAL_CLASS) {
|
||||||
break;
|
if (Z_TYPE_P(zv) != IS_ALIAS_PTR) {
|
||||||
|
break; /* can stop already */
|
||||||
|
}
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ce->ce_flags & ZEND_ACC_LINKED) && !(ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED)) {
|
if ((ce->ce_flags & ZEND_ACC_LINKED) && !(ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED)) {
|
||||||
if (!(ce->ce_flags & ZEND_ACC_TRAIT)) { /* don't update traits */
|
if (!(ce->ce_flags & ZEND_ACC_TRAIT)) { /* don't update traits */
|
||||||
CG(in_compilation) = true; /* prevent autoloading */
|
CG(in_compilation) = true; /* prevent autoloading */
|
||||||
|
@ -4120,7 +4139,13 @@ static void preload_link(void)
|
||||||
ZEND_HASH_MAP_FOREACH_STR_KEY_VAL_FROM(
|
ZEND_HASH_MAP_FOREACH_STR_KEY_VAL_FROM(
|
||||||
EG(class_table), key, zv, EG(persistent_classes_count)) {
|
EG(class_table), key, zv, EG(persistent_classes_count)) {
|
||||||
ce = Z_PTR_P(zv);
|
ce = Z_PTR_P(zv);
|
||||||
ZEND_ASSERT(ce->type != ZEND_INTERNAL_CLASS);
|
|
||||||
|
/* Possible with internal class aliases */
|
||||||
|
if (ce->type == ZEND_INTERNAL_CLASS) {
|
||||||
|
ZEND_ASSERT(Z_TYPE_P(zv) == IS_ALIAS_PTR);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if ((ce->ce_flags & (ZEND_ACC_TOP_LEVEL|ZEND_ACC_ANON_CLASS))
|
if ((ce->ce_flags & (ZEND_ACC_TOP_LEVEL|ZEND_ACC_ANON_CLASS))
|
||||||
&& !(ce->ce_flags & ZEND_ACC_LINKED)) {
|
&& !(ce->ce_flags & ZEND_ACC_LINKED)) {
|
||||||
zend_string *lcname = zend_string_tolower(ce->name);
|
zend_string *lcname = zend_string_tolower(ce->name);
|
||||||
|
|
27
ext/opcache/tests/gh18567.phpt
Normal file
27
ext/opcache/tests/gh18567.phpt
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
--TEST--
|
||||||
|
GH-18567 (Preloading with internal class alias triggers assertion failure)
|
||||||
|
--INI--
|
||||||
|
opcache.enable=1
|
||||||
|
opcache.enable_cli=1
|
||||||
|
opcache.preload={PWD}/preload_gh18567.inc
|
||||||
|
--EXTENSIONS--
|
||||||
|
opcache
|
||||||
|
--SKIPIF--
|
||||||
|
<?php
|
||||||
|
if (PHP_OS_FAMILY == 'Windows') die('skip Preloading is not supported on Windows');
|
||||||
|
?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
abstract class Test implements MyStringable {
|
||||||
|
}
|
||||||
|
$rc = new ReflectionClass(Test::class);
|
||||||
|
var_dump($rc->getInterfaces());
|
||||||
|
?>
|
||||||
|
--EXPECT--
|
||||||
|
array(1) {
|
||||||
|
["Stringable"]=>
|
||||||
|
object(ReflectionClass)#2 (1) {
|
||||||
|
["name"]=>
|
||||||
|
string(10) "Stringable"
|
||||||
|
}
|
||||||
|
}
|
2
ext/opcache/tests/preload_gh18567.inc
Normal file
2
ext/opcache/tests/preload_gh18567.inc
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
<?php
|
||||||
|
class_alias('Stringable', 'MyStringable');
|
Loading…
Add table
Add a link
Reference in a new issue