diff --git a/system/CLI/CLI.php b/system/CLI/CLI.php index f01124ec9075..68bd0e22433d 100644 --- a/system/CLI/CLI.php +++ b/system/CLI/CLI.php @@ -778,7 +778,7 @@ public static function generateDimensions() static::$width = (int) $matches[2]; } } - } elseif (($size = exec('stty size')) && preg_match('/(\d+)\s+(\d+)/', $size, $matches)) { + } elseif (($size = exec('stty size 2>/dev/null')) && preg_match('/(\d+)\s+(\d+)/', $size, $matches)) { static::$height = (int) $matches[1]; static::$width = (int) $matches[2]; } else { diff --git a/tests/system/CLI/CLITest.php b/tests/system/CLI/CLITest.php index 6a69cf7e69ab..c084d067ad6b 100644 --- a/tests/system/CLI/CLITest.php +++ b/tests/system/CLI/CLITest.php @@ -21,6 +21,7 @@ use CodeIgniter\Test\StreamFilterTrait; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\Group; +use PHPUnit\Framework\Attributes\RequiresOperatingSystem; use ReflectionProperty; /** @@ -594,6 +595,33 @@ public function testWindow(): void $this->assertIsInt(CLI::getWidth()); } + #[RequiresOperatingSystem('Darwin|Linux')] + public function testGenerateDimensionsDoesNotLeakSttyErrorToStderr(): void + { + $code = <<<'PHP' + require __DIR__ . '/system/Test/bootstrap.php'; + CodeIgniter\CLI\CLI::generateDimensions(); + PHP; + + $cmd = sprintf('%s -r %s < /dev/null', PHP_BINARY, escapeshellarg($code)); + + $proc = proc_open( + $cmd, + [1 => ['pipe', 'w'], 2 => ['pipe', 'w']], + $pipes, + ROOTPATH, + ); + $this->assertIsResource($proc); + + stream_get_contents($pipes[1]); + $stderr = stream_get_contents($pipes[2]); + fclose($pipes[1]); + fclose($pipes[2]); + proc_close($proc); + + $this->assertSame('', $stderr); + } + /** * @param array $tbody * @param array $thead diff --git a/user_guide_src/source/changelogs/v4.7.3.rst b/user_guide_src/source/changelogs/v4.7.3.rst index ea3b37f579f7..3b5c2ce38555 100644 --- a/user_guide_src/source/changelogs/v4.7.3.rst +++ b/user_guide_src/source/changelogs/v4.7.3.rst @@ -37,6 +37,7 @@ Bugs Fixed ********** - **Autoloader:** Fixed a bug where ``Autoloader::unregister()`` (used during tests) silently failed to remove handlers from the SPL autoload stack, causing closures to accumulate permanently. +- **CLI:** Fixed a bug where ``CLI::generateDimensions()`` leaked ``stty`` error output (e.g., ``stty: 'standard input': Inappropriate ioctl for device``) to stderr when stdin was not a TTY. - **Commands:** Fixed a bug in the ``env`` command where passing options only would cause the command to throw a ``TypeError`` instead of showing the current environment. - **Common:** Fixed a bug where the ``command()`` helper function did not properly clean up output buffers, which could lead to risky tests when exceptions were thrown. - **Validation:** Fixed a bug where ``Validation::getValidated()`` dropped fields whose validated value was explicitly ``null``.