bug #41210 [Console] Fix Windows code page support (orkan)
This PR was merged into the 4.4 branch.
Discussion
----------
[Console] Fix Windows code page support
| Q | A
| ------------- | ---
| Branch? | 4.4
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets | Fix #37385, Fix #35842, Fix #36324, Fix #37495, Fix #37278
| License | MIT
Corrects mojibake problem on Windows where an OEM code page was applied to an input string and then messed with PHP.internal_encoding setting used by the script. This caused strings with different encodings to be displayed on the console output.
Commits
-------
41452785c6
[Console] Fix Windows code page support
This commit is contained in:
commit
49dd6ef279
@ -108,11 +108,6 @@ class QuestionHelper extends Helper
|
|||||||
$inputStream = $this->inputStream ?: \STDIN;
|
$inputStream = $this->inputStream ?: \STDIN;
|
||||||
$autocomplete = $question->getAutocompleterCallback();
|
$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()) {
|
if (null === $autocomplete || !self::$stty || !Terminal::hasSttyAvailable()) {
|
||||||
$ret = false;
|
$ret = false;
|
||||||
if ($question->isHidden()) {
|
if ($question->isHidden()) {
|
||||||
@ -127,7 +122,9 @@ class QuestionHelper extends Helper
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (false === $ret) {
|
if (false === $ret) {
|
||||||
|
$cp = $this->setIOCodepage();
|
||||||
$ret = fgets($inputStream, 4096);
|
$ret = fgets($inputStream, 4096);
|
||||||
|
$ret = $this->resetIOCodepage($cp, $ret);
|
||||||
if (false === $ret) {
|
if (false === $ret) {
|
||||||
throw new MissingInputException('Aborted.');
|
throw new MissingInputException('Aborted.');
|
||||||
}
|
}
|
||||||
@ -503,4 +500,41 @@ class QuestionHelper extends Helper
|
|||||||
|
|
||||||
return self::$stdinIsInteractive = 1 !== $status;
|
return self::$stdinIsInteractive = 1 !== $status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user