From 4664e331adf6c6e531de9fa97d5f99b5d6a26520 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Sat, 12 Sep 2026 11:02:14 +0100 Subject: [PATCH] ext/intl: intl_error_set_custom_msg() crash without an active call frame. Since 6600d0e00fc the message was unconditionally prefixed with get_active_function_or_method_name(), which asserts zend_is_executing() and dereferences a null EG(current_execute_data) in a release build. A UConverter subclass destroyed at request shutdown reached it through ucnv_close(). Fall back to the unprefixed message when there is no frame. --- ext/intl/intl_error.c | 19 ++++++++++------- .../tests/uconverter_shutdown_subclass.phpt | 21 +++++++++++++++++++ 2 files changed, 33 insertions(+), 7 deletions(-) create mode 100644 ext/intl/tests/uconverter_shutdown_subclass.phpt diff --git a/ext/intl/intl_error.c b/ext/intl/intl_error.c index be6e53fb5439..e5506ab44ac3 100644 --- a/ext/intl/intl_error.c +++ b/ext/intl/intl_error.c @@ -91,13 +91,18 @@ void intl_error_set_custom_msg( intl_error* err, const char* msg) return; } - zend_string *method_or_func = get_active_function_or_method_name(); - zend_string *prefixed_message = zend_string_concat3( - ZSTR_VAL(method_or_func), ZSTR_LEN(method_or_func), - ZEND_STRL("(): "), - msg, strlen(msg) - ); - zend_string_release_ex(method_or_func, false); + zend_string *prefixed_message; + if (zend_is_executing()) { + zend_string *method_or_func = get_active_function_or_method_name(); + prefixed_message = zend_string_concat3( + ZSTR_VAL(method_or_func), ZSTR_LEN(method_or_func), + ZEND_STRL("(): "), + msg, strlen(msg) + ); + zend_string_release_ex(method_or_func, false); + } else { + prefixed_message = zend_string_init(msg, strlen(msg), false); + } if( !err ) { if (INTL_G(error_level)) { diff --git a/ext/intl/tests/uconverter_shutdown_subclass.phpt b/ext/intl/tests/uconverter_shutdown_subclass.phpt new file mode 100644 index 000000000000..09c231a99e9c --- /dev/null +++ b/ext/intl/tests/uconverter_shutdown_subclass.phpt @@ -0,0 +1,21 @@ +--TEST-- +UConverter subclass destroyed at request shutdown does not crash +--EXTENSIONS-- +intl +--FILE-- + +--EXPECT-- +end of script