diff --git a/NEWS b/NEWS index 6ba018dab89d..0ba84b077000 100644 --- a/NEWS +++ b/NEWS @@ -97,6 +97,9 @@ PHP NEWS locale_get_display_keyword_value() respectively. (Weilin Du) . Fix incorrect argument positions for invalid start/end arguments in transliterator_transliterate(). (Weilin Du) + . IntlDateFormatter::parse()/datefmt_parse() and + IntlDateFormatter::localtime()/datefmt_localtime() now raise TypeError + when the offset argument is not of type int. (Weilin Du) . Fixed IntlTimeZone::getDisplayName() to synchronize object error state for invalid display types. (Weilin Du) . Fixed Locale::lookup() and locale_lookup() to return NULL instead of the diff --git a/UPGRADING b/UPGRADING index fa9a816f7aed..5e3d37bd62ac 100644 --- a/UPGRADING +++ b/UPGRADING @@ -53,6 +53,10 @@ PHP 8.6 UPGRADE NOTES . ResourceBundle::get() and resourcebundle_get() now report fallback-disabled resource lookups with "without fallback to " instead of the malformed "without fallback from to ". + . IntlDateFormatter::parse()/datefmt_parse() and + IntlDateFormatter::localtime()/datefmt_localtime() now raise a TypeError + when the offset argument is not of type int instead of silently converting + the value. - PCNTL: . pcntl_alarm() now raises a ValueError if the seconds argument is diff --git a/ext/intl/dateformat/dateformat_parse.cpp b/ext/intl/dateformat/dateformat_parse.cpp index d818627439e3..0537b42feec5 100644 --- a/ext/intl/dateformat/dateformat_parse.cpp +++ b/ext/intl/dateformat/dateformat_parse.cpp @@ -147,9 +147,12 @@ U_CFUNC PHP_FUNCTION(datefmt_parse) DATE_FORMAT_METHOD_FETCH_OBJECT; if (z_parse_pos) { - zval *z_parse_pos_tmp = z_parse_pos; - ZVAL_DEREF(z_parse_pos_tmp); - const zend_long long_parse_pos = zval_get_long(z_parse_pos_tmp); + bool failed; + const zend_long long_parse_pos = zval_try_get_long(z_parse_pos, &failed); + if (failed) { + zend_argument_type_error(hasThis() ? 2 : 3, "must be of type int, %s given", zend_zval_value_name(z_parse_pos)); + RETURN_THROWS(); + } if (ZEND_LONG_INT_OVFL(long_parse_pos)) { intl_error_set_code(NULL, U_ILLEGAL_ARGUMENT_ERROR); intl_error_set_custom_msg(NULL, "String index is out of valid range."); @@ -229,9 +232,12 @@ U_CFUNC PHP_FUNCTION(datefmt_localtime) DATE_FORMAT_METHOD_FETCH_OBJECT; if (z_parse_pos) { - zval *z_parse_pos_tmp = z_parse_pos; - ZVAL_DEREF(z_parse_pos_tmp); - const zend_long long_parse_pos = zval_get_long(z_parse_pos_tmp); + bool failed; + const zend_long long_parse_pos = zval_try_get_long(z_parse_pos, &failed); + if (failed) { + zend_argument_type_error(hasThis() ? 2 : 3, "must be of type int, %s given", zend_zval_value_name(z_parse_pos)); + RETURN_THROWS(); + } if (ZEND_LONG_INT_OVFL(long_parse_pos)) { intl_error_set_code(NULL, U_ILLEGAL_ARGUMENT_ERROR); intl_error_set_custom_msg(NULL, "String index is out of valid range."); diff --git a/ext/intl/tests/datefmt_parse_localtime_offset_type_error.phpt b/ext/intl/tests/datefmt_parse_localtime_offset_type_error.phpt new file mode 100644 index 000000000000..5c3d03cd4f65 --- /dev/null +++ b/ext/intl/tests/datefmt_parse_localtime_offset_type_error.phpt @@ -0,0 +1,44 @@ +--TEST-- +datefmt_parse() and datefmt_localtime() validate offset type +--EXTENSIONS-- +intl +--FILE-- +setPattern('VV'); + +$offset = 'offset'; +try { + $fmt->parse('America/Los_Angeles', $offset); +} catch (TypeError $e) { + echo $e->getMessage(), PHP_EOL; +} + +$offset = 'offset'; +try { + datefmt_parse($fmt, 'America/Los_Angeles', $offset); +} catch (TypeError $e) { + echo $e->getMessage(), PHP_EOL; +} + +$offset = 'offset'; +try { + $fmt->localtime('America/Los_Angeles', $offset); +} catch (TypeError $e) { + echo $e->getMessage(), PHP_EOL; +} + +$offset = 'offset'; +try { + datefmt_localtime($fmt, 'America/Los_Angeles', $offset); +} catch (TypeError $e) { + echo $e->getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +IntlDateFormatter::parse(): Argument #2 ($offset) must be of type int, string given +datefmt_parse(): Argument #3 ($offset) must be of type int, string given +IntlDateFormatter::localtime(): Argument #2 ($offset) must be of type int, string given +datefmt_localtime(): Argument #3 ($offset) must be of type int, string given