From b2cea917324cbd0a0d3d24dd3086a4804c63b90c Mon Sep 17 00:00:00 2001 From: David Carlier Date: Sat, 5 Oct 2024 07:43:30 +0100 Subject: [PATCH 1/2] Fix GH-16228 overflow on easter_days/easter_date year argument. --- ext/calendar/easter.c | 5 +++++ ext/calendar/tests/gh16228.phpt | 26 ++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 ext/calendar/tests/gh16228.phpt diff --git a/ext/calendar/easter.c b/ext/calendar/easter.c index c319abd17fef..0592ec087051 100644 --- a/ext/calendar/easter.c +++ b/ext/calendar/easter.c @@ -48,6 +48,11 @@ static void _cal_easter(INTERNAL_FUNCTION_PARAMETERS, bool gm) } } + if (year < 0 || year > (ZEND_LONG_MAX - 1)) { + zend_argument_value_error(1, "must be between 0 and " ZEND_LONG_FMT, (ZEND_LONG_MAX - 1)); + RETURN_THROWS(); + } + if (gm && (year<1970 || year>2037)) { /* out of range for timestamps */ zend_argument_value_error(1, "must be between 1970 and 2037 (inclusive)"); RETURN_THROWS(); diff --git a/ext/calendar/tests/gh16228.phpt b/ext/calendar/tests/gh16228.phpt new file mode 100644 index 000000000000..d018f4b2dd50 --- /dev/null +++ b/ext/calendar/tests/gh16228.phpt @@ -0,0 +1,26 @@ +--TEST-- +GH-16228 (easter_days, Overflow on year argument) +--EXTENSIONS-- +calendar +--FILE-- +getMessage() . PHP_EOL; +} +try { + easter_days(-1, 0); +} catch (\ValueError $e) { + echo $e->getMessage() . PHP_EOL; +} +try { + easter_date(PHP_INT_MAX, 0); +} catch (\ValueError $e) { + echo $e->getMessage() . PHP_EOL; +} +?> +--EXPECTF-- +easter_days(): Argument #1 ($year) must be between 0 and %d +easter_days(): Argument #1 ($year) must be between 0 and %d +easter_date(): Argument #1 ($year) must be between 0 and %d From 81acd543c8ed5576adf7c2fc026b255a25428ef1 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Sat, 5 Oct 2024 10:34:42 +0100 Subject: [PATCH 2/2] changes from feedback --- ext/calendar/easter.c | 5 +++-- ext/calendar/tests/gh16228.phpt | 6 +++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/ext/calendar/easter.c b/ext/calendar/easter.c index 0592ec087051..2832d0bdefe0 100644 --- a/ext/calendar/easter.c +++ b/ext/calendar/easter.c @@ -28,6 +28,7 @@ static void _cal_easter(INTERNAL_FUNCTION_PARAMETERS, bool gm) struct tm te; zend_long year, golden, solar, lunar, pfm, dom, tmp, easter, result; zend_long method = CAL_EASTER_DEFAULT; + const zend_long max_year = ZEND_LONG_MAX / 1.25; bool year_is_null = 1; if (zend_parse_parameters(ZEND_NUM_ARGS(), @@ -48,8 +49,8 @@ static void _cal_easter(INTERNAL_FUNCTION_PARAMETERS, bool gm) } } - if (year < 0 || year > (ZEND_LONG_MAX - 1)) { - zend_argument_value_error(1, "must be between 0 and " ZEND_LONG_FMT, (ZEND_LONG_MAX - 1)); + if (year <= 0 || year > max_year) { + zend_argument_value_error(1, "must be between 1 and " ZEND_LONG_FMT, max_year); RETURN_THROWS(); } diff --git a/ext/calendar/tests/gh16228.phpt b/ext/calendar/tests/gh16228.phpt index d018f4b2dd50..9ce80688195b 100644 --- a/ext/calendar/tests/gh16228.phpt +++ b/ext/calendar/tests/gh16228.phpt @@ -21,6 +21,6 @@ try { } ?> --EXPECTF-- -easter_days(): Argument #1 ($year) must be between 0 and %d -easter_days(): Argument #1 ($year) must be between 0 and %d -easter_date(): Argument #1 ($year) must be between 0 and %d +easter_days(): Argument #1 ($year) must be between 1 and %d +easter_days(): Argument #1 ($year) must be between 1 and %d +easter_date(): Argument #1 ($year) must be between 1 and %d