diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2019-12-10 11:55:14 +0100 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2019-12-10 13:06:36 +0100 |
commit | baf3a9133bf0bc7069e5191b780c221485b2dda6 (patch) | |
tree | 57fabe030d1454468eb346afc7325784a04b3b71 | |
parent | 3f86adb0efab3a68d87645941dc997d1e6314050 (diff) | |
download | php-git-baf3a9133bf0bc7069e5191b780c221485b2dda6.tar.gz |
Add support for class_alias to preloading
Related to bug #78918.
-rw-r--r-- | ext/opcache/tests/preload_class_alias.inc | 3 | ||||
-rw-r--r-- | ext/opcache/tests/preload_class_alias.phpt | 17 | ||||
-rw-r--r-- | ext/opcache/zend_persist.c | 6 | ||||
-rw-r--r-- | ext/opcache/zend_persist_calc.c | 6 |
4 files changed, 32 insertions, 0 deletions
diff --git a/ext/opcache/tests/preload_class_alias.inc b/ext/opcache/tests/preload_class_alias.inc new file mode 100644 index 0000000000..2aaa5adafc --- /dev/null +++ b/ext/opcache/tests/preload_class_alias.inc @@ -0,0 +1,3 @@ +<?php +class A {} +class_alias(A::class, 'B'); diff --git a/ext/opcache/tests/preload_class_alias.phpt b/ext/opcache/tests/preload_class_alias.phpt new file mode 100644 index 0000000000..aee94426d0 --- /dev/null +++ b/ext/opcache/tests/preload_class_alias.phpt @@ -0,0 +1,17 @@ +--TEST-- +Bug #78918: Class alias during preloading causes assertion failure +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.optimization_level=-1 +opcache.preload={PWD}/preload_class_alias.inc +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +var_dump(class_exists('A')); +var_dump(class_exists('B')); +?> +--EXPECT-- +bool(true) +bool(true) diff --git a/ext/opcache/zend_persist.c b/ext/opcache/zend_persist.c index 1571093419..bcbd2f270f 100644 --- a/ext/opcache/zend_persist.c +++ b/ext/opcache/zend_persist.c @@ -700,6 +700,12 @@ static void zend_persist_class_entry(zval *zv) zend_class_entry *ce = Z_PTR_P(zv); if (ce->type == ZEND_USER_CLASS) { + /* The same zend_class_entry may be reused by class_alias */ + zend_class_entry *new_ce = zend_shared_alloc_get_xlat_entry(ce); + if (new_ce) { + Z_PTR_P(zv) = new_ce; + return; + } if ((ce->ce_flags & ZEND_ACC_LINKED) && (ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED) && (ce->ce_flags & ZEND_ACC_PROPERTY_TYPES_RESOLVED) diff --git a/ext/opcache/zend_persist_calc.c b/ext/opcache/zend_persist_calc.c index cc798b27de..dacc2376e8 100644 --- a/ext/opcache/zend_persist_calc.c +++ b/ext/opcache/zend_persist_calc.c @@ -352,6 +352,12 @@ static void zend_persist_class_entry_calc(zval *zv) Bucket *p; if (ce->type == ZEND_USER_CLASS) { + /* The same zend_class_entry may be reused by class_alias */ + if (zend_shared_alloc_get_xlat_entry(ce)) { + return; + } + zend_shared_alloc_register_xlat_entry(ce, ce); + check_property_type_resolution(ce); ZCG(is_immutable_class) = |