Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ PHP NEWS
types. (Weilin Du)
. Fixed MessageFormatter::parse() and parseMessage() returning PHP_INT_MIN
as float rather than int on 64-bit platforms. (Weilin Du)
. Fixed UConverter::transcode() silently truncating from_subst and to_subst
option lengths greater than 127 bytes. (Weilin Du)

- JSON:
. Enriched JSON last error / exception message with error location.
Expand Down
3 changes: 3 additions & 0 deletions UPGRADING
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ PHP 8.6 UPGRADE NOTES
int, rather than float, on 64-bit platforms when parsing integer values.
. The $type parameter of IntlBreakIterator::getPartsIterator() has been
changed from string to int to match the underlying implementation.
. UConverter::transcode() now rejects from_subst and to_subst option values
longer than 127 bytes instead of silently truncating the length before
passing it to ICU.

- PCNTL:
. pcntl_alarm() now raises a ValueError if the seconds argument is
Expand Down
14 changes: 12 additions & 2 deletions ext/intl/converter/converter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -682,6 +682,16 @@ static zend_string* php_converter_do_convert(UConverter *dest_cnv,
}
/* }}} */

static void php_converter_set_subst_chars(UConverter *cnv, zend_string *subst, UErrorCode *error)
{
if (ZSTR_LEN(subst) > SCHAR_MAX) {
*error = U_ILLEGAL_ARGUMENT_ERROR;
return;
}

ucnv_setSubstChars(cnv, ZSTR_VAL(subst), (int8_t) ZSTR_LEN(subst), error);
}

/* {{{ */
#define UCNV_REASON_CASE(v) case (UCNV_ ## v) : RETURN_STRINGL( "REASON_" #v , sizeof( "REASON_" #v ) - 1);
PHP_METHOD(UConverter, reasonText) {
Expand Down Expand Up @@ -761,13 +771,13 @@ PHP_METHOD(UConverter, transcode) {
(tmpzval = zend_hash_str_find_deref(Z_ARRVAL_P(options), "from_subst", sizeof("from_subst") - 1)) != NULL &&
Z_TYPE_P(tmpzval) == IS_STRING) {
error = U_ZERO_ERROR;
ucnv_setSubstChars(src_cnv, Z_STRVAL_P(tmpzval), Z_STRLEN_P(tmpzval) & 0x7F, &error);
php_converter_set_subst_chars(src_cnv, Z_STR_P(tmpzval), &error);
}
if (U_SUCCESS(error) &&
(tmpzval = zend_hash_str_find_deref(Z_ARRVAL_P(options), "to_subst", sizeof("to_subst") - 1)) != NULL &&
Z_TYPE_P(tmpzval) == IS_STRING) {
error = U_ZERO_ERROR;
ucnv_setSubstChars(dest_cnv, Z_STRVAL_P(tmpzval), Z_STRLEN_P(tmpzval) & 0x7F, &error);
php_converter_set_subst_chars(dest_cnv, Z_STR_P(tmpzval), &error);
}
}

Expand Down
20 changes: 20 additions & 0 deletions ext/intl/tests/uconverter_transcode_subst_length.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
--TEST--
UConverter::transcode() rejects too long substitution strings
--EXTENSIONS--
intl
--INI--
intl.use_exceptions=false
--FILE--
<?php
$subst = str_repeat('A', 129);

var_dump(UConverter::transcode('abc', 'UTF-8', 'ASCII', ['from_subst' => $subst]));
echo intl_get_error_message(), "\n";
var_dump(UConverter::transcode('abc', 'UTF-8', 'ASCII', ['to_subst' => $subst]));
echo intl_get_error_message(), "\n";
?>
--EXPECT--
bool(false)
UConverter::transcode(): returned error 1: U_ILLEGAL_ARGUMENT_ERROR: U_ILLEGAL_ARGUMENT_ERROR
bool(false)
UConverter::transcode(): returned error 1: U_ILLEGAL_ARGUMENT_ERROR: U_ILLEGAL_ARGUMENT_ERROR
Loading