Allow easter_date to process years after 2037 on 64bit systems (#11862)

Added a check to easter_date to allow it to run with years past
2037 when on a 64bit platform.
This commit is contained in:
Arne_ 2023-08-04 17:47:04 +02:00 committed by GitHub
parent e5b2590041
commit 8ef0e4cfa0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 105 additions and 2 deletions

View File

@ -317,6 +317,10 @@ PHP 8.3 UPGRADE NOTES
significant digits before the decimal point. Previously negative $decimals
got silently ignored and the number got rounded to zero decimal places.
- Calendar
. easter_date() now supports years from 1970 to 2,000,000,000 on 64-bit systems,
previously it only supported years in the range from 1970 to 2037.
========================================
6. New Functions
========================================

View File

@ -13,6 +13,7 @@
| Authors: Shane Caraveo <shane@caraveo.com> |
| Colin Viebrock <colin@easydns.com> |
| Hartmut Holzgraefe <hholzgra@php.net> |
| Arne Perschke <a.perschke@hctec.net> |
+----------------------------------------------------------------------+
*/
@ -21,6 +22,10 @@
#include "sdncal.h"
#include <time.h>
/**
* If `gm` is true this will return the timestamp at midnight on Easter of the given year. If it is false this
* will return the number of days Easter is after March 21st.
*/
static void _cal_easter(INTERNAL_FUNCTION_PARAMETERS, bool gm)
{
/* based on code by Simon Kershaw, <webmaster@ely.anglican.org> */
@ -48,10 +53,27 @@ static void _cal_easter(INTERNAL_FUNCTION_PARAMETERS, bool gm)
}
}
if (gm && (year<1970 || year>2037)) { /* out of range for timestamps */
#ifdef ZEND_ENABLE_ZVAL_LONG64
/* Compiling for 64bit, allow years between 1970 and 2.000.000.000 */
if (gm && year < 1970) {
/* timestamps only start after 1970 */
zend_argument_value_error(1, "must be a year after 1970 (inclusive)");
RETURN_THROWS();
}
if (gm && year > 2000000000) {
/* timestamps only go up to the year 2.000.000.000 */
zend_argument_value_error(1, "must be a year before 2.000.000.000 (inclusive)");
RETURN_THROWS();
}
#else
/* Compiling for 32bit, allow years between 1970 and 2037 */
if (gm && (year < 1970 || year > 2037)) {
zend_argument_value_error(1, "must be between 1970 and 2037 (inclusive)");
RETURN_THROWS();
}
#endif
golden = (year % 19) + 1; /* the Golden number */

View File

@ -1,5 +1,7 @@
--TEST--
easter_date()
Test easter_date() on 32bit systems
--SKIPIF--
<?php if (PHP_INT_SIZE != 4) die("skip 32-bit only"); ?>
--INI--
date.timezone=UTC
--ENV--

View File

@ -0,0 +1,33 @@
--TEST--
Test easter_date() on 64bit systems
--SKIPIF--
<?php if (PHP_INT_SIZE != 8) die("skip 64-bit only"); ?>
--INI--
date.timezone=UTC
--ENV--
TZ=UTC
--EXTENSIONS--
calendar
--FILE--
<?php
putenv('TZ=UTC');
echo date("Y-m-d", easter_date(2000))."\n";
echo date("Y-m-d", easter_date(2001))."\n";
echo date("Y-m-d", easter_date(2002))."\n";
echo date("Y-m-d", easter_date(2045))."\n";
echo date("Y-m-d", easter_date(2046))."\n";
echo date("Y-m-d", easter_date(2047))."\n";
try {
easter_date(1492);
} catch (ValueError $ex) {
echo "{$ex->getMessage()}\n";
}
?>
--EXPECT--
2000-04-23
2001-04-15
2002-03-31
2045-04-09
2046-03-25
2047-04-14
easter_date(): Argument #1 ($year) must be a year after 1970 (inclusive)

View File

@ -0,0 +1,21 @@
--TEST--
Test easter_date() on 32bit systems checks the upper year limit
--SKIPIF--
<?php if (PHP_INT_SIZE != 4) die("skip 32-bit only"); ?>
--INI--
date.timezone=UTC
--ENV--
TZ=UTC
--EXTENSIONS--
calendar
--FILE--
<?php
putenv('TZ=UTC');
try {
easter_date(2040);
} catch (ValueError $ex) {
echo "{$ex->getMessage()}\n";
}
?>
--EXPECT--
easter_date(): Argument #1 ($year) must be between 1970 and 2037 (inclusive)

View File

@ -0,0 +1,21 @@
--TEST--
Test easter_date() on 64bit systems checks the upper year limit
--SKIPIF--
<?php if (PHP_INT_SIZE != 8) die("skip 64-bit only"); ?>
--INI--
date.timezone=UTC
--ENV--
TZ=UTC
--EXTENSIONS--
calendar
--FILE--
<?php
putenv('TZ=UTC');
try {
easter_date(293274701009);
} catch (ValueError $ex) {
echo "{$ex->getMessage()}\n";
}
?>
--EXPECT--
easter_date(): Argument #1 ($year) must be a year before 2.000.000.000 (inclusive)