Skip to content

Commit 901e938

Browse files
Merge branch '5.1'
* 5.1: [HttpClient][CurlHttpClient] Fix http_version option usage [HttpClient] fix parsing response headers in CurlResponse [PropertyAccess] Remove inflector component [Console] Do not check for "stty" using "exec" if that function is disabled [Console] always use stty when possible to ask hidden questions
2 parents b3df84c + a815bc2 commit 901e938

File tree

5 files changed

+50
-64
lines changed

5 files changed

+50
-64
lines changed

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

Lines changed: 28 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class QuestionHelper extends Helper
3636
private $inputStream;
3737
private static $shell;
3838
private static $stty = true;
39+
private static $stdinIsInteractive;
3940

4041
/**
4142
* Asks a question to the user.
@@ -418,33 +419,26 @@ private function getHiddenResponse(OutputInterface $output, $inputStream, bool $
418419

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

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

434-
return $value;
429+
if (self::$stty && Terminal::hasSttyAvailable()) {
430+
shell_exec(sprintf('stty %s', $sttyMode));
435431
}
436432

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

447-
throw new RuntimeException('Unable to hide the response.');
441+
return $value;
448442
}
449443

450444
/**
@@ -472,56 +466,35 @@ private function validateAttempts(callable $interviewer, OutputInterface $output
472466
throw $e;
473467
} catch (\Exception $error) {
474468
}
475-
476-
$attempts = $attempts ?? -(int) $this->askForever();
477469
}
478470

479471
throw $error;
480472
}
481473

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

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

517484
if (\function_exists('stream_isatty')) {
518-
return stream_isatty($inputStream);
485+
return self::$stdinIsInteractive = stream_isatty(fopen('php://stdin', 'r'));
519486
}
520487

521488
if (\function_exists('posix_isatty')) {
522-
return posix_isatty($inputStream);
489+
return self::$stdinIsInteractive = posix_isatty(fopen('php://stdin', 'r'));
523490
}
524491

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

src/Symfony/Component/Console/Terminal.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,11 @@ public static function hasSttyAvailable()
6666
return self::$stty;
6767
}
6868

69+
// skip check if exec function is disabled
70+
if (!\function_exists('exec')) {
71+
return false;
72+
}
73+
6974
exec('stty 2>&1', $output, $exitcode);
7075

7176
return self::$stty = 0 === $exitcode;

src/Symfony/Component/HttpClient/CurlHttpClient.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,12 +138,12 @@ public function request(string $method, string $url, array $options = []): Respo
138138
CURLOPT_CERTINFO => $options['capture_peer_cert_chain'],
139139
];
140140

141-
if (\defined('CURL_VERSION_HTTP2') && (CURL_VERSION_HTTP2 & self::$curlVersion['features']) && ('https:' === $scheme || 2.0 === (float) $options['http_version'])) {
142-
$curlopts[CURLOPT_HTTP_VERSION] = CURL_HTTP_VERSION_2_0;
143-
} elseif (1.0 === (float) $options['http_version']) {
141+
if (1.0 === (float) $options['http_version']) {
144142
$curlopts[CURLOPT_HTTP_VERSION] = CURL_HTTP_VERSION_1_0;
145143
} elseif (1.1 === (float) $options['http_version']) {
146144
$curlopts[CURLOPT_HTTP_VERSION] = CURL_HTTP_VERSION_1_1;
145+
} elseif (\defined('CURL_VERSION_HTTP2') && (CURL_VERSION_HTTP2 & self::$curlVersion['features']) && ('https:' === $scheme || 2.0 === (float) $options['http_version'])) {
146+
$curlopts[CURLOPT_HTTP_VERSION] = CURL_HTTP_VERSION_2_0;
147147
}
148148

149149
if (isset($options['auth_ntlm'])) {

src/Symfony/Component/HttpClient/Response/CurlResponse.php

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ public function __construct(CurlClientState $multi, $ch, array $options = null,
4646
$this->multi = $multi;
4747

4848
if (\is_resource($ch) || $ch instanceof \CurlHandle) {
49-
unset($multi->handlesActivity[(int) $ch]);
5049
$this->handle = $ch;
5150
$this->debugBuffer = fopen('php://temp', 'w+');
5251
if (0x074000 === $curlVersion) {
@@ -77,7 +76,17 @@ public function __construct(CurlClientState $multi, $ch, array $options = null,
7776
}
7877

7978
curl_setopt($ch, CURLOPT_HEADERFUNCTION, static function ($ch, string $data) use (&$info, &$headers, $options, $multi, $id, &$location, $resolveRedirect, $logger): int {
80-
return self::parseHeaderLine($ch, $data, $info, $headers, $options, $multi, $id, $location, $resolveRedirect, $logger);
79+
if (0 !== substr_compare($data, "\r\n", -2)) {
80+
return 0;
81+
}
82+
83+
$len = 0;
84+
85+
foreach (explode("\r\n", substr($data, 0, -2)) as $data) {
86+
$len += 2 + self::parseHeaderLine($ch, $data, $info, $headers, $options, $multi, $id, $location, $resolveRedirect, $logger);
87+
}
88+
89+
return $len;
8190
});
8291

8392
if (null === $options) {
@@ -365,10 +374,10 @@ private static function parseHeaderLine($ch, string $data, array &$info, array &
365374
return \strlen($data); // Ignore HTTP trailers
366375
}
367376

368-
if ("\r\n" !== $data) {
377+
if ('' !== $data) {
369378
try {
370379
// Regular header line: add it to the list
371-
self::addResponseHeaders([substr($data, 0, -2)], $info, $headers);
380+
self::addResponseHeaders([$data], $info, $headers);
372381
} catch (TransportException $e) {
373382
$multi->handlesActivity[$id][] = null;
374383
$multi->handlesActivity[$id][] = $e;
@@ -378,7 +387,7 @@ private static function parseHeaderLine($ch, string $data, array &$info, array &
378387

379388
if (0 !== strpos($data, 'HTTP/')) {
380389
if (0 === stripos($data, 'Location:')) {
381-
$location = trim(substr($data, 9, -2));
390+
$location = trim(substr($data, 9));
382391
}
383392

384393
return \strlen($data);

src/Symfony/Component/PropertyAccess/composer.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
],
1818
"require": {
1919
"php": ">=7.2.5",
20-
"symfony/inflector": "^4.4|^5.0",
2120
"symfony/polyfill-php80": "^1.15",
2221
"symfony/property-info": "^5.1.1"
2322
},

0 commit comments

Comments
 (0)