Skip to content

Commit dcbdd5c

Browse files
committed
Fix easter_date() beyond the year 3000 on Windows
mktime() on Windows only goes up to the year 3000 and returns -1 beyond that, so easter_date() returned -1 instead of throwing for the years 3001 to 2000000000. Limit the year to 3000 on Windows.
1 parent d711a7e commit dcbdd5c

5 files changed

Lines changed: 44 additions & 3 deletions

File tree

‎NEWS‎

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

5+
- Calendar:
6+
. Fixed bug GH-23915 (easter_date() reports inconsistent year ranges and
7+
returns -1 after the year 3000 on Windows). (Marc Bennewitz)
8+
59
- CLI
610
. Fix GH-22567 (Windows ZTS CLI SAPI should refresh its TSRMLS cache during
711
request activation). (matyhtf)

‎ext/calendar/easter.c‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,13 @@ static void _cal_easter(INTERNAL_FUNCTION_PARAMETERS, bool gm)
4040
/* Timestamps only start after 1970 and are calculated by mktime() */
4141
min_year = 1970;
4242
#ifdef ZEND_ENABLE_ZVAL_LONG64
43+
# ifdef PHP_WIN32
44+
/* mktime() on Windows only goes up to the year 3000 */
45+
max_year = 3000;
46+
# else
4347
/* Timestamps only go up to the year 2.000.000.000 */
4448
max_year = 2000000000;
49+
# endif
4550
#else
4651
max_year = 2037;
4752
#endif

‎ext/calendar/tests/easter_date_64bit.phpt‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,11 @@ try {
2323
echo "{$ex->getMessage()}\n";
2424
}
2525
?>
26-
--EXPECT--
26+
--EXPECTF--
2727
2000-04-23
2828
2001-04-15
2929
2002-03-31
3030
2045-04-09
3131
2046-03-25
3232
2047-04-14
33-
easter_date(): Argument #1 ($year) must be between 1970 and 2000000000
33+
easter_date(): Argument #1 ($year) must be between 1970 and %d

‎ext/calendar/tests/easter_date_checks_upper_bound_64bit.phpt‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
--TEST--
22
Test easter_date() on 64bit systems checks the upper year limit
33
--SKIPIF--
4-
<?php if (PHP_INT_SIZE != 8) die("skip 64-bit only"); ?>
4+
<?php
5+
if (PHP_INT_SIZE != 8) die("skip 64-bit only");
6+
if (PHP_OS_FAMILY === "Windows") die("skip not for Windows, see gh23915_windows.phpt");
7+
?>
58
--INI--
69
date.timezone=UTC
710
--ENV--
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
--TEST--
2+
GH-23915 (easter_date() reports inconsistent year ranges in errors and returns -1 for years after 3000 on Windows)
3+
--SKIPIF--
4+
<?php
5+
if (PHP_INT_SIZE != 8) die("skip 64-bit only");
6+
if (PHP_OS_FAMILY !== "Windows") die("skip Windows only");
7+
?>
8+
--INI--
9+
date.timezone=UTC
10+
--ENV--
11+
TZ=UTC
12+
--EXTENSIONS--
13+
calendar
14+
--FILE--
15+
<?php
16+
putenv('TZ=UTC');
17+
// mktime() on Windows only goes up to the year 3000
18+
foreach ([3000, 3001, 293274701009] as $year) {
19+
try {
20+
echo date('Y-m-d', easter_date($year)), "\n";
21+
} catch (ValueError $ex) {
22+
echo "{$ex->getMessage()}\n";
23+
}
24+
}
25+
?>
26+
--EXPECT--
27+
3000-04-13
28+
easter_date(): Argument #1 ($year) must be between 1970 and 3000
29+
easter_date(): Argument #1 ($year) must be between 1970 and 3000

0 commit comments

Comments
 (0)