Skip to content

Commit 456301e

Browse files
committed
Allow easter_date to process years after 2037 on 64bit systems
Added a check to easter_date to allow it to run with years past 2037 when on a 64bit platform.
1 parent 66b359e commit 456301e

5 files changed

+99
-2
lines changed

ext/calendar/easter.c

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
| Authors: Shane Caraveo <[email protected]> |
1414
| Colin Viebrock <[email protected]> |
1515
| Hartmut Holzgraefe <[email protected]> |
16+
| Arne Perschke <[email protected]> |
1617
+----------------------------------------------------------------------+
1718
*/
1819

@@ -21,6 +22,10 @@
2122
#include "sdncal.h"
2223
#include <time.h>
2324

25+
/**
26+
* If `gm` is true this will return the timestamp at midnight on Easter of the given year. If it is false this
27+
* will return the number of days Easter is after March 21st.
28+
*/
2429
static void _cal_easter(INTERNAL_FUNCTION_PARAMETERS, bool gm)
2530
{
2631
/* based on code by Simon Kershaw, <[email protected]> */
@@ -48,10 +53,25 @@ static void _cal_easter(INTERNAL_FUNCTION_PARAMETERS, bool gm)
4853
}
4954
}
5055

51-
if (gm && (year<1970 || year>2037)) { /* out of range for timestamps */
56+
#ifdef ZEND_ENABLE_ZVAL_LONG64
57+
/* Compiling for 64bit, allow years between 1970 and 2.000.000.000 */
58+
if (gm && year<1970) { /* timestamps only start after 1970 */
59+
zend_argument_value_error(1, "must be a year after 1970 (inclusive)");
60+
RETURN_THROWS();
61+
}
62+
63+
if (gm && year>2000000000) { /* timestamps only go up to the year 2.000.000.000 */
64+
zend_argument_value_error(1, "must be a year before 2.000.000.000 (inclusive)");
65+
RETURN_THROWS();
66+
}
67+
#else
68+
/* Compiling for 32bit, allow years between 1970 and 2037 */
69+
if (gm && (year<1970 || year>2037)) { /* out of range for timestamps on 32bit systems */
5270
zend_argument_value_error(1, "must be between 1970 and 2037 (inclusive)");
5371
RETURN_THROWS();
5472
}
73+
#endif
74+
5575

5676
golden = (year % 19) + 1; /* the Golden number */
5777

ext/calendar/tests/easter_date.phpt renamed to ext/calendar/tests/easter_date_32bit.phpt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
--TEST--
2-
easter_date()
2+
Test easter_date() on 32bit systems
3+
--SKIPIF--
4+
<?php if (PHP_INT_SIZE != 4) die("skip 32-bit only"); ?>
35
--INI--
46
date.timezone=UTC
57
--ENV--
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
--TEST--
2+
Test easter_date() on 64bit systems
3+
--SKIPIF--
4+
<?php if (PHP_INT_SIZE != 8) die("skip 64-bit only"); ?>
5+
--INI--
6+
date.timezone=UTC
7+
--ENV--
8+
TZ=UTC
9+
--EXTENSIONS--
10+
calendar
11+
--FILE--
12+
<?php
13+
putenv('TZ=UTC');
14+
echo date("Y-m-d", easter_date(2000))."\n";
15+
echo date("Y-m-d", easter_date(2001))."\n";
16+
echo date("Y-m-d", easter_date(2002))."\n";
17+
echo date("Y-m-d", easter_date(2045))."\n";
18+
echo date("Y-m-d", easter_date(2046))."\n";
19+
echo date("Y-m-d", easter_date(2047))."\n";
20+
try {
21+
easter_date(1492);
22+
} catch (ValueError $ex) {
23+
echo "{$ex->getMessage()}\n";
24+
}
25+
?>
26+
--EXPECT--
27+
2000-04-23
28+
2001-04-15
29+
2002-03-31
30+
2045-04-09
31+
2046-03-25
32+
2047-04-14
33+
easter_date(): Argument #1 ($year) must be a year after 1970 (inclusive)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
--TEST--
2+
Test easter_date() on 32bit systems checks the upper year limit
3+
--SKIPIF--
4+
<?php if (PHP_INT_SIZE != 4) die("skip 32-bit only"); ?>
5+
--INI--
6+
date.timezone=UTC
7+
--ENV--
8+
TZ=UTC
9+
--EXTENSIONS--
10+
calendar
11+
--FILE--
12+
<?php
13+
putenv('TZ=UTC');
14+
try {
15+
easter_date(2040);
16+
} catch (ValueError $ex) {
17+
echo "{$ex->getMessage()}\n";
18+
}
19+
?>
20+
--EXPECT--
21+
easter_date(): Argument #1 ($year) must be between 1970 and 2037 (inclusive)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
--TEST--
2+
Test easter_date() on 64bit systems checks the upper year limit
3+
--SKIPIF--
4+
<?php if (PHP_INT_SIZE != 8) die("skip 64-bit only"); ?>
5+
--INI--
6+
date.timezone=UTC
7+
--ENV--
8+
TZ=UTC
9+
--EXTENSIONS--
10+
calendar
11+
--FILE--
12+
<?php
13+
putenv('TZ=UTC');
14+
try {
15+
easter_date(293274701009);
16+
} catch (ValueError $ex) {
17+
echo "{$ex->getMessage()}\n";
18+
}
19+
?>
20+
--EXPECT--
21+
easter_date(): Argument #1 ($year) must be a year before 2.000.000.000 (inclusive)

0 commit comments

Comments
 (0)