From 2309fab259fa4c8118361d0ab031cd67400ddbf0 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Thu, 16 Jun 2022 15:06:48 +0200 Subject: [PATCH 1/4] Fix segfault when calling from/tryFrom on empty enum --- Zend/tests/enum/empty-from.phpt | 12 ++++++++++++ Zend/zend_enum.c | 4 ++++ 2 files changed, 16 insertions(+) create mode 100644 Zend/tests/enum/empty-from.phpt diff --git a/Zend/tests/enum/empty-from.phpt b/Zend/tests/enum/empty-from.phpt new file mode 100644 index 0000000000000..db42c78ed31c7 --- /dev/null +++ b/Zend/tests/enum/empty-from.phpt @@ -0,0 +1,12 @@ +--TEST-- +Empty enum with from/tryFrom doens't segfault +--FILE-- + +--EXPECT-- +NULL diff --git a/Zend/zend_enum.c b/Zend/zend_enum.c index a4a450d22fba6..8c8c7294e5c47 100644 --- a/Zend/zend_enum.c +++ b/Zend/zend_enum.c @@ -281,6 +281,9 @@ ZEND_API zend_result zend_enum_get_case_by_value(zend_object **result, zend_clas return FAILURE; } } + if (!ce->backed_enum_table) { + goto not_found; + } zval *case_name_zv; if (ce->enum_backing_type == IS_LONG) { @@ -292,6 +295,7 @@ ZEND_API zend_result zend_enum_get_case_by_value(zend_object **result, zend_clas } if (case_name_zv == NULL) { +not_found: if (try) { *result = NULL; return SUCCESS; From fe71a9569d6160d0d2bed01812e658d63fddf7bb Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Thu, 16 Jun 2022 15:07:30 +0200 Subject: [PATCH 2/4] Fix segfault when using preloaded enums --- Zend/zend_enum.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Zend/zend_enum.c b/Zend/zend_enum.c index 8c8c7294e5c47..2911efa8e892c 100644 --- a/Zend/zend_enum.c +++ b/Zend/zend_enum.c @@ -199,7 +199,7 @@ zend_result zend_enum_build_backed_enum_table(zend_class_entry *ce) zend_string *name; zval *val; - ZEND_HASH_MAP_FOREACH_STR_KEY_VAL(&ce->constants_table, name, val) { + ZEND_HASH_MAP_FOREACH_STR_KEY_VAL(CE_CONSTANTS_TABLE(ce), name, val) { zend_class_constant *c = Z_PTR_P(val); if ((ZEND_CLASS_CONST_FLAGS(c) & ZEND_CLASS_CONST_IS_CASE) == 0) { continue; From ea3a0ebf443bdac589e4419cef3c29dc4fd9ef26 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Thu, 16 Jun 2022 15:14:16 +0200 Subject: [PATCH 3/4] Fix leak of backed_enum_table with preloading --- Zend/zend_enum.c | 1 + Zend/zend_execute_API.c | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/Zend/zend_enum.c b/Zend/zend_enum.c index 2911efa8e892c..7e8654942f216 100644 --- a/Zend/zend_enum.c +++ b/Zend/zend_enum.c @@ -187,6 +187,7 @@ void zend_enum_add_interfaces(zend_class_entry *ce) zend_result zend_enum_build_backed_enum_table(zend_class_entry *ce) { ZEND_ASSERT(ce->ce_flags & ZEND_ACC_ENUM); + ZEND_ASSERT(!(ce->ce_flags & ZEND_ACC_IMMUTABLE)); ZEND_ASSERT(ce->type == ZEND_USER_CLASS); uint32_t backing_type = ce->enum_backing_type; diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index e203556a8ecd7..9822ef692a83d 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -346,6 +346,12 @@ ZEND_API void zend_shutdown_executor_values(bool fast_shutdown) } } + if (ce->type == ZEND_USER_CLASS && ce->backed_enum_table) { + ZEND_ASSERT(!(ce->ce_flags & ZEND_ACC_IMMUTABLE)); + zend_hash_release(ce->backed_enum_table); + ce->backed_enum_table = NULL; + } + if (ce->ce_flags & ZEND_HAS_STATIC_IN_METHODS) { zend_op_array *op_array; ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, op_array) { From 75cf10aa384dfb2ec181d519e7bdc42ae4f0b723 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Thu, 16 Jun 2022 16:16:13 +0200 Subject: [PATCH 4/4] Fix magic constants in backed enum values Fix GH-8777 --- Zend/tests/enum/magic-constants.phpt | 14 ++++++++++++++ Zend/zend_compile.c | 3 +++ 2 files changed, 17 insertions(+) create mode 100644 Zend/tests/enum/magic-constants.phpt diff --git a/Zend/tests/enum/magic-constants.phpt b/Zend/tests/enum/magic-constants.phpt new file mode 100644 index 0000000000000..7a11d7785d7a4 --- /dev/null +++ b/Zend/tests/enum/magic-constants.phpt @@ -0,0 +1,14 @@ +--TEST-- +Backed enums can contain magic constants +--FILE-- +value, "\n"; + +?> +--EXPECTF-- +%smagic-constants.php diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 728feded60896..06a21944443dc 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -10473,6 +10473,9 @@ static void zend_eval_const_expr(zend_ast **ast_ptr) /* {{{ */ case ZEND_AST_NAMED_ARG: zend_eval_const_expr(&ast->child[1]); return; + case ZEND_AST_CONST_ENUM_INIT: + zend_eval_const_expr(&ast->child[2]); + return; default: return; }