diff --git a/Descriptor/TextDescriptor.php b/Descriptor/TextDescriptor.php index ccfbd6d36..16ab3eb55 100644 --- a/Descriptor/TextDescriptor.php +++ b/Descriptor/TextDescriptor.php @@ -117,7 +117,7 @@ protected function describeInputDefinition(InputDefinition $definition, array $o $this->writeText('Options:', $options); foreach ($definition->getOptions() as $option) { - if (\strlen($option->getShortcut()) > 1) { + if (\strlen($option->getShortcut() ?? '') > 1) { $laterOptions[] = $option; continue; } diff --git a/Descriptor/XmlDescriptor.php b/Descriptor/XmlDescriptor.php index 4931fba62..5323a3ba8 100644 --- a/Descriptor/XmlDescriptor.php +++ b/Descriptor/XmlDescriptor.php @@ -200,7 +200,7 @@ private function getInputOptionDocument(InputOption $option): \DOMDocument $dom->appendChild($objectXML = $dom->createElement('option')); $objectXML->setAttribute('name', '--'.$option->getName()); - $pos = strpos($option->getShortcut(), '|'); + $pos = strpos($option->getShortcut() ?? '', '|'); if (false !== $pos) { $objectXML->setAttribute('shortcut', '-'.substr($option->getShortcut(), 0, $pos)); $objectXML->setAttribute('shortcuts', '-'.str_replace('|', '|-', $option->getShortcut())); diff --git a/Helper/ProgressIndicator.php b/Helper/ProgressIndicator.php index 491a537eb..2d8774201 100644 --- a/Helper/ProgressIndicator.php +++ b/Helper/ProgressIndicator.php @@ -185,7 +185,7 @@ private function display() } return $matches[0]; - }, $this->format)); + }, $this->format ?? '')); } private function determineBestFormat(): string diff --git a/Helper/QuestionHelper.php b/Helper/QuestionHelper.php index 72880f6a6..340b552aa 100644 --- a/Helper/QuestionHelper.php +++ b/Helper/QuestionHelper.php @@ -110,11 +110,6 @@ private function doAsk(OutputInterface $output, Question $question) $inputStream = $this->inputStream ?: \STDIN; $autocomplete = $question->getAutocompleterCallback(); - if (\function_exists('sapi_windows_cp_set')) { - // Codepage used by cmd.exe on Windows to allow special characters (éàüñ). - @sapi_windows_cp_set(1252); - } - if (null === $autocomplete || !self::$stty || !Terminal::hasSttyAvailable()) { $ret = false; if ($question->isHidden()) { @@ -514,7 +509,10 @@ private function isInteractiveInput($inputStream): bool private function readInput($inputStream, Question $question) { if (!$question->isMultiline()) { - return fgets($inputStream, 4096); + $cp = $this->setIOCodepage(); + $ret = fgets($inputStream, 4096); + + return $this->resetIOCodepage($cp, $ret); } $multiLineStreamReader = $this->cloneInputStream($inputStream); @@ -523,6 +521,7 @@ private function readInput($inputStream, Question $question) } $ret = ''; + $cp = $this->setIOCodepage(); while (false !== ($char = fgetc($multiLineStreamReader))) { if (\PHP_EOL === "{$ret}{$char}") { break; @@ -530,7 +529,44 @@ private function readInput($inputStream, Question $question) $ret .= $char; } - return $ret; + return $this->resetIOCodepage($cp, $ret); + } + + /** + * Sets console I/O to the host code page. + * + * @return int Previous code page in IBM/EBCDIC format + */ + private function setIOCodepage(): int + { + if (\function_exists('sapi_windows_cp_set')) { + $cp = sapi_windows_cp_get(); + sapi_windows_cp_set(sapi_windows_cp_get('oem')); + + return $cp; + } + + return 0; + } + + /** + * Sets console I/O to the specified code page and converts the user input. + * + * @param string|false $input + * + * @return string|false + */ + private function resetIOCodepage(int $cp, $input) + { + if (0 !== $cp) { + sapi_windows_cp_set($cp); + + if (false !== $input && '' !== $input) { + $input = sapi_windows_cp_conv(sapi_windows_cp_get('oem'), $cp, $input); + } + } + + return $input; } /** diff --git a/Helper/Table.php b/Helper/Table.php index ee969bcff..9662f4e75 100644 --- a/Helper/Table.php +++ b/Helper/Table.php @@ -572,7 +572,7 @@ private function buildTableRows(array $rows): TableRows if (isset($this->columnMaxWidths[$column]) && Helper::strlenWithoutDecoration($formatter, $cell) > $this->columnMaxWidths[$column]) { $cell = $formatter->formatAndWrap($cell, $this->columnMaxWidths[$column] * $colspan); } - if (!strstr($cell, "\n")) { + if (!strstr($cell ?? '', "\n")) { continue; } $escaped = implode("\n", array_map([OutputFormatter::class, 'escapeTrailingBackslash'], explode("\n", $cell)));