Commit 946d687d8d5 for php.net
commit 946d687d8d5a18c65a547a8fbb80b93dbe3abcce
Author: “LamentXU123” <108666168+LamentXU123@users.noreply.github.com>
Date: Fri May 22 18:28:58 2026 +0800
ext/intl: fix IntlListFormatter object error state after format() failures
close GH-22119
fix UPGRADING
diff --git a/NEWS b/NEWS
index 595b7c8096f..ae3cae76032 100644
--- a/NEWS
+++ b/NEWS
@@ -388,6 +388,8 @@ PHP NEWS
when pos.size < 2). (Oblivionsage)
- Intl:
+ . Fixed IntlListFormatter::getErrorCode() and getErrorMessage() not
+ reflecting format() failures. (Weilin Du)
. Fix leak in umsg_format_helper(). (ndossche)
- LDAP:
diff --git a/UPGRADING b/UPGRADING
index 80b6a5ff38d..8b6e0c57cb1 100644
--- a/UPGRADING
+++ b/UPGRADING
@@ -846,6 +846,8 @@ PHP 8.5 UPGRADE NOTES
indicates more accurately which call site caused what error.
Moreover, some ext/date exceptions have been wrapped inside a
IntlException now.
+ . IntlListFormatter::getErrorCode() and getErrorMessage() now reflect
+ IntlListFormatter::format() failures.
- Lexbor:
. An always enabled lexbor extension is added. It contains the lexbor
diff --git a/ext/intl/listformatter/listformatter_class.c b/ext/intl/listformatter/listformatter_class.c
index 1aa849370ab..e4f8b18d7dd 100644
--- a/ext/intl/listformatter/listformatter_class.c
+++ b/ext/intl/listformatter/listformatter_class.c
@@ -124,6 +124,8 @@ PHP_METHOD(IntlListFormatter, format)
Z_PARAM_ARRAY_HT(ht)
ZEND_PARSE_PARAMETERS_END();
+ intl_errors_reset(LISTFORMATTER_ERROR_P(obj));
+
uint32_t count = zend_hash_num_elements(ht);
if (count == 0) {
RETURN_EMPTY_STRING();
@@ -154,7 +156,7 @@ PHP_METHOD(IntlListFormatter, format)
}
efree(items);
efree(itemLengths);
- intl_error_set(NULL, status, "Failed to convert string to UTF-16");
+ intl_errors_set(LISTFORMATTER_ERROR_P(obj), status, "Failed to convert string to UTF-16");
RETURN_FALSE;
}
@@ -170,7 +172,7 @@ PHP_METHOD(IntlListFormatter, format)
resultLength = ulistfmt_format(LISTFORMATTER_OBJECT(obj), items, itemLengths, count, NULL, 0, &status);
if (U_FAILURE(status) && status != U_BUFFER_OVERFLOW_ERROR) {
- intl_error_set(NULL, status, "Failed to format list");
+ intl_errors_set(LISTFORMATTER_ERROR_P(obj), status, "Failed to format list");
RETVAL_FALSE;
goto cleanup;
}
@@ -184,7 +186,7 @@ PHP_METHOD(IntlListFormatter, format)
if (result) {
efree(result);
}
- intl_error_set(NULL, status, "Failed to format list");
+ intl_errors_set(LISTFORMATTER_ERROR_P(obj), status, "Failed to format list");
RETVAL_FALSE;
goto cleanup;
}
@@ -194,7 +196,7 @@ PHP_METHOD(IntlListFormatter, format)
efree(result);
if (!ret) {
- intl_error_set(NULL, status, "Failed to convert result to UTF-8");
+ intl_errors_set(LISTFORMATTER_ERROR_P(obj), status, "Failed to convert result to UTF-8");
RETVAL_FALSE;
} else {
RETVAL_NEW_STR(ret);
diff --git a/ext/intl/tests/listformatter/listformatter_get_error.phpt b/ext/intl/tests/listformatter/listformatter_get_error.phpt
new file mode 100644
index 00000000000..a2a23b3473d
--- /dev/null
+++ b/ext/intl/tests/listformatter/listformatter_get_error.phpt
@@ -0,0 +1,25 @@
+--TEST--
+IntlListFormatter getErrorCode()/getErrorMessage() reflect format() failures
+--EXTENSIONS--
+intl
+--FILE--
+<?php
+
+$formatter = new IntlListFormatter('en_US');
+
+var_dump($formatter->format(["\x80"]));
+var_dump($formatter->getErrorCode() === U_INVALID_CHAR_FOUND);
+var_dump($formatter->getErrorMessage());
+
+var_dump($formatter->format(['a', 'b']));
+var_dump($formatter->getErrorCode() === U_ZERO_ERROR);
+var_dump($formatter->getErrorMessage());
+
+?>
+--EXPECT--
+bool(false)
+bool(true)
+string(85) "IntlListFormatter::format(): Failed to convert string to UTF-16: U_INVALID_CHAR_FOUND"
+string(7) "a and b"
+bool(true)
+string(12) "U_ZERO_ERROR"