From f9453a889d379cd4b4a3370a5ed9d5b741dde1d8 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Fri, 18 Oct 2024 17:46:40 +0200 Subject: [PATCH] Fix GH-14732: date_sun_info() fails for non-finite values `timelib_astro_rise_set_altitude()` is not prepared to deal with non- finite values (`nan`, `inf` and `-inf`) for `lon` and `lat`; instead these trigger undefined behavior. Thus we catch non-finite values before even calling that timelib function; for `date_sun_info()` we trigger `ValueError`s; for `date_sunrise()` and `date_sunset()` we silently return `false`, since these functions will be sunsetted anyway. Closes GH-16497. --- NEWS | 1 + ext/date/php_date.c | 13 +++++++++++++ ext/date/tests/gh14732.phpt | 38 +++++++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+) create mode 100644 ext/date/tests/gh14732.phpt diff --git a/NEWS b/NEWS index 069d88817d4..d2369c2e6e3 100644 --- a/NEWS +++ b/NEWS @@ -28,6 +28,7 @@ PHP NEWS . Fixed bug GH-16454 (Unhandled INF in date_sunset() with tiny $utcOffset). (cmb) . Fixed bug GH-16037 (Assertion failure in ext/date/php_date.c). (Derick) + . Fixed bug GH-14732 (date_sun_info() fails for non-finite values). (cmb) - DBA: . Fixed bug GH-16390 (dba_open() can segfault for "pathless" streams). (cmb) diff --git a/ext/date/php_date.c b/ext/date/php_date.c index 92ac3c630b0..9108a7c246a 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -5111,6 +5111,10 @@ static void php_do_date_sunrise_sunset(INTERNAL_FUNCTION_PARAMETERS, bool calc_s } altitude = 90 - zenith; + if (!zend_finite(latitude) || !zend_finite(longitude)) { + RETURN_FALSE; + } + /* Initialize time struct */ tzi = get_timezone_info(); if (!tzi) { @@ -5188,6 +5192,15 @@ PHP_FUNCTION(date_sun_info) Z_PARAM_DOUBLE(longitude) ZEND_PARSE_PARAMETERS_END(); + if (!zend_finite(latitude)) { + zend_argument_value_error(2, "must be finite"); + RETURN_THROWS(); + } + if (!zend_finite(longitude)) { + zend_argument_value_error(3, "must be finite"); + RETURN_THROWS(); + } + /* Initialize time struct */ tzi = get_timezone_info(); if (!tzi) { diff --git a/ext/date/tests/gh14732.phpt b/ext/date/tests/gh14732.phpt new file mode 100644 index 00000000000..a41d2885dd5 --- /dev/null +++ b/ext/date/tests/gh14732.phpt @@ -0,0 +1,38 @@ +--TEST-- +GH-14732 (date_sun_info() fails for non-finite values) +--FILE-- +getMessage(), "\n"; +} +try { + date_sun_info(1, -INF, 1); +} catch (ValueError $ex) { + echo $ex->getMessage(), "\n"; +} +try { + date_sun_info(1, 1, NAN); +} catch (ValueError $ex) { + echo $ex->getMessage(), "\n"; +} +try { + date_sun_info(1, 1, INF); +} catch (ValueError $ex) { + echo $ex->getMessage(), "\n"; +} +var_dump(date_sunset(1, SUNFUNCS_RET_STRING, NAN, 1)); +var_dump(date_sunrise(1, SUNFUNCS_RET_STRING, 1, NAN)); +?> +--EXPECTF-- +date_sun_info(): Argument #2 ($latitude) must be finite +date_sun_info(): Argument #2 ($latitude) must be finite +date_sun_info(): Argument #3 ($longitude) must be finite +date_sun_info(): Argument #3 ($longitude) must be finite + +Deprecated: Function date_sunset() is deprecated in %s on line %d +bool(false) + +Deprecated: Function date_sunrise() is deprecated in %s on line %d +bool(false)