Commit f61ebc03488 for php
commit f61ebc03488496e7b6af5d2a0e18e3c8c7b09b73
Author: David Carlier <devnexen@gmail.com>
Date: Sat Sep 12 11:02:14 2026 +0100
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.
Close GH-23673
diff --git a/NEWS b/NEWS
index cc86e4e8be3..c872634f968 100644
--- a/NEWS
+++ b/NEWS
@@ -42,6 +42,8 @@ PHP NEWS
toUCallback/fromUCallback. (Ilia Alshanetsky)
. Fixed Collator attribute and strength methods not rejecting an
unconstructed Collator. (Ilia Alshanetsky)
+ . Fixed crash in intl_error_set_custom_msg() without an active call frame.
+ (David Carlier)
- Lexbor:
. Merge patches lexbor/lexbor@8a14bc0 and lexbor/lexbor@f67ce4b, fixing a
diff --git a/ext/intl/intl_error.c b/ext/intl/intl_error.c
index be6e53fb543..e5506ab44ac 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 00000000000..09c231a99e9
--- /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--
+<?php
+class MyConverter extends UConverter {
+ public function toUCallback($reason, $source, $codeUnits, &$error): string|int|array|null {
+ return '?';
+ }
+
+ public function fromUCallback($reason, $source, $codePoint, &$error): string|int|array|null {
+ return '?';
+ }
+}
+
+$converter = new MyConverter('ascii', 'utf-8');
+echo 'end of script', PHP_EOL;
+?>
+--EXPECT--
+end of script