Skip to content

Commit 10704f0

Browse files
LamentXU123devnexen
authored andcommitted
ext/intl: Fix out-of-bounds argument positions in calendar date/time APIs.
close phpGH-22044
1 parent 37bb1c3 commit 10704f0

8 files changed

Lines changed: 215 additions & 12 deletions

NEWS

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@ PHP NEWS
22
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
33
?? ??? ????, PHP 8.4.22
44

5+
- Intl:
6+
. Fix incorrect argument positions in out-of-bounds errors for
7+
IntlCalendar::set(), IntlCalendar::setDate(), IntlCalendar::setDateTime(),
8+
and IntlGregorianCalendar date/time construction. (Weilin Du)
9+
510
- MySQLnd:
611
. Fix persistent free of non-persistent connect_attr key (David Carlier).
712

UPGRADING

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@ PHP 8.4 UPGRADE NOTES
8282
. bind_textdomain_codeset, textdomain and d(*)gettext functions now throw an exception
8383
if the domain argument is empty.
8484
. Intl:
85+
. IntlCalendar::set(), IntlCalendar::setDate(), IntlCalendar::setDateTime(),
86+
and IntlGregorianCalendar date/time construction now report the correct
87+
argument position for out-of-bounds integer values.
8588
. resourcebundle_get(), ResourceBundle::get(), and accessing offsets on a
8689
ResourceBundle object now throw:
8790
- TypeError for invalid offset types

ext/intl/calendar/calendar_methods.cpp

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -391,8 +391,8 @@ U_CFUNC PHP_FUNCTION(intlcal_set)
391391
}
392392

393393
for (int i = 0; i < arg_num; i++) {
394-
/* Arguments start at 1 */
395-
ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(args[i], i + 1);
394+
/* Count from intlcal_set($calendar, ...), so date/time arguments start at #2. */
395+
ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(args[i], i + 2);
396396
}
397397

398398
CALENDAR_METHOD_FETCH_OBJECT;
@@ -427,9 +427,10 @@ U_CFUNC PHP_METHOD(IntlCalendar, setDate)
427427
RETURN_THROWS();
428428
}
429429

430-
ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(year, 1);
431-
ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(month, 2);
432-
ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(day, 3);
430+
/* These method-only APIs parse the object first, so the API argument positions are offset by +1. */
431+
ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(year, 2);
432+
ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(month, 3);
433+
ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(day, 4);
433434

434435
CALENDAR_METHOD_FETCH_OBJECT;
435436

@@ -450,18 +451,19 @@ U_CFUNC PHP_METHOD(IntlCalendar, setDateTime)
450451
RETURN_THROWS();
451452
}
452453

453-
ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(year, 1);
454-
ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(month, 2);
455-
ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(day, 3);
456-
ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(hour, 4);
457-
ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(minute, 5);
454+
/* These method-only APIs parse the object first, so the API argument positions are offset by +1. */
455+
ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(year, 2);
456+
ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(month, 3);
457+
ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(day, 4);
458+
ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(hour, 5);
459+
ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(minute, 6);
458460

459461
CALENDAR_METHOD_FETCH_OBJECT;
460462

461463
if (second_is_null) {
462464
co->ucal->set((int32_t) year, (int32_t) month, (int32_t) day, (int32_t) hour, (int32_t) minute);
463465
} else {
464-
ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(second, 6);
466+
ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(second, 7);
465467
co->ucal->set((int32_t) year, (int32_t) month, (int32_t) day, (int32_t) hour, (int32_t) minute, (int32_t) second);
466468
}
467469
}

