From 2603b0e76cb1337035af43b66ad82c48600ddd0e Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Tue, 27 Oct 2026 11:44:33 +0100 Subject: [PATCH] Fix IntlDateFormatter parse functions truncating an $offset below INT_MIN Only the upper bound of $offset was checked before it is narrowed into an int32_t, so on 64-bit platforms e.g. -4294967295 was truncated to 1 and parsing started from there instead of failing. --- NEWS | 4 +++ ext/intl/dateformat/dateformat_parse.c | 6 ++-- .../dateformat_parse_offset_out_of_range.phpt | 33 +++++++++++++++++++ 3 files changed, 40 insertions(+), 3 deletions(-) create mode 100644 ext/intl/tests/dateformat_parse_offset_out_of_range.phpt diff --git a/NEWS b/NEWS index 131c02d4c240..bacab4bdfde3 100644 --- a/NEWS +++ b/NEWS @@ -83,6 +83,10 @@ PHP NEWS - Hash: . Fix GOST and Snefru digests of 512 MiB or more. (Martin Mirchev) +- Intl: + . Fixed IntlDateFormatter parse functions truncating an $offset below + INT_MIN. (Marc Bennewitz) + - MBString: . Fixed bug GH-23958 (truncated encoding names resolving to full names). (Kamil Tekiela) . Fixed out-of-bounds read in php_mb_rfc1867_getword() on a multibyte lead diff --git a/ext/intl/dateformat/dateformat_parse.c b/ext/intl/dateformat/dateformat_parse.c index 2199da369156..7daa910c8f22 100644 --- a/ext/intl/dateformat/dateformat_parse.c +++ b/ext/intl/dateformat/dateformat_parse.c @@ -169,7 +169,7 @@ PHP_FUNCTION(datefmt_parse) zval *z_parse_pos_tmp = z_parse_pos; ZVAL_DEREF(z_parse_pos_tmp); zend_long long_parse_pos = zval_get_long(z_parse_pos_tmp); - if (ZEND_LONG_INT_OVFL(long_parse_pos)) { + if (ZEND_LONG_EXCEEDS_INT(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.", 0); RETURN_FALSE; @@ -212,7 +212,7 @@ PHP_METHOD(IntlDateFormatter, parseToCalendar) zend_argument_type_error(2, "must be of type int, %s given", zend_zval_value_name(z_parse_pos)); RETURN_THROWS(); } - if (ZEND_LONG_INT_OVFL(long_parse_pos)) { + if (ZEND_LONG_EXCEEDS_INT(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.", 0); RETURN_FALSE; @@ -251,7 +251,7 @@ PHP_FUNCTION(datefmt_localtime) zval *z_parse_pos_tmp = z_parse_pos; ZVAL_DEREF(z_parse_pos_tmp); zend_long long_parse_pos = zval_get_long(z_parse_pos_tmp); - if (ZEND_LONG_INT_OVFL(long_parse_pos)) { + if (ZEND_LONG_EXCEEDS_INT(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.", 0); RETURN_FALSE; diff --git a/ext/intl/tests/dateformat_parse_offset_out_of_range.phpt b/ext/intl/tests/dateformat_parse_offset_out_of_range.phpt new file mode 100644 index 000000000000..3347665eb3bf --- /dev/null +++ b/ext/intl/tests/dateformat_parse_offset_out_of_range.phpt @@ -0,0 +1,33 @@ +--TEST-- +IntlDateFormatter parse functions reject an offset below INT_MIN +--EXTENSIONS-- +intl +--SKIPIF-- + +--FILE-- +parseToCalendar('12026', $offset), $offset, intl_get_error_message()); + +$offset = -4294967295; +var_dump(datefmt_localtime($fmt, '12026', $offset), $offset, intl_get_error_message()); +?> +--EXPECTF-- +bool(false) +int(-4294967295) +string(%d) "%SString index is out of valid range.: U_ILLEGAL_ARGUMENT_ERROR" +bool(false) +int(-4294967295) +string(%d) "%SString index is out of valid range.: U_ILLEGAL_ARGUMENT_ERROR" +bool(false) +int(-4294967295) +string(%d) "%SString index is out of valid range.: U_ILLEGAL_ARGUMENT_ERROR"