Skip to content

Commit a07ae61

Browse files
marc-mabeLamentXU123
authored andcommitted
Fix IntlDateFormatter parse functions truncating an $offset below INT_MIN (#24781)
Check both bounds before narrowing the parse offset to int32_t. On 64-bit systems, a value such as -4294967295 previously became 1 and parsing started at the wrong position. Cover all three parse functions with a regression test. Closes #24781
1 parent 3a8bcb6 commit a07ae61

3 files changed

Lines changed: 40 additions & 3 deletions

File tree

‎NEWS‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,10 @@ PHP NEWS
9898
- Hash:
9999
. Fix GOST and Snefru digests of 512 MiB or more. (Martin Mirchev)
100100

101+
- Intl:
102+
. Fixed IntlDateFormatter parse functions truncating an $offset below
103+
INT_MIN. (Marc Bennewitz)
104+
101105
- MBString:
102106
. Fixed bug GH-23958 (truncated encoding names resolving to full names). (Kamil Tekiela)
103107
. Fixed out-of-bounds read in php_mb_rfc1867_getword() on a multibyte lead

‎ext/intl/dateformat/dateformat_parse.c‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ PHP_FUNCTION(datefmt_parse)
169169
zval *z_parse_pos_tmp = z_parse_pos;
170170
ZVAL_DEREF(z_parse_pos_tmp);
171171
zend_long long_parse_pos = zval_get_long(z_parse_pos_tmp);
172-
if (ZEND_LONG_INT_OVFL(long_parse_pos)) {
172+
if (ZEND_LONG_EXCEEDS_INT(long_parse_pos)) {
173173
intl_error_set_code(NULL, U_ILLEGAL_ARGUMENT_ERROR);
174174
intl_error_set_custom_msg(NULL, "String index is out of valid range.", 0);
175175
RETURN_FALSE;
@@ -212,7 +212,7 @@ PHP_METHOD(IntlDateFormatter, parseToCalendar)
212212
zend_argument_type_error(2, "must be of type int, %s given", zend_zval_value_name(z_parse_pos));
213213
RETURN_THROWS();
214214
}
215-
if (ZEND_LONG_INT_OVFL(long_parse_pos)) {
215+
if (ZEND_LONG_EXCEEDS_INT(long_parse_pos)) {
216216
intl_error_set_code(NULL, U_ILLEGAL_ARGUMENT_ERROR);
217217
intl_error_set_custom_msg(NULL, "String index is out of valid range.", 0);
218218
RETURN_FALSE;
@@ -251,7 +251,7 @@ PHP_FUNCTION(datefmt_localtime)
251251
zval *z_parse_pos_tmp = z_parse_pos;
252252
ZVAL_DEREF(z_parse_pos_tmp);
253253
zend_long long_parse_pos = zval_get_long(z_parse_pos_tmp);
254-
if (ZEND_LONG_INT_OVFL(long_parse_pos)) {
254+
if (ZEND_LONG_EXCEEDS_INT(long_parse_pos)) {
255255
intl_error_set_code(NULL, U_ILLEGAL_ARGUMENT_ERROR);
256256
intl_error_set_custom_msg(NULL, "String index is out of valid range.", 0);
257257
RETURN_FALSE;
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
--TEST--
2+
IntlDateFormatter parse functions reject an offset below INT_MIN
3+
--EXTENSIONS--
4+
intl
5+
--SKIPIF--
6+
<?php
7+
if (PHP_INT_SIZE <= 4) die('skip requires a 64-bit zend_long');
8+
?>
9+
--FILE--
10+
<?php
11+
/* -4294967295 used to be truncated to an int32_t of 1, so parsing started
12+
* at offset 1 instead of failing. */
13+
$fmt = new IntlDateFormatter('en_US', IntlDateFormatter::FULL, IntlDateFormatter::FULL, 'UTC', null, 'yyyy');
14+
15+
$offset = -4294967295;
16+
var_dump(datefmt_parse($fmt, '12026', $offset), $offset, intl_get_error_message());
17+
18+
$offset = -4294967295;
19+
var_dump($fmt->parseToCalendar('12026', $offset), $offset, intl_get_error_message());
20+
21+
$offset = -4294967295;
22+
var_dump(datefmt_localtime($fmt, '12026', $offset), $offset, intl_get_error_message());
23+
?>
24+
--EXPECTF--
25+
bool(false)
26+
int(-4294967295)
27+
string(%d) "%SString index is out of valid range.: U_ILLEGAL_ARGUMENT_ERROR"
28+
bool(false)
29+
int(-4294967295)
30+
string(%d) "%SString index is out of valid range.: U_ILLEGAL_ARGUMENT_ERROR"
31+
bool(false)
32+
int(-4294967295)
33+
string(%d) "%SString index is out of valid range.: U_ILLEGAL_ARGUMENT_ERROR"

0 commit comments

Comments
 (0)