Commit cd5574617f8 for php.net
commit cd5574617f8f27a56ba33f2ebbbc78ddb5039e4d
Merge: e22ba55be19 946d687d8d5
Author: David Carlier <devnexen@gmail.com>
Date: Sun May 24 07:35:29 2026 +0100
Merge branch 'PHP-8.5'
* PHP-8.5:
ext/intl: fix IntlListFormatter object error state after format() failures
diff --cc ext/intl/listformatter/listformatter_class.cpp
index 817b3d74369,e4f8b18d7dd..950eb81b7e1
--- a/ext/intl/listformatter/listformatter_class.cpp
+++ b/ext/intl/listformatter/listformatter_class.cpp
@@@ -142,41 -138,76 +144,41 @@@ PHP_METHOD(IntlListFormatter, format
ZEND_HASH_FOREACH_VAL(ht, val) {
zend_string *str_val, *tmp_str;
-
- str_val = zval_get_tmp_string(val, &tmp_str);
-
- // Convert PHP string to UTF-16
- UChar *ustr = NULL;
- int32_t ustr_len = 0;
- UErrorCode status = U_ZERO_ERROR;
-
- intl_convert_utf8_to_utf16(&ustr, &ustr_len, ZSTR_VAL(str_val), ZSTR_LEN(str_val), &status);
+ UErrorCode conv_status = U_ZERO_ERROR;
+
+ str_val = zval_try_get_tmp_string(val, &tmp_str);
+ if (UNEXPECTED(!str_val)) {
+ RETURN_THROWS();
+ }
+ intl_stringFromChar(items[i], ZSTR_VAL(str_val), ZSTR_LEN(str_val), &conv_status);
zend_tmp_string_release(tmp_str);
- if (U_FAILURE(status)) {
- // We can't use goto cleanup because items and itemLengths are incompletely allocated
- for (uint32_t j = 0; j < i; j++) {
- efree((void *)items[j]);
- }
- efree(items);
- efree(itemLengths);
- intl_errors_set(LISTFORMATTER_ERROR_P(obj), status, "Failed to convert string to UTF-16");
+ if (U_FAILURE(conv_status)) {
- intl_error_set(nullptr, conv_status, "Failed to convert string to UTF-16");
++ intl_errors_set(LISTFORMATTER_ERROR_P(obj), conv_status, "Failed to convert string to UTF-16");
RETURN_FALSE;
}
-
- items[i] = ustr;
- itemLengths[i] = ustr_len;
+
i++;
} ZEND_HASH_FOREACH_END();
UErrorCode status = U_ZERO_ERROR;
- int32_t resultLength;
- UChar *result = NULL;
-
- resultLength = ulistfmt_format(LISTFORMATTER_OBJECT(obj), items, itemLengths, count, NULL, 0, &status);
-
- if (U_FAILURE(status) && status != U_BUFFER_OVERFLOW_ERROR) {
- intl_errors_set(LISTFORMATTER_ERROR_P(obj), status, "Failed to format list");
- RETVAL_FALSE;
- goto cleanup;
- }
+ UnicodeString result;
- // Allocate buffer and try again
- status = U_ZERO_ERROR;
- result = (UChar *)safe_emalloc(resultLength + 1, sizeof(UChar), 0);
- ulistfmt_format(LISTFORMATTER_OBJECT(obj), items, itemLengths, count, result, resultLength, &status);
+ LISTFORMATTER_OBJECT(obj)->format(items.get(), count, result, status);
if (U_FAILURE(status)) {
- intl_error_set(nullptr, status, "Failed to format list");
- if (result) {
- efree(result);
- }
+ intl_errors_set(LISTFORMATTER_ERROR_P(obj), status, "Failed to format list");
- RETVAL_FALSE;
- goto cleanup;
+ RETURN_FALSE;
}
- // Convert result back to UTF-8
- zend_string *ret = intl_convert_utf16_to_utf8(result, resultLength, &status);
- efree(result);
-
+ zend_string *ret = intl_charFromString(result, &status);
+
if (!ret) {
- intl_error_set(nullptr, 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);
+ RETURN_FALSE;
}
-cleanup:
- for (i = 0; i < count; i++) {
- efree((void *)items[i]);
- }
- efree(items);
- efree(itemLengths);
+ RETVAL_STR(ret);
}
PHP_METHOD(IntlListFormatter, getErrorCode)