summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2019-12-11 12:21:49 +0300
committerDmitry Stogov <dmitry@zend.com>2019-12-11 12:21:49 +0300
commit3280209c0312df000d558e029aa4e8c63912967a (patch)
tree4d05c4ba30e3d17cd803b08474f472ffe7acaf17
parent20ef51db22c46fd45976eb6d0b780c14022c8873 (diff)
downloadphp-git-3280209c0312df000d558e029aa4e8c63912967a.tar.gz
Addirional fix for bug #78918
-rw-r--r--Zend/zend_API.c7
-rw-r--r--Zend/zend_types.h6
-rw-r--r--ext/opcache/ZendAccelerator.c4
-rw-r--r--ext/opcache/tests/preload_class_alias_2.inc4
-rw-r--r--ext/opcache/tests/preload_class_alias_2.phpt17
-rw-r--r--ext/opcache/zend_persist.c7
6 files changed, 39 insertions, 6 deletions
diff --git a/Zend/zend_API.c b/Zend/zend_API.c
index 3493a241a6..21d2c964e8 100644
--- a/Zend/zend_API.c
+++ b/Zend/zend_API.c
@@ -2762,6 +2762,7 @@ ZEND_API zend_class_entry *zend_register_internal_interface(zend_class_entry *or
ZEND_API int zend_register_class_alias_ex(const char *name, size_t name_len, zend_class_entry *ce, int persistent) /* {{{ */
{
zend_string *lcname;
+ zval zv, *ret;
/* TODO: Move this out of here in 7.4. */
if (persistent && EG(current_module) && EG(current_module)->type == MODULE_TEMPORARY) {
@@ -2779,9 +2780,11 @@ ZEND_API int zend_register_class_alias_ex(const char *name, size_t name_len, zen
zend_assert_valid_class_name(lcname);
lcname = zend_new_interned_string(lcname);
- ce = zend_hash_add_ptr(CG(class_table), lcname, ce);
+
+ ZVAL_ALIAS_PTR(&zv, ce);
+ ret = zend_hash_add(CG(class_table), lcname, &zv);
zend_string_release_ex(lcname, 0);
- if (ce) {
+ if (ret) {
if (!(ce->ce_flags & ZEND_ACC_IMMUTABLE)) {
ce->refcount++;
}
diff --git a/Zend/zend_types.h b/Zend/zend_types.h
index 50634417c6..7b8c079c45 100644
--- a/Zend/zend_types.h
+++ b/Zend/zend_types.h
@@ -427,6 +427,7 @@ struct _zend_ast_ref {
/* internal types */
#define IS_INDIRECT 13
#define IS_PTR 14
+#define IS_ALIAS_PTR 15
#define _IS_ERROR 15
/* fake types used only for type hinting (Z_TYPE(zv) can not use them) */
@@ -964,6 +965,11 @@ static zend_always_inline uint32_t zval_gc_info(uint32_t gc_type_info) {
Z_TYPE_INFO_P(z) = IS_PTR; \
} while (0)
+#define ZVAL_ALIAS_PTR(z, p) do { \
+ Z_PTR_P(z) = (p); \
+ Z_TYPE_INFO_P(z) = IS_ALIAS_PTR; \
+ } while (0)
+
#define ZVAL_ERROR(z) do { \
Z_TYPE_INFO_P(z) = _IS_ERROR; \
} while (0)
diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c
index 055ab1bd25..d320d1c097 100644
--- a/ext/opcache/ZendAccelerator.c
+++ b/ext/opcache/ZendAccelerator.c
@@ -3259,7 +3259,7 @@ static void preload_move_user_classes(HashTable *src, HashTable *dst)
}
}
if (copy) {
- _zend_hash_append_ptr(dst, p->key, ce);
+ _zend_hash_append(dst, p->key, &p->val);
} else {
orig_dtor(&p->val);
}
@@ -4238,7 +4238,7 @@ static void preload_load(void)
Bucket *end = p + ZCSG(preload_script)->script.class_table.nNumUsed;
for (; p != end; p++) {
- _zend_hash_append_ptr_ex(CG(class_table), p->key, Z_PTR(p->val), 1);
+ _zend_hash_append_ex(CG(class_table), p->key, &p->val, 1);
}
}
diff --git a/ext/opcache/tests/preload_class_alias_2.inc b/ext/opcache/tests/preload_class_alias_2.inc
new file mode 100644
index 0000000000..3d0a70d882
--- /dev/null
+++ b/ext/opcache/tests/preload_class_alias_2.inc
@@ -0,0 +1,4 @@
+<?php
+interface I {}
+class B implements I {}
+class_alias('B', 'C');
diff --git a/ext/opcache/tests/preload_class_alias_2.phpt b/ext/opcache/tests/preload_class_alias_2.phpt
new file mode 100644
index 0000000000..6dc2c21a8a
--- /dev/null
+++ b/ext/opcache/tests/preload_class_alias_2.phpt
@@ -0,0 +1,17 @@
+--TEST--
+Bug #78918.2: 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_2.inc
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+var_dump(class_exists('B'));
+var_dump(class_exists('C'));
+?>
+--EXPECT--
+bool(true)
+bool(true)
diff --git a/ext/opcache/zend_persist.c b/ext/opcache/zend_persist.c
index bcbd2f270f..06d103d670 100644
--- a/ext/opcache/zend_persist.c
+++ b/ext/opcache/zend_persist.c
@@ -1037,8 +1037,11 @@ static void zend_accel_persist_class_table(HashTable *class_table)
zend_accel_store_interned_string(p->key);
zend_persist_class_entry(&p->val);
} ZEND_HASH_FOREACH_END();
- ZEND_HASH_FOREACH_PTR(class_table, ce) {
- zend_update_parent_ce(ce);
+ ZEND_HASH_FOREACH_BUCKET(class_table, p) {
+ if (EXPECTED(Z_TYPE(p->val) != IS_ALIAS_PTR)) {
+ ce = Z_PTR(p->val);
+ zend_update_parent_ce(ce);
+ }
} ZEND_HASH_FOREACH_END();
}