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