Skip to content

Commit e668d6a

Browse files
committed
Fix IntlCalendar::setDate(), IntlCalendar::setDateTime()
1 parent a6338a0 commit e668d6a

5 files changed

Lines changed: 126 additions & 11 deletions

File tree

NEWS

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ PHP NEWS
44

55
- Intl:
66
. Fix incorrect argument positions in out-of-bounds errors for
7-
IntlCalendar::set() and IntlGregorianCalendar date/time construction.
8-
(Weilin Du)
7+
IntlCalendar::set(), IntlCalendar::setDate(), IntlCalendar::setDateTime(),
8+
and IntlGregorianCalendar date/time construction. (Weilin Du)
99

1010
- MySQLnd:
1111
. Fix persistent free of non-persistent connect_attr key (David Carlier).

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: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -427,9 +427,18 @@ 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+
if (UNEXPECTED(year < INT32_MIN || year > INT32_MAX)) {
431+
zend_argument_value_error(1, "must be between %d and %d", INT32_MIN, INT32_MAX);
432+
RETURN_THROWS();
433+
}
434+
if (UNEXPECTED(month < INT32_MIN || month > INT32_MAX)) {
435+
zend_argument_value_error(2, "must be between %d and %d", INT32_MIN, INT32_MAX);
436+
RETURN_THROWS();
437+
}
438+
if (UNEXPECTED(day < INT32_MIN || day > INT32_MAX)) {
439+
zend_argument_value_error(3, "must be between %d and %d", INT32_MIN, INT32_MAX);
440+
RETURN_THROWS();
441+
}
433442

434443
CALENDAR_METHOD_FETCH_OBJECT;
435444

@@ -450,18 +459,36 @@ U_CFUNC PHP_METHOD(IntlCalendar, setDateTime)
450459
RETURN_THROWS();
451460
}
452461

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);
462+
if (UNEXPECTED(year < INT32_MIN || year > INT32_MAX)) {
463+
zend_argument_value_error(1, "must be between %d and %d", INT32_MIN, INT32_MAX);
464+
RETURN_THROWS();
465+
}
466+
if (UNEXPECTED(month < INT32_MIN || month > INT32_MAX)) {
467+
zend_argument_value_error(2, "must be between %d and %d", INT32_MIN, INT32_MAX);
468+
RETURN_THROWS();
469+
}
470+
if (UNEXPECTED(day < INT32_MIN || day > INT32_MAX)) {
471+
zend_argument_value_error(3, "must be between %d and %d", INT32_MIN, INT32_MAX);
472+
RETURN_THROWS();
473+
}
474+
if (UNEXPECTED(hour < INT32_MIN || hour > INT32_MAX)) {
475+
zend_argument_value_error(4, "must be between %d and %d", INT32_MIN, INT32_MAX);
476+
RETURN_THROWS();
477+
}
478+
if (UNEXPECTED(minute < INT32_MIN || minute > INT32_MAX)) {
479+
zend_argument_value_error(5, "must be between %d and %d", INT32_MIN, INT32_MAX);
480+
RETURN_THROWS();
481+
}
458482

459483
CALENDAR_METHOD_FETCH_OBJECT;
460484

461485
if (second_is_null) {
462486
co->ucal->set((int32_t) year, (int32_t) month, (int32_t) day, (int32_t) hour, (int32_t) minute);
463487
} else {
464-
ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(second, 6);
488+
if (UNEXPECTED(second < INT32_MIN || second > INT32_MAX)) {
489+
zend_argument_value_error(6, "must be between %d and %d", INT32_MIN, INT32_MAX);
490+
RETURN_THROWS();
491+
}
465492
co->ucal->set((int32_t) year, (int32_t) month, (int32_t) day, (int32_t) hour, (int32_t) minute, (int32_t) second);
466493
}
467494
}
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

0 commit comments

Comments
 (0)