Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 339bfc8

Browse filesBrowse files
[Console] always use stty when possible to ask hidden questions
1 parent b9354dc commit 339bfc8
Copy full SHA for 339bfc8

File tree

1 file changed

+29
-56
lines changed
Filter options

1 file changed

+29
-56
lines changed

‎src/Symfony/Component/Console/Helper/QuestionHelper.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Console/Helper/QuestionHelper.php
+29-56Lines changed: 29 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class QuestionHelper extends Helper
3434
private $inputStream;
3535
private static $shell;
3636
private static $stty = true;
37+
private static $stdinIsInteractive;
3738

3839
/**
3940
* Asks a question to the user.
@@ -417,35 +418,28 @@ private function getHiddenResponse(OutputInterface $output, $inputStream, bool $
417418
return $value;
418419
}
419420

420-
if (self::$stty && Terminal::hasSttyAvailable()) {
421+
if (Terminal::hasSttyAvailable()) {
421422
$sttyMode = shell_exec('stty -g');
422-
423423
shell_exec('stty -echo');
424-
$value = fgets($inputStream, 4096);
425-
shell_exec(sprintf('stty %s', $sttyMode));
424+
} elseif ($this->isInteractiveInput($inputStream)) {
425+
throw new RuntimeException('Unable to hide the response.');
426+
}
426427

427-
if (false === $value) {
428-
throw new MissingInputException('Aborted.');
429-
}
430-
if ($trimmable) {
431-
$value = trim($value);
432-
}
433-
$output->writeln('');
428+
$value = fgets($inputStream, 4096);
434429

435-
return $value;
430+
if (Terminal::hasSttyAvailable()) {
431+
shell_exec(sprintf('stty %s', $sttyMode));
436432
}
437433

438-
if (false !== $shell = $this->getShell()) {
439-
$readCmd = 'csh' === $shell ? 'set mypassword = $<' : 'read -r mypassword';
440-
$command = sprintf("/usr/bin/env %s -c 'stty -echo; %s; stty echo; echo \$mypassword' 2> /dev/null", $shell, $readCmd);
441-
$sCommand = shell_exec($command);
442-
$value = $trimmable ? rtrim($sCommand) : $sCommand;
443-
$output->writeln('');
444-
445-
return $value;
434+
if (false === $value) {
435+
throw new MissingInputException('Aborted.');
446436
}
437+
if ($trimmable) {
438+
$value = trim($value);
439+
}
440+
$output->writeln('');
447441

448-
throw new RuntimeException('Unable to hide the response.');
442+
return $value;
449443
}
450444

451445
/**
@@ -473,56 +467,35 @@ private function validateAttempts(callable $interviewer, OutputInterface $output
473467
throw $e;
474468
} catch (\Exception $error) {
475469
}
476-
477-
$attempts = $attempts ?? -(int) $this->askForever();
478470
}
479471

480472
throw $error;
481473
}
482474

483-
/**
484-
* Returns a valid unix shell.
485-
*
486-
* @return string|bool The valid shell name, false in case no valid shell is found
487-
*/
488-
private function getShell()
475+
private function isInteractiveInput($inputStream): bool
489476
{
490-
if (null !== self::$shell) {
491-
return self::$shell;
477+
if ('php://stdin' !== (stream_get_meta_data($inputStream)['uri'] ?? null)) {
478+
return false;
492479
}
493480

494-
self::$shell = false;
495-
496-
if (file_exists('/usr/bin/env')) {
497-
// handle other OSs with bash/zsh/ksh/csh if available to hide the answer
498-
$test = "/usr/bin/env %s -c 'echo OK' 2> /dev/null";
499-
foreach (['bash', 'zsh', 'ksh', 'csh'] as $sh) {
500-
if ('OK' === rtrim(shell_exec(sprintf($test, $sh)))) {
501-
self::$shell = $sh;
502-
break;
503-
}
504-
}
505-
}
506-
507-
return self::$shell;
508-
}
509-
510-
private function askForever(): bool
511-
{
512-
$inputStream = $this->inputStream ?: fopen('php://stdin', 'r');
513-
514-
if ('php://stdin' !== (stream_get_meta_data($inputStream)['url'] ?? null)) {
515-
return true;
481+
if (null !== self::$stdinIsInteractive) {
482+
return self::$stdinIsInteractive;
516483
}
517484

518485
if (\function_exists('stream_isatty')) {
519-
return stream_isatty($inputStream);
486+
return self::$stdinIsInteractive = stream_isatty(fopen('php://stdin', 'r'));
520487
}
521488

522489
if (\function_exists('posix_isatty')) {
523-
return posix_isatty($inputStream);
490+
return self::$stdinIsInteractive = posix_isatty(fopen('php://stdin', 'r'));
524491
}
525492

526-
return true;
493+
if (!\function_exists('exec')) {
494+
return self::$stdinIsInteractive = true;
495+
}
496+
497+
exec('stty 2> /dev/null', $output, $status);
498+
499+
return self::$stdinIsInteractive = 1 !== $status;
527500
}
528501
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.