From 8d278496fb9e2ed2ad5659af860240f0584e1d2e Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sat, 19 Sep 2026 00:46:06 +0200 Subject: [PATCH 1/3] fix(Debug): treat zero time as valid timer start --- system/Debug/Timer.php | 2 +- tests/system/Debug/TimerTest.php | 10 ++++++++++ user_guide_src/source/changelogs/v4.7.5.rst | 1 + 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/system/Debug/Timer.php b/system/Debug/Timer.php index 9b6af4d4bcd0..4c383a743413 100644 --- a/system/Debug/Timer.php +++ b/system/Debug/Timer.php @@ -46,7 +46,7 @@ class Timer public function start(string $name, ?float $time = null) { $this->timers[strtolower($name)] = [ - 'start' => $time === null || $time === 0.0 ? microtime(true) : $time, + 'start' => $time ?? microtime(true), 'end' => null, ]; diff --git a/tests/system/Debug/TimerTest.php b/tests/system/Debug/TimerTest.php index 0f28e7dba69b..8d1750adbf99 100644 --- a/tests/system/Debug/TimerTest.php +++ b/tests/system/Debug/TimerTest.php @@ -86,6 +86,16 @@ public function testElapsedTimeGivesSameResultAsTimersArray(): void $this->assertSame($expected, $timer->getElapsedTime('test1')); } + public function testStartWithZeroTime(): void + { + $timer = new Timer(); + $timer->start('test1', 0.0); + + $timers = $timer->getTimers(); + + $this->assertSame(0.0, $timers['test1']['start']); + } + public function testThrowsExceptionStoppingNonTimer(): void { $this->expectException('RunTimeException'); diff --git a/user_guide_src/source/changelogs/v4.7.5.rst b/user_guide_src/source/changelogs/v4.7.5.rst index 83e0bf47742a..c01bb5cca6d6 100644 --- a/user_guide_src/source/changelogs/v4.7.5.rst +++ b/user_guide_src/source/changelogs/v4.7.5.rst @@ -58,6 +58,7 @@ Bugs Fixed - **I18n:** Fixed a bug where ``Time::today()``, ``Time::yesterday()``, and ``Time::tomorrow()`` ignored the specified ``$timezone`` and ``setTestNow()`` when calculating the day. - **Logger:** Fixed a bug where interpolating a log message with array or non-stringable context values could raise PHP warnings or errors. - **Cache:** Fixed ``MemcachedHandler::decrement()`` initializing a non-existent counter to the positive offset. Missing counters are now initialized to ``0``, reflecting Memcached's unsigned, saturating counter semantics. +- **Debug:** Fixed a bug where ``Timer::start()`` treated ``0.0`` as an empty value and substituted the current time. See the repo's `CHANGELOG.md `_ From dbbdba821a0ee1277cad26577a350c31073c42b7 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sat, 19 Sep 2026 01:00:11 +0200 Subject: [PATCH 2/3] test: use assertEqualsWithDelta for timer start value in TimerTest --- tests/system/Debug/TimerTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/system/Debug/TimerTest.php b/tests/system/Debug/TimerTest.php index 8d1750adbf99..8ec9a3602c2b 100644 --- a/tests/system/Debug/TimerTest.php +++ b/tests/system/Debug/TimerTest.php @@ -93,7 +93,7 @@ public function testStartWithZeroTime(): void $timers = $timer->getTimers(); - $this->assertSame(0.0, $timers['test1']['start']); + $this->assertEqualsWithDelta(0.0, $timers['test1']['start'], PHP_FLOAT_EPSILON); } public function testThrowsExceptionStoppingNonTimer(): void From 6413f1e18ab6cd2320e7f4056ca22c8735ac4a60 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 20 Sep 2026 02:14:53 +0200 Subject: [PATCH 3/3] docs: sort v4.7.5 changelog alphabetically --- user_guide_src/source/changelogs/v4.7.5.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/user_guide_src/source/changelogs/v4.7.5.rst b/user_guide_src/source/changelogs/v4.7.5.rst index c01bb5cca6d6..5fc0cfce5578 100644 --- a/user_guide_src/source/changelogs/v4.7.5.rst +++ b/user_guide_src/source/changelogs/v4.7.5.rst @@ -19,9 +19,9 @@ Message Changes *************** - Added the ``CLI.generator.undefinedDatabaseGroup`` and ``CLI.generator.unsupportedSessionDriver`` language strings. -- Added the ``Cookie.invalidCookieValue`` language string. -- Added the ``Cookie.invalidCookiePath`` language string. - Added the ``Cookie.invalidCookieDomain`` language string. +- Added the ``Cookie.invalidCookiePath`` language string. +- Added the ``Cookie.invalidCookieValue`` language string. ******* Changes @@ -41,6 +41,7 @@ Bugs Fixed - **Autoloader:** Fixed a bug where ``FileLocatorCached::deleteCache()`` left the deleted data in memory, so it could be written back to the cache file on shutdown. ``spark optimize`` and ``spark cache:clear`` now clear the shared locator's cache instead of a separate instance. - **BaseModel:** Fixed a bug where auto-generated ``created_at``/``updated_at`` timestamps always rendered ``.000000`` for a ``'datetime'`` ``$dateFormat`` whose connection ``dateFormat`` mask includes ``.v``/``.u``, instead of the real sub-second value. +- **Cache:** Fixed ``MemcachedHandler::decrement()`` initializing a non-existent counter to the positive offset. Missing counters are now initialized to ``0``, reflecting Memcached's unsigned, saturating counter semantics. - **CLI:** Fixed a bug where pressing backspace in a ``CLI::prompt()`` erased the prompt text when the ``readline`` extension is enabled. The prompt is now passed to ``readline()`` so line redraws repaint it. ANSI color codes in the prompt (e.g., option defaults) are wrapped in readline's non-printing markers under GNU readline so cursor positioning stays accurate. On Windows, where the ``readline`` extension is built on WinEditLine, the prompt is written to STDOUT first because WinEditLine reports no library version and prints ANSI sequences literally. @@ -52,13 +53,12 @@ Bugs Fixed - **Cookie:** Fixed a bug where ``Cookie`` instances created with ``raw: true`` allowed invalid characters in cookie values rejected by ``setrawcookie()``. - **Cookie:** Fixed a bug where ``Cookie`` instances allowed invalid characters in path, domain, and prefix attributes rejected by ``setcookie()`` and ``setrawcookie()``. - **Database:** Fixed a bug where rebuilding a SQLite3 table (e.g., ``Forge::dropColumn()``, ``Forge::modifyColumn()``, ``Forge::dropForeignKey()`` and ``Forge::dropPrimaryKey()``) corrupted the table names referenced by its foreign keys when ``DBPrefix`` was set. +- **Debug:** Fixed a bug where ``Timer::start()`` treated ``0.0`` as an empty value and substituted the current time. - **Files:** Fixed a bug where ``File::move()`` and ``UploadedFile::move()`` set executable and overly permissive file permissions (``0777 & ~umask()`` instead of ``0666 & ~umask()``), and ``UploadedFile::move()`` targeted the parent directory instead of the destination file for ``chmod()``. - **Helpers:** Fixed a bug where ``get_dir_file_info()`` returned incomplete entries for subdirectories and missing files instead of omitting them. - **Honeypot:** Fixed a bug where bot detection returned an HTTP 500 response instead of 403 (Forbidden). - **I18n:** Fixed a bug where ``Time::today()``, ``Time::yesterday()``, and ``Time::tomorrow()`` ignored the specified ``$timezone`` and ``setTestNow()`` when calculating the day. - **Logger:** Fixed a bug where interpolating a log message with array or non-stringable context values could raise PHP warnings or errors. -- **Cache:** Fixed ``MemcachedHandler::decrement()`` initializing a non-existent counter to the positive offset. Missing counters are now initialized to ``0``, reflecting Memcached's unsigned, saturating counter semantics. -- **Debug:** Fixed a bug where ``Timer::start()`` treated ``0.0`` as an empty value and substituted the current time. See the repo's `CHANGELOG.md `_