Skip to content

Commit

Permalink
Escape trailing \ in QuestionHelper autocompletion
Browse files Browse the repository at this point in the history
Fixes #24652
Trailing backslash, being unescaped, used to escape closing formatting
tag and, thus, formatting tag appeared in autocompletion
  • Loading branch information
kamazee committed Oct 22, 2017
1 parent 0f9c6e6 commit 0c0f1da
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 1 deletion.
3 changes: 2 additions & 1 deletion src/Symfony/Component/Console/Helper/QuestionHelper.php
Expand Up @@ -11,6 +11,7 @@

namespace Symfony\Component\Console\Helper;

use Symfony\Component\Console\Formatter\OutputFormatter;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\ConsoleOutputInterface;
use Symfony\Component\Console\Output\OutputInterface;
Expand Down Expand Up @@ -303,7 +304,7 @@ private function autocomplete(OutputInterface $output, Question $question, $inpu
// Save cursor position
$output->write("\0337");
// Write highlighted text
$output->write('<hl>'.substr($matches[$ofs], $i).'</hl>');
$output->write('<hl>'.OutputFormatter::escapeTrailingBackslash(substr($matches[$ofs], $i)).'</hl>');
// Restore cursor position
$output->write("\0338");
}
Expand Down
40 changes: 40 additions & 0 deletions src/Symfony/Component/Console/Tests/Helper/QuestionHelperTest.php
Expand Up @@ -156,6 +156,46 @@ public function testAskWithAutocompleteWithNonSequentialKeys()
$this->assertEquals('AsseticBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question));
}

public function testAutocompleteWithTrailingBackslash()
{
if (!$this->hasSttyAvailable()) {
$this->markTestSkipped('`stty` is required to test autocomplete functionality');
}

$inputStream = $this->getInputStream('E');

$dialog = new QuestionHelper();
$dialog->setInputStream($inputStream);
$helperSet = new HelperSet(array(new FormatterHelper()));
$dialog->setHelperSet($helperSet);

$question = new Question('');
$expectedCompletion = 'ExampleNamespace\\';
$question->setAutocompleterValues(array($expectedCompletion));

$output = $this->createOutputInterface();
$dialog->ask($this->createInputInterfaceMock(), $output, $question);

$outputStream = $output->getStream();
rewind($outputStream);
$actualOutput = stream_get_contents($outputStream);

// Shell control (esc) sequences are not so important: we only care that
// <hl> tag is interpreted correctly and replaced
$irrelevantEscSequences = array(
"\0337" => '', // Save cursor position
"\0338" => '', // Restore cursor position
"\033[K" => '', // Clear line from cursor till the end
);

$importantActualOutput = strtr($actualOutput, $irrelevantEscSequences);

// Remove colors (e.g. "\033[30m", "\033[31;41m")
$importantActualOutput = preg_replace('/\033\[\d+(;\d+)?m/', '', $importantActualOutput);

$this->assertEquals($expectedCompletion, $importantActualOutput);
}

public function testAskHiddenResponse()
{
if ('\\' === DIRECTORY_SEPARATOR) {
Expand Down

0 comments on commit 0c0f1da

Please sign in to comment.