From 2e96b22320dc3b654cde870868b9ac7446a806e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20FIDRY?= Date: Thu, 18 Jan 2024 11:11:51 +0100 Subject: [PATCH] [Console] Only execute additional checks for color support if the output is a TTY --- .../Component/Console/Output/StreamOutput.php | 37 ++++++++++++++++++- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Console/Output/StreamOutput.php b/src/Symfony/Component/Console/Output/StreamOutput.php index f057f0e51d159..dcd9e54c128df 100644 --- a/src/Symfony/Component/Console/Output/StreamOutput.php +++ b/src/Symfony/Component/Console/Output/StreamOutput.php @@ -95,6 +95,10 @@ protected function hasColorSupport() return false; } + if (!$this->isTty()) { + return false; + } + if (\DIRECTORY_SEPARATOR === '\\' && \function_exists('sapi_windows_vt100_support') && @sapi_windows_vt100_support($this->stream) @@ -105,7 +109,36 @@ protected function hasColorSupport() return 'Hyper' === getenv('TERM_PROGRAM') || false !== getenv('ANSICON') || 'ON' === getenv('ConEmuANSI') - || str_starts_with((string) getenv('TERM'), 'xterm') - || stream_isatty($this->stream); + || str_starts_with((string) getenv('TERM'), 'xterm'); + } + + /** + * Checks if the stream is a TTY, i.e; whether the output stream is connected to a terminal. + * + * Reference: Composer\Util\Platform::isTty + * https://github.com/composer/composer + */ + private function isTty(): bool + { + // Detect msysgit/mingw and assume this is a tty because detection + // does not work correctly, see https://github.com/composer/composer/issues/9690 + if (\in_array(strtoupper((string) getenv('MSYSTEM')), ['MINGW32', 'MINGW64'], true)) { + return true; + } + + // Modern cross-platform function, includes the fstat fallback so if it is present we trust it + if (\function_exists('stream_isatty')) { + return stream_isatty($this->stream); + } + + // Only trusting this if it is positive, otherwise prefer fstat fallback. + if (\function_exists('posix_isatty') && posix_isatty($this->stream)) { + return true; + } + + $stat = @fstat($this->stream); + + // Check if formatted mode is S_IFCHR + return $stat ? 0020000 === ($stat['mode'] & 0170000) : false; } }