mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
Fix GH-18567: Preloading with internal class alias triggers assertion failure
The assertion is imprecise now, and the code assumed that from the moment an internal class was encountered that there were only internal classes remaining. This is wrong now, and we still have to continue if we encounter an internal class. We can only skip the remaining iterations if the entry in the hash table is not an alias. Closes GH-18575.
This commit is contained in:
2
NEWS
2
NEWS
@@ -32,6 +32,8 @@ PHP NEWS
|
||||
- Opcache:
|
||||
. Fixed bug GH-18417 (Windows SHM reattachment fails when increasing
|
||||
memory_consumption or jit_buffer_size). (nielsdos)
|
||||
. Fixed bug GH-18567 (Preloading with internal class alias triggers assertion
|
||||
failure). (nielsdos)
|
||||
|
||||
- PDO_OCI:
|
||||
. Fixed bug GH-18494 (PDO OCI segfault in statement GC). (nielsdos)
|
||||
|
||||
@@ -3522,7 +3522,7 @@ static void preload_shutdown(void)
|
||||
if (EG(class_table)) {
|
||||
ZEND_HASH_MAP_REVERSE_FOREACH_VAL(EG(class_table), 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;
|
||||
}
|
||||
} ZEND_HASH_MAP_FOREACH_END_DEL();
|
||||
@@ -3610,7 +3610,15 @@ static void preload_move_user_classes(HashTable *src, HashTable *dst)
|
||||
zend_hash_extend(dst, dst->nNumUsed + src->nNumUsed, 0);
|
||||
ZEND_HASH_MAP_FOREACH_BUCKET_FROM(src, p, EG(persistent_classes_count)) {
|
||||
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) {
|
||||
filename = ce->info.user.filename;
|
||||
if (filename) {
|
||||
@@ -3904,7 +3912,12 @@ static void preload_link(void)
|
||||
|
||||
ZEND_HASH_MAP_FOREACH_STR_KEY_VAL_FROM(EG(class_table), key, zv, EG(persistent_classes_count)) {
|
||||
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))
|
||||
|| (ce->ce_flags & ZEND_ACC_LINKED)) {
|
||||
@@ -3990,9 +4003,15 @@ static void preload_link(void)
|
||||
|
||||
ZEND_HASH_MAP_REVERSE_FOREACH_VAL(EG(class_table), zv) {
|
||||
ce = Z_PTR_P(zv);
|
||||
|
||||
/* Possible with internal class aliases */
|
||||
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_TRAIT)) { /* don't update traits */
|
||||
CG(in_compilation) = true; /* prevent autoloading */
|
||||
@@ -4009,7 +4028,13 @@ static void preload_link(void)
|
||||
ZEND_HASH_MAP_FOREACH_STR_KEY_VAL_FROM(
|
||||
EG(class_table), key, zv, EG(persistent_classes_count)) {
|
||||
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))
|
||||
&& !(ce->ce_flags & ZEND_ACC_LINKED)) {
|
||||
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');
|
||||
Reference in New Issue
Block a user