Skip to content

Commit

Permalink
Merge branch '4.4' into 5.0
Browse files Browse the repository at this point in the history
* 4.4:
  [HttpClient][CurlHttpClient] Fix http_version option usage
  [HttpClient] fix parsing response headers in CurlResponse
  [Console] Do not check for "stty" using "exec" if that function is disabled
  [Console] always use stty when possible to ask hidden questions
  • Loading branch information
nicolas-grekas committed Jul 3, 2020
2 parents 980e4b4 + a3562f4 commit 9ce1c15
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 55 deletions.
83 changes: 28 additions & 55 deletions Helper/QuestionHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class QuestionHelper extends Helper
private $inputStream;
private static $shell;
private static $stty = true;
private static $stdinIsInteractive;

/**
* Asks a question to the user.
Expand Down Expand Up @@ -417,33 +418,26 @@ private function getHiddenResponse(OutputInterface $output, $inputStream, bool $

if (self::$stty && Terminal::hasSttyAvailable()) {
$sttyMode = shell_exec('stty -g');

shell_exec('stty -echo');
$value = fgets($inputStream, 4096);
shell_exec(sprintf('stty %s', $sttyMode));
} elseif ($this->isInteractiveInput($inputStream)) {
throw new RuntimeException('Unable to hide the response.');
}

if (false === $value) {
throw new MissingInputException('Aborted.');
}
if ($trimmable) {
$value = trim($value);
}
$output->writeln('');
$value = fgets($inputStream, 4096);

return $value;
if (self::$stty && Terminal::hasSttyAvailable()) {
shell_exec(sprintf('stty %s', $sttyMode));
}

if (false !== $shell = $this->getShell()) {
$readCmd = 'csh' === $shell ? 'set mypassword = $<' : 'read -r mypassword';
$command = sprintf("/usr/bin/env %s -c 'stty -echo; %s; stty echo; echo \$mypassword' 2> /dev/null", $shell, $readCmd);
$sCommand = shell_exec($command);
$value = $trimmable ? rtrim($sCommand) : $sCommand;
$output->writeln('');

return $value;
if (false === $value) {
throw new MissingInputException('Aborted.');
}
if ($trimmable) {
$value = trim($value);
}
$output->writeln('');

throw new RuntimeException('Unable to hide the response.');
return $value;
}

/**
Expand Down Expand Up @@ -471,56 +465,35 @@ private function validateAttempts(callable $interviewer, OutputInterface $output
throw $e;
} catch (\Exception $error) {
}

$attempts = $attempts ?? -(int) $this->askForever();
}

throw $error;
}

/**
* Returns a valid unix shell.
*
* @return string|bool The valid shell name, false in case no valid shell is found
*/
private function getShell()
private function isInteractiveInput($inputStream): bool
{
if (null !== self::$shell) {
return self::$shell;
if ('php://stdin' !== (stream_get_meta_data($inputStream)['uri'] ?? null)) {
return false;
}

self::$shell = false;

if (file_exists('/usr/bin/env')) {
// handle other OSs with bash/zsh/ksh/csh if available to hide the answer
$test = "/usr/bin/env %s -c 'echo OK' 2> /dev/null";
foreach (['bash', 'zsh', 'ksh', 'csh'] as $sh) {
if ('OK' === rtrim(shell_exec(sprintf($test, $sh)))) {
self::$shell = $sh;
break;
}
}
}

return self::$shell;
}

private function askForever(): bool
{
$inputStream = $this->inputStream ?: fopen('php://stdin', 'r');

if ('php://stdin' !== (stream_get_meta_data($inputStream)['url'] ?? null)) {
return true;
if (null !== self::$stdinIsInteractive) {
return self::$stdinIsInteractive;
}

if (\function_exists('stream_isatty')) {
return stream_isatty($inputStream);
return self::$stdinIsInteractive = stream_isatty(fopen('php://stdin', 'r'));
}

if (\function_exists('posix_isatty')) {
return posix_isatty($inputStream);
return self::$stdinIsInteractive = posix_isatty(fopen('php://stdin', 'r'));
}

return true;
if (!\function_exists('exec')) {
return self::$stdinIsInteractive = true;
}

exec('stty 2> /dev/null', $output, $status);

return self::$stdinIsInteractive = 1 !== $status;
}
}
5 changes: 5 additions & 0 deletions Terminal.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ public static function hasSttyAvailable()
return self::$stty;
}

// skip check if exec function is disabled
if (!\function_exists('exec')) {
return false;
}

exec('stty 2>&1', $output, $exitcode);

return self::$stty = 0 === $exitcode;
Expand Down

0 comments on commit 9ce1c15

Please sign in to comment.