From 237518763f82d06286e6292fc0fed2f817514a8a Mon Sep 17 00:00:00 2001 From: David Carlier Date: Wed, 3 Jul 2024 22:07:38 +0100 Subject: [PATCH] Fix GH-14774 time_sleep_until overflow. --- NEWS | 1 + ext/standard/basic_functions.c | 6 ++++++ ext/standard/tests/misc/gh14774.phpt | 23 +++++++++++++++++++++++ 3 files changed, 30 insertions(+) create mode 100644 ext/standard/tests/misc/gh14774.phpt diff --git a/NEWS b/NEWS index d382469764c..f99079d04db 100644 --- a/NEWS +++ b/NEWS @@ -42,6 +42,7 @@ PHP NEWS - Standard: . Fix 32-bit wordwrap test failures. (orlitzky) + . Fixed bug GH-14774 (time_sleep_until overflow). (David Carlier) - Treewide: . Fix compatibility with libxml2 2.13.2. (nielsdos) diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index b4a723a5468..a368d0ac7f2 100755 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -1228,6 +1228,7 @@ PHP_FUNCTION(time_sleep_until) struct timespec php_req, php_rem; uint64_t current_ns, target_ns, diff_ns; const uint64_t ns_per_sec = 1000000000; + const double top_target_sec = (double)(UINT64_MAX / ns_per_sec); ZEND_PARSE_PARAMETERS_START(1, 1) Z_PARAM_DOUBLE(target_secs) @@ -1237,6 +1238,11 @@ PHP_FUNCTION(time_sleep_until) RETURN_FALSE; } + if (UNEXPECTED(!(target_secs >= 0 && target_secs <= top_target_sec))) { + zend_argument_value_error(1, "must be between 0 and %" PRIu64, (uint64_t)top_target_sec); + RETURN_THROWS(); + } + target_ns = (uint64_t) (target_secs * ns_per_sec); current_ns = ((uint64_t) tm.tv_sec) * ns_per_sec + ((uint64_t) tm.tv_usec) * 1000; if (target_ns < current_ns) { diff --git a/ext/standard/tests/misc/gh14774.phpt b/ext/standard/tests/misc/gh14774.phpt new file mode 100644 index 00000000000..1f9cd921e03 --- /dev/null +++ b/ext/standard/tests/misc/gh14774.phpt @@ -0,0 +1,23 @@ +--TEST-- +GH-14774 time_sleep_until overflow +--SKIPIF-- + +--FILE-- +getMessage() . PHP_EOL; + } +} +?> +--EXPECTF-- +time_sleep_until(): Argument #1 ($timestamp) must be between 0 and %d +time_sleep_until(): Argument #1 ($timestamp) must be between 0 and %d +time_sleep_until(): Argument #1 ($timestamp) must be between 0 and %d +time_sleep_until(): Argument #1 ($timestamp) must be between 0 and %d +time_sleep_until(): Argument #1 ($timestamp) must be between 0 and %d +time_sleep_until(): Argument #1 ($timestamp) must be between 0 and %d