From e6abc937a0fb0148bac480c341e2f5acf88b58d3 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Tue, 11 Jul 2023 16:39:25 +0200 Subject: [PATCH] Fix GH-10914: OPCache with Enum and Callback functions results in segmentation fault See linked issue for analysis. --- ext/opcache/tests/gh10914.phpt | 26 ++++++++++++++++++++++++++ ext/opcache/tests/preload_gh10914.inc | 5 +++++ ext/reflection/php_reflection.c | 4 ++-- 3 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 ext/opcache/tests/gh10914.phpt create mode 100644 ext/opcache/tests/preload_gh10914.inc diff --git a/ext/opcache/tests/gh10914.phpt b/ext/opcache/tests/gh10914.phpt new file mode 100644 index 0000000000000..043eb8a8c7d03 --- /dev/null +++ b/ext/opcache/tests/gh10914.phpt @@ -0,0 +1,26 @@ +--TEST-- +GH-10914 (OPCache with Enum and Callback functions results in segmentation fault) +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.protect_memory=1 +opcache.preload={PWD}/preload_gh10914.inc +--EXTENSIONS-- +opcache +--SKIPIF-- + +--FILE-- +getCases()[0]->getValue()); +var_dump($x->getCases()[0]->getBackingValue()); +var_dump($x->getCase('FIRST')->getValue()); +var_dump($x->getCase('FIRST')->getBackingValue()); +?> +--EXPECT-- +enum(ExampleEnum::FIRST) +string(4) "AAAb" +enum(ExampleEnum::FIRST) +string(4) "AAAb" diff --git a/ext/opcache/tests/preload_gh10914.inc b/ext/opcache/tests/preload_gh10914.inc new file mode 100644 index 0000000000000..de43d637b0534 --- /dev/null +++ b/ext/opcache/tests/preload_gh10914.inc @@ -0,0 +1,5 @@ +constants_table, name); + zend_class_constant *constant = zend_hash_find_ptr(CE_CONSTANTS_TABLE(ce), name); if (constant == NULL) { zend_throw_exception_ex(reflection_exception_ptr, 0, "Case %s::%s does not exist", ZSTR_VAL(ce->name), ZSTR_VAL(name)); RETURN_THROWS(); @@ -6825,7 +6825,7 @@ ZEND_METHOD(ReflectionEnum, getCases) GET_REFLECTION_OBJECT_PTR(ce); array_init(return_value); - ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->constants_table, name, constant) { + ZEND_HASH_FOREACH_STR_KEY_PTR(CE_CONSTANTS_TABLE(ce), name, constant) { if (ZEND_CLASS_CONST_FLAGS(constant) & ZEND_CLASS_CONST_IS_CASE) { zval class_const; reflection_enum_case_factory(ce, name, constant, &class_const);