diff --git a/system/Email/Email.php b/system/Email/Email.php index 727419832c62..3e4cd5671a97 100644 --- a/system/Email/Email.php +++ b/system/Email/Email.php @@ -2142,12 +2142,16 @@ protected function getSMTPData() */ protected function getHostname() { - if (isset($_SERVER['SERVER_NAME'])) { - return $_SERVER['SERVER_NAME']; + $superglobals = service('superglobals'); + + $serverName = $superglobals->server('SERVER_NAME'); + if (! in_array($serverName, [null, ''], true)) { + return $serverName; } - if (isset($_SERVER['SERVER_ADDR'])) { - return '[' . $_SERVER['SERVER_ADDR'] . ']'; + $serverAddr = $superglobals->server('SERVER_ADDR'); + if (! in_array($serverAddr, [null, ''], true)) { + return '[' . $serverAddr . ']'; } $hostname = gethostname(); diff --git a/tests/system/Email/EmailTest.php b/tests/system/Email/EmailTest.php index ca26743c3ddc..63e82a0a72ba 100644 --- a/tests/system/Email/EmailTest.php +++ b/tests/system/Email/EmailTest.php @@ -16,9 +16,11 @@ use CodeIgniter\Events\Events; use CodeIgniter\Test\CIUnitTestCase; use CodeIgniter\Test\Mock\MockEmail; +use CodeIgniter\Test\ReflectionHelper; use ErrorException; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\Group; +use ReflectionException; /** * @internal @@ -26,6 +28,8 @@ #[Group('Others')] final class EmailTest extends CIUnitTestCase { + use ReflectionHelper; + public function testEmailValidation(): void { $config = config('Email'); @@ -215,4 +219,51 @@ public function testSetAttachmentCIDBufferString(): void $email->archive['body'], ); } + + /** + * @throws ReflectionException + */ + public function testGetHostnameUsesServerName(): void + { + $email = $this->createMockEmail(); + + $superglobals = service('superglobals'); + $superglobals->setServer('SERVER_NAME', 'example.test'); + + $getHostname = self::getPrivateMethodInvoker($email, 'getHostname'); + + $this->assertSame('example.test', $getHostname()); + } + + /** + * @throws ReflectionException + */ + public function testGetHostnameUsesServerAddr(): void + { + $email = $this->createMockEmail(); + + $superglobals = service('superglobals'); + $superglobals->setServer('SERVER_NAME', ''); + $superglobals->setServer('SERVER_ADDR', '192.168.1.10'); + + $getHostname = self::getPrivateMethodInvoker($email, 'getHostname'); + + $this->assertSame('[192.168.1.10]', $getHostname()); + } + + /** + * @throws ReflectionException + */ + public function testGetHostnameFallsBackToGethostnameFunction(): void + { + $email = $this->createMockEmail(); + + $superglobals = service('superglobals'); + $superglobals->setServer('SERVER_NAME', ''); + $superglobals->setServer('SERVER_ADDR', ''); + + $getHostname = self::getPrivateMethodInvoker($email, 'getHostname'); + + $this->assertSame(gethostname(), $getHostname()); + } } diff --git a/user_guide_src/source/changelogs/v4.6.2.rst b/user_guide_src/source/changelogs/v4.6.2.rst index 936c0e709046..676d1a731ee9 100644 --- a/user_guide_src/source/changelogs/v4.6.2.rst +++ b/user_guide_src/source/changelogs/v4.6.2.rst @@ -37,6 +37,7 @@ Bugs Fixed - **Cache:** Fixed a bug where a corrupted or unreadable cache file could cause an unhandled exception in ``FileHandler::getItem()``. - **Database:** Fixed a bug where ``when()`` and ``whenNot()`` in ``ConditionalTrait`` incorrectly evaluated certain falsy values (such as ``[]``, ``0``, ``0.0``, and ``'0'``) as truthy, causing callbacks to be executed unexpectedly. These methods now cast the condition to a boolean using ``(bool)`` to ensure consistent behavior with PHP's native truthiness. +- **Email:** Fixed a bug where ``Email::getHostname()`` failed to use ``$_SERVER['SERVER_ADDR']`` when ``$_SERVER['SERVER_NAME']`` was not set. - **Security:** Fixed a bug where the ``sanitize_filename()`` function from the Security helper would throw an error when used in CLI requests. - **Session:** Fixed a bug where using the ``DatabaseHandler`` with an unsupported database driver (such as ``SQLSRV``, ``OCI8``, or ``SQLite3``) did not throw an appropriate error. diff --git a/utils/phpstan-baseline/codeigniter.superglobalAccess.neon b/utils/phpstan-baseline/codeigniter.superglobalAccess.neon index a12ee94e1fff..893b1cd96c62 100644 --- a/utils/phpstan-baseline/codeigniter.superglobalAccess.neon +++ b/utils/phpstan-baseline/codeigniter.superglobalAccess.neon @@ -1,4 +1,4 @@ -# total 83 errors +# total 79 errors parameters: ignoreErrors: @@ -67,16 +67,6 @@ parameters: count: 1 path: ../../system/Config/Services.php - - - message: '#^Accessing offset ''SERVER_ADDR'' directly on \$_SERVER is discouraged\.$#' - count: 2 - path: ../../system/Email/Email.php - - - - message: '#^Accessing offset ''SERVER_NAME'' directly on \$_SERVER is discouraged\.$#' - count: 2 - path: ../../system/Email/Email.php - - message: '#^Accessing offset ''HTTP_USER_AGENT'' directly on \$_SERVER is discouraged\.$#' count: 2 diff --git a/utils/phpstan-baseline/loader.neon b/utils/phpstan-baseline/loader.neon index 5c7183708c35..643d42e8c95f 100644 --- a/utils/phpstan-baseline/loader.neon +++ b/utils/phpstan-baseline/loader.neon @@ -1,4 +1,4 @@ -# total 3149 errors +# total 3145 errors includes: - argument.type.neon - assign.propertyType.neon