From f0f029c97fd048fb708ded0c47ea6404a0934a79 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. --- ext/standard/basic_functions.c | 6 ++++++ ext/standard/tests/misc/gh14774.phpt | 17 +++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 ext/standard/tests/misc/gh14774.phpt diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index b4a723a546818..e08063541cc32 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 uint64_t top_target_sec = 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((uint64_t)target_secs > top_target_sec)) { + zend_argument_value_error(1, "must be at most " ZEND_LONG_FMT, 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 0000000000000..6359b5d5c4b23 --- /dev/null +++ b/ext/standard/tests/misc/gh14774.phpt @@ -0,0 +1,17 @@ +--TEST-- +GH-14774 time_sleep_until overflow +--SKIPIF-- + +--FILE-- +getMessage(); +} +?> +--EXPECTF-- +time_sleep_until(): Argument #1 ($timestamp) must be at most %d