ext/intl/calendar/gregoriancalendar_methods.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ static void _php_intlgregcal_constructor_body(
178178
} else {
179179
// From date/time (3, 5 or 6 arguments)
180180
for (int i = 0; i < variant; i++) {
181-
ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(largs[i], hasThis() ? (i-1) : i);
181+
ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(largs[i], i + 1);
182182
}
183183

184184
if (variant == 3) {
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
--TEST--
2+
IntlCalendar::setDate(): out-of-bounds arguments report correct positions
3+
--EXTENSIONS--
4+
intl
5+
--SKIPIF--
6+
<?php if (PHP_INT_SIZE != 8) die("skip: 64-bit only"); ?>
7+
--FILE--
8+
<?php
9+
$cal = IntlCalendar::createInstance();
10+
11+
try {
12+
$cal->setDate(99999999999, 1, 1);
13+
} catch (Throwable $e) {
14+
echo $e->getMessage(), "\n";
15+
}
16+
17+
try {
18+
$cal->setDate(1, 99999999999, 1);
19+
} catch (Throwable $e) {
20+
echo $e->getMessage(), "\n";
21+
}
22+
23+
try {
24+
$cal->setDate(1, 1, 99999999999);
25+
} catch (Throwable $e) {
26+
echo $e->getMessage(), "\n";
27+
}
28+
?>
29+
--EXPECT--
30+
IntlCalendar::setDate(): Argument #1 ($year) must be between -2147483648 and 2147483647
31+
IntlCalendar::setDate(): Argument #2 ($month) must be between -2147483648 and 2147483647
32+
IntlCalendar::setDate(): Argument #3 ($dayOfMonth) must be between -2147483648 and 2147483647
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
--TEST--
2+
IntlCalendar::setDateTime(): out-of-bounds arguments report correct positions
3+
--EXTENSIONS--
4+
intl
5+
--SKIPIF--
6+
<?php if (PHP_INT_SIZE != 8) die("skip: 64-bit only"); ?>
7+
--FILE--
8+
<?php
9+
$cal = IntlCalendar::createInstance();
10+
11+
try {
12+
$cal->setDateTime(99999999999, 1, 1, 1, 1, 1);
13+
} catch (Throwable $e) {
14+
echo $e->getMessage(), "\n";
15+
}
16+
17+
try {
18+
$cal->setDateTime(1, 99999999999, 1, 1, 1, 1);
19+
} catch (Throwable $e) {
20+
echo $e->getMessage(), "\n";
21+
}
22+
23+
try {
24+
$cal->setDateTime(1, 1, 99999999999, 1, 1, 1);
25+
} catch (Throwable $e) {
26+
echo $e->getMessage(), "\n";
27+
}
28+
29+
try {
30+
$cal->setDateTime(1, 1, 1, 99999999999, 1, 1);
31+
} catch (Throwable $e) {
32+
echo $e->getMessage(), "\n";
33+
}
34+
35+
try {
36+
$cal->setDateTime(1, 1, 1, 1, 99999999999, 1);
37+
} catch (Throwable $e) {
38+
echo $e->getMessage(), "\n";
39+
}
40+
41+
try {
42+
$cal->setDateTime(1, 1, 1, 1, 1, 99999999999);
43+
} catch (Throwable $e) {
44+
echo $e->getMessage(), "\n";
45+
}
46+
?>
47+
--EXPECT--
48+
IntlCalendar::setDateTime(): Argument #1 ($year) must be between -2147483648 and 2147483647
49+
IntlCalendar::setDateTime(): Argument #2 ($month) must be between -2147483648 and 2147483647
50+
IntlCalendar::setDateTime(): Argument #3 ($dayOfMonth) must be between -2147483648 and 2147483647
51+
IntlCalendar::setDateTime(): Argument #4 ($hour) must be between -2147483648 and 2147483647
52+
IntlCalendar::setDateTime(): Argument #5 ($minute) must be between -2147483648 and 2147483647
53+
IntlCalendar::setDateTime(): Argument #6 ($second) must be between -2147483648 and 2147483647
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
--TEST--
2+
IntlCalendar::set(): out-of-bounds date/time arguments report correct positions
3+
--EXTENSIONS--
4+
intl
5+
--SKIPIF--
6+
<?php if (PHP_INT_SIZE != 8) die("skip: 64-bit only"); ?>
7+
--FILE--
8+
<?php
9+
$cal = IntlCalendar::createInstance();
10+
11+
try {
12+
$cal->set(99999999999, 1, 1);
13+
} catch (Throwable $e) {
14+
echo $e->getMessage(), "\n";
15+
}
16+
17+
try {
18+
intlcal_set($cal, 1, 99999999999, 1);
19+
} catch (Throwable $e) {
20+
echo $e->getMessage(), "\n";
21+
}
22+
23+
try {
24+
$cal->set(1, 1, 1, 99999999999, 1);
25+
} catch (Throwable $e) {
26+
echo $e->getMessage(), "\n";
27+
}
28+
29+
try {
30+
$cal->set(1, 1, 1, 1, 99999999999, 1);
31+
} catch (Throwable $e) {
32+
echo $e->getMessage(), "\n";
33+
}
34+
35+
try {
36+
intlcal_set($cal, 1, 1, 1, 1, 1, 99999999999);
37+
} catch (Throwable $e) {
38+
echo $e->getMessage(), "\n";
39+
}
40+
?>
41+
--EXPECTF--
42+
Deprecated: Calling IntlCalendar::set() with more than 2 arguments is deprecated, use either IntlCalendar::setDate() or IntlCalendar::setDateTime() instead in %s on line %d
43+
IntlCalendar::set(): Argument #1 ($year) must be between -2147483648 and 2147483647
44+
45+
Deprecated: Function intlcal_set() is deprecated since 8.4, use IntlCalendar::set(), IntlCalendar::setDate(), or IntlCalendar::setDateTime() instead in %s on line %d
46+
intlcal_set(): Argument #3 ($month) must be between -2147483648 and 2147483647
47+
48+
Deprecated: Calling IntlCalendar::set() with more than 2 arguments is deprecated, use either IntlCalendar::setDate() or IntlCalendar::setDateTime() instead in %s on line %d
49+
IntlCalendar::set(): Argument #4 ($hour) must be between -2147483648 and 2147483647
50+
51+
Deprecated: Calling IntlCalendar::set() with more than 2 arguments is deprecated, use either IntlCalendar::setDate() or IntlCalendar::setDateTime() instead in %s on line %d
52+
IntlCalendar::set(): Argument #5 ($minute) must be between -2147483648 and 2147483647
53+
54+
Deprecated: Function intlcal_set() is deprecated since 8.4, use IntlCalendar::set(), IntlCalendar::setDate(), or IntlCalendar::setDateTime() instead in %s on line %d
55+
intlcal_set(): Argument #7 ($second) must be between -2147483648 and 2147483647
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
--TEST--
2+
IntlGregorianCalendar::__construct(): out-of-bounds date/time arguments report correct positions
3+
--EXTENSIONS--
4+
intl
5+
--SKIPIF--
6+
<?php if (PHP_INT_SIZE != 8) die("skip: 64-bit only"); ?>
7+
--FILE--
8+
<?php
9+
try {
10+
new IntlGregorianCalendar(99999999999, 1, 1);
11+
} catch (Throwable $e) {
12+
echo $e->getMessage(), "\n";
13+
}
14+
15+
try {
16+
intlgregcal_create_instance(1, 99999999999, 1);
17+
} catch (Throwable $e) {
18+
echo $e->getMessage(), "\n";
19+
}
20+
21+
try {
22+
new IntlGregorianCalendar(1, 1, 1, 99999999999, 1);
23+
} catch (Throwable $e) {
24+
echo $e->getMessage(), "\n";
25+
}
26+
27+
try {
28+
new IntlGregorianCalendar(1, 1, 1, 1, 99999999999);
29+
} catch (Throwable $e) {
30+
echo $e->getMessage(), "\n";
31+
}
32+
33+
try {
34+
intlgregcal_create_instance(1, 1, 1, 1, 1, 99999999999);
35+
} catch (Throwable $e) {
36+
echo $e->getMessage(), "\n";
37+
}
38+
?>
39+
--EXPECTF--
40+
Deprecated: Calling IntlGregorianCalendar::__construct() with more than 2 arguments is deprecated, use either IntlGregorianCalendar::createFromDate() or IntlGregorianCalendar::createFromDateTime() instead in %s on line %d
41+
IntlGregorianCalendar::__construct(): Argument #1 ($timezoneOrYear) must be between -2147483648 and 2147483647
42+
43+
Deprecated: Function intlgregcal_create_instance() is deprecated since 8.4, use IntlGregorianCalendar::__construct(), IntlGregorianCalendar::createFromDate(), or IntlGregorianCalendar::createFromDateTime() instead in %s on line %d
44+
intlgregcal_create_instance(): Argument #2 ($localeOrMonth) must be between -2147483648 and 2147483647
45+
46+
Deprecated: Calling IntlGregorianCalendar::__construct() with more than 2 arguments is deprecated, use either IntlGregorianCalendar::createFromDate() or IntlGregorianCalendar::createFromDateTime() instead in %s on line %d
47+
IntlGregorianCalendar::__construct(): Argument #4 ($hour) must be between -2147483648 and 2147483647
48+
49+
Deprecated: Calling IntlGregorianCalendar::__construct() with more than 2 arguments is deprecated, use either IntlGregorianCalendar::createFromDate() or IntlGregorianCalendar::createFromDateTime() instead in %s on line %d
50+
IntlGregorianCalendar::__construct(): Argument #5 ($minute) must be between -2147483648 and 2147483647
51+
52+
Deprecated: Function intlgregcal_create_instance() is deprecated since 8.4, use IntlGregorianCalendar::__construct(), IntlGregorianCalendar::createFromDate(), or IntlGregorianCalendar::createFromDateTime() instead in %s on line %d
53+
intlgregcal_create_instance(): Argument #6 ($second) must be between -2147483648 and 2147483647

0 commit comments

Comments
 (0)