@@ -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}
0 commit comments