diff --git a/system/HTTP/UserAgent.php b/system/HTTP/UserAgent.php index ba9e544ae2f8..fe7679e59384 100644 --- a/system/HTTP/UserAgent.php +++ b/system/HTTP/UserAgent.php @@ -317,8 +317,15 @@ protected function setBrowser(): bool if (is_array($this->config->browsers) && $this->config->browsers !== []) { foreach ($this->config->browsers as $key => $val) { if (preg_match('|' . $key . '.*?([0-9\.]+)|i', $this->agent, $match)) { + $version = $match[1]; + + // Safari's browser version is reported in the Version token. + if ($val === 'Safari' && preg_match('|Version/([0-9\.]+).*?Safari|i', $this->agent, $safariMatch)) { + $version = $safariMatch[1]; + } + $this->isBrowser = true; - $this->version = $match[1]; + $this->version = $version; $this->browser = $val; $this->setMobile(); diff --git a/tests/system/HTTP/UserAgentTest.php b/tests/system/HTTP/UserAgentTest.php index c43c46354e87..b19e0c62dee5 100644 --- a/tests/system/HTTP/UserAgentTest.php +++ b/tests/system/HTTP/UserAgentTest.php @@ -74,10 +74,38 @@ public function testBrowserInfo(): void { $this->assertSame('Mac OS X', $this->agent->getPlatform()); $this->assertSame('Safari', $this->agent->getBrowser()); - $this->assertSame('533.20.27', $this->agent->getVersion()); + $this->assertSame('5.0.4', $this->agent->getVersion()); $this->assertSame('', $this->agent->getRobot()); } + public function testParseModernSafariUsesVersionToken(): void + { + $this->agent->parse('Mozilla/5.0 (Macintosh; Intel Mac OS X 13_2) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.3 Safari/605.1.15'); + + $this->assertSame('Mac OS X', $this->agent->getPlatform()); + $this->assertSame('Safari', $this->agent->getBrowser()); + $this->assertSame('16.3', $this->agent->getVersion()); + } + + public function testParseMobileSafariUsesVersionToken(): void + { + $this->agent->parse($this->_mobile_ua); + + $this->assertSame('iOS', $this->agent->getPlatform()); + $this->assertSame('Safari', $this->agent->getBrowser()); + $this->assertSame('4.0.5', $this->agent->getVersion()); + $this->assertSame('Apple iPhone', $this->agent->getMobile()); + } + + public function testParseChromeWithSafariTokenUsesChromeVersion(): void + { + $this->agent->parse('Mozilla/5.0 (Macintosh; Intel Mac OS X 13_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36'); + + $this->assertSame('Mac OS X', $this->agent->getPlatform()); + $this->assertSame('Chrome', $this->agent->getBrowser()); + $this->assertSame('110.0.0.0', $this->agent->getVersion()); + } + public function testParse(): void { $newAgent = 'Mozilla/5.0 (Android; Mobile; rv:13.0) Gecko/13.0 Firefox/13.0'; diff --git a/user_guide_src/source/changelogs/v4.7.4.rst b/user_guide_src/source/changelogs/v4.7.4.rst index 244823a000f7..daf64bbda631 100644 --- a/user_guide_src/source/changelogs/v4.7.4.rst +++ b/user_guide_src/source/changelogs/v4.7.4.rst @@ -31,6 +31,7 @@ Bugs Fixed ********** - **Database:** Fixed a bug where ``updateBatch()`` could be called after Query Builder ``where()`` conditions, even though it's not supported. In this situation, now the ``DatabaseException`` is thrown. +- **HTTP:** Fixed a bug where the User Agent library reported Safari's WebKit version instead of the browser version from the ``Version`` token. See the repo's `CHANGELOG.md `_