From c6c35b3db983fe8c3e76a71577511787258f5dc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Pineau?= Date: Sun, 25 Aug 2013 15:33:45 +0200 Subject: [PATCH 1/4] [Console] Escape exception message during the rendering of an exception --- src/Symfony/Component/Console/Application.php | 3 ++- .../Console/Tests/ApplicationTest.php | 3 +++ .../Console/Tests/Fixtures/Foo3Command.php | 8 ++++-- .../Fixtures/application_renderexception3.txt | 24 +++++++++++------ .../application_renderexception3decorated.txt | 27 +++++++++++++++++++ 5 files changed, 54 insertions(+), 11 deletions(-) create mode 100644 src/Symfony/Component/Console/Tests/Fixtures/application_renderexception3decorated.txt diff --git a/src/Symfony/Component/Console/Application.php b/src/Symfony/Component/Console/Application.php index 1381d5f394..b64f4bb268 100644 --- a/src/Symfony/Component/Console/Application.php +++ b/src/Symfony/Component/Console/Application.php @@ -23,6 +23,7 @@ use Symfony\Component\Console\Output\ConsoleOutputInterface; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Command\HelpCommand; use Symfony\Component\Console\Command\ListCommand; +use Symfony\Component\Console\Formatter\OutputFormatter; use Symfony\Component\Console\Helper\HelperSet; use Symfony\Component\Console\Helper\FormatterHelper; use Symfony\Component\Console\Helper\DialogHelper; @@ -827,7 +828,7 @@ class Application $output->writeln(""); $output->writeln(""); foreach ($messages as $message) { - $output->writeln(''.$message.''); + $output->writeln(''.OutputFormatter::escape($message).''); } $output->writeln(""); $output->writeln(""); diff --git a/src/Symfony/Component/Console/Tests/ApplicationTest.php b/src/Symfony/Component/Console/Tests/ApplicationTest.php index f78d8de107..7f73aa1a4d 100644 --- a/src/Symfony/Component/Console/Tests/ApplicationTest.php +++ b/src/Symfony/Component/Console/Tests/ApplicationTest.php @@ -429,6 +429,9 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase $tester->run(array('command' => 'foo3:bar'), array('decorated' => false)); $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception3.txt', $this->normalizeLineBreaks($tester->getDisplay()), '->renderException() renders a pretty exceptions with previous exceptions'); + $tester->run(array('command' => 'foo3:bar'), array('decorated' => true)); + $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception3decorated.txt', $tester->getDisplay(true), '->renderException() renders a pretty exceptions with previous exceptions'); + $application = $this->getMock('Symfony\Component\Console\Application', array('getTerminalWidth')); $application->setAutoExit(false); $application->expects($this->any()) diff --git a/src/Symfony/Component/Console/Tests/Fixtures/Foo3Command.php b/src/Symfony/Component/Console/Tests/Fixtures/Foo3Command.php index 7349bc355e..2a59b1d297 100644 --- a/src/Symfony/Component/Console/Tests/Fixtures/Foo3Command.php +++ b/src/Symfony/Component/Console/Tests/Fixtures/Foo3Command.php @@ -17,9 +17,13 @@ class Foo3Command extends Command protected function execute(InputInterface $input, OutputInterface $output) { try { - throw new \Exception("First exception"); + try { + throw new \Exception("First exception

this is html

"); + } catch (\Exception $e) { + throw new \Exception("Second exception comment", 0, $e); + } } catch (\Exception $e) { - throw new \Exception("Second exception", 0, $e); + throw new \Exception("Third exception comment", 0, $e); } } } diff --git a/src/Symfony/Component/Console/Tests/Fixtures/application_renderexception3.txt b/src/Symfony/Component/Console/Tests/Fixtures/application_renderexception3.txt index c639924238..a12a32c577 100644 --- a/src/Symfony/Component/Console/Tests/Fixtures/application_renderexception3.txt +++ b/src/Symfony/Component/Console/Tests/Fixtures/application_renderexception3.txt @@ -1,17 +1,25 @@ - - [Exception] - Second exception - + + [Exception] + Third exception comment + - - [Exception] - First exception - + + [Exception] + Second exception comment + + + + + + + [Exception] + First exception

this is html

+ foo3:bar diff --git a/src/Symfony/Component/Console/Tests/Fixtures/application_renderexception3decorated.txt b/src/Symfony/Component/Console/Tests/Fixtures/application_renderexception3decorated.txt new file mode 100644 index 0000000000..9f9d0cbc04 --- /dev/null +++ b/src/Symfony/Component/Console/Tests/Fixtures/application_renderexception3decorated.txt @@ -0,0 +1,27 @@ + + +  + [Exception]  + Third exception comment  +  + + + + +  + [Exception]  + Second exception comment  +  + + + + +  + [Exception]  + First exception

this is html

 +  + + +foo3:bar + + From a47d663f251ac68852a5c6d0ba86ff3f8a38428a Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Tue, 17 Sep 2013 14:13:58 +0200 Subject: [PATCH 2/4] [Console] fixed the formatter for single-char tags --- .../Component/Console/Formatter/OutputFormatter.php | 2 +- .../Console/Tests/Formatter/OutputFormatterTest.php | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Console/Formatter/OutputFormatter.php b/src/Symfony/Component/Console/Formatter/OutputFormatter.php index f3c3298866..01904ccb48 100644 --- a/src/Symfony/Component/Console/Formatter/OutputFormatter.php +++ b/src/Symfony/Component/Console/Formatter/OutputFormatter.php @@ -23,7 +23,7 @@ class OutputFormatter implements OutputFormatterInterface /** * The pattern to phrase the format. */ - const FORMAT_PATTERN = '#(\\\\?)<(/?)([a-z][a-z0-9_=;-]+)?>((?: [^<\\\\]+ | (?!<(?:/?[a-z]|/>)). | .(?<=\\\\<) )*)#isx'; + const FORMAT_PATTERN = '#(\\\\?)<(/?)([a-z][a-z0-9_=;-]*)?>((?: [^<\\\\]+ | (?!<(?:/?[a-z]|/>)). | .(?<=\\\\<) )*)#isx'; private $decorated; private $styles = array(); diff --git a/src/Symfony/Component/Console/Tests/Formatter/OutputFormatterTest.php b/src/Symfony/Component/Console/Tests/Formatter/OutputFormatterTest.php index 497630e87c..08bd02e852 100644 --- a/src/Symfony/Component/Console/Tests/Formatter/OutputFormatterTest.php +++ b/src/Symfony/Component/Console/Tests/Formatter/OutputFormatterTest.php @@ -113,7 +113,10 @@ class FormatterStyleTest extends \PHPUnit_Framework_TestCase $this->assertEquals($style, $formatter->getStyle('test')); $this->assertNotEquals($style, $formatter->getStyle('info')); - $this->assertEquals("\033[34;47msome custom msg\033[0m", $formatter->format('some custom msg')); + $style = new OutputFormatterStyle('blue', 'white'); + $formatter->setStyle('b', $style); + + $this->assertEquals("\033[34;47msome \033[0m\033[34;47mcustom\033[0m\033[34;47m msg\033[0m", $formatter->format('some custom msg')); } public function testRedefineStyle() @@ -137,7 +140,7 @@ class FormatterStyleTest extends \PHPUnit_Framework_TestCase public function testNonStyleTag() { $formatter = new OutputFormatter(true); - $this->assertEquals("\033[32msome \033[0m\033[32m styled\033[0m", $formatter->format('some styled')); + $this->assertEquals("\033[32msome \033[0m\033[32m styled \033[0m\033[32m

single-char tag\033[0m\033[32m

\033[0m", $formatter->format('some styled

single-char tag

')); } public function testNotDecoratedFormatter() From 1f88a28d54e006bd4090bfb3bb7a31bef4e57cf3 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Tue, 17 Sep 2013 14:15:59 +0200 Subject: [PATCH 3/4] [Console] added some more information about OutputFormatter::replaceStyle() --- src/Symfony/Component/Console/Formatter/OutputFormatter.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Symfony/Component/Console/Formatter/OutputFormatter.php b/src/Symfony/Component/Console/Formatter/OutputFormatter.php index 01904ccb48..36721601ed 100644 --- a/src/Symfony/Component/Console/Formatter/OutputFormatter.php +++ b/src/Symfony/Component/Console/Formatter/OutputFormatter.php @@ -163,6 +163,8 @@ class OutputFormatter implements OutputFormatterInterface /** * Replaces style of the output. * + * All escaped tags and tags that reference unknown styles are kept as is. + * * @param array $match * * @return string The replaced style From c8d0342887620f3067506c6cd388ee9844b2efbf Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Tue, 17 Sep 2013 14:23:45 +0200 Subject: [PATCH 4/4] [Console] fixed exception rendering when nested styles --- src/Symfony/Component/Console/Application.php | 29 +++++++++---------- .../Console/Tests/Fixtures/Foo3Command.php | 2 +- .../Fixtures/application_renderexception3.txt | 16 +++++----- .../application_renderexception3decorated.txt | 18 ++++++------ 4 files changed, 32 insertions(+), 33 deletions(-) diff --git a/src/Symfony/Component/Console/Application.php b/src/Symfony/Component/Console/Application.php index b64f4bb268..49ef6224f7 100644 --- a/src/Symfony/Component/Console/Application.php +++ b/src/Symfony/Component/Console/Application.php @@ -23,7 +23,6 @@ use Symfony\Component\Console\Output\ConsoleOutputInterface; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Command\HelpCommand; use Symfony\Component\Console\Command\ListCommand; -use Symfony\Component\Console\Formatter\OutputFormatter; use Symfony\Component\Console\Helper\HelperSet; use Symfony\Component\Console\Helper\FormatterHelper; use Symfony\Component\Console\Helper\DialogHelper; @@ -809,29 +808,29 @@ class Application $title = sprintf(' [%s] ', get_class($e)); $len = $strlen($title); $width = $this->getTerminalWidth() ? $this->getTerminalWidth() - 1 : PHP_INT_MAX; + $formatter = $output->getFormatter(); $lines = array(); foreach (preg_split('/\r?\n/', $e->getMessage()) as $line) { foreach (str_split($line, $width - 4) as $line) { - $lines[] = sprintf(' %s ', $line); - $len = max($strlen($line) + 4, $len); + // pre-format lines to get the right string length + $lineLength = $strlen(preg_replace('/\[[^m]*m/', '', $formatter->format($line))) + 4; + $lines[] = array($line, $lineLength); + + $len = max($lineLength, $len); } } - $messages = array(str_repeat(' ', $len), $title.str_repeat(' ', max(0, $len - $strlen($title)))); - + $messages = array('', ''); + $messages[] = $emptyLine = $formatter->format(sprintf('%s', str_repeat(' ', $len))); + $messages[] = $formatter->format(sprintf('%s%s', $title, str_repeat(' ', max(0, $len - $strlen($title))))); foreach ($lines as $line) { - $messages[] = $line.str_repeat(' ', $len - $strlen($line)); + $messages[] = $formatter->format(sprintf(' %s %s', $line[0], str_repeat(' ', $len - $line[1]))); } + $messages[] = $emptyLine; + $messages[] = ''; + $messages[] = ''; - $messages[] = str_repeat(' ', $len); - - $output->writeln(""); - $output->writeln(""); - foreach ($messages as $message) { - $output->writeln(''.OutputFormatter::escape($message).''); - } - $output->writeln(""); - $output->writeln(""); + $output->writeln($messages, OutputInterface::OUTPUT_RAW); if (OutputInterface::VERBOSITY_VERBOSE === $output->getVerbosity()) { $output->writeln('Exception trace:'); diff --git a/src/Symfony/Component/Console/Tests/Fixtures/Foo3Command.php b/src/Symfony/Component/Console/Tests/Fixtures/Foo3Command.php index 2a59b1d297..43a35076e3 100644 --- a/src/Symfony/Component/Console/Tests/Fixtures/Foo3Command.php +++ b/src/Symfony/Component/Console/Tests/Fixtures/Foo3Command.php @@ -20,7 +20,7 @@ class Foo3Command extends Command try { throw new \Exception("First exception

this is html

"); } catch (\Exception $e) { - throw new \Exception("Second exception comment", 0, $e); + throw new \Exception("Second exception comment", 0, $e); } } catch (\Exception $e) { throw new \Exception("Third exception comment", 0, $e); diff --git a/src/Symfony/Component/Console/Tests/Fixtures/application_renderexception3.txt b/src/Symfony/Component/Console/Tests/Fixtures/application_renderexception3.txt index a12a32c577..72a72867f3 100644 --- a/src/Symfony/Component/Console/Tests/Fixtures/application_renderexception3.txt +++ b/src/Symfony/Component/Console/Tests/Fixtures/application_renderexception3.txt @@ -1,17 +1,17 @@ - - [Exception] - Third exception comment - + + [Exception] + Third exception comment + - - [Exception] - Second exception comment - + + [Exception] + Second exception comment + diff --git a/src/Symfony/Component/Console/Tests/Fixtures/application_renderexception3decorated.txt b/src/Symfony/Component/Console/Tests/Fixtures/application_renderexception3decorated.txt index 9f9d0cbc04..eb4181c2b4 100644 --- a/src/Symfony/Component/Console/Tests/Fixtures/application_renderexception3decorated.txt +++ b/src/Symfony/Component/Console/Tests/Fixtures/application_renderexception3decorated.txt @@ -1,24 +1,24 @@ -  - [Exception]  - Third exception comment  -  +  + [Exception]  + Third exception comment  +  -  - [Exception]  - Second exception comment  -  +  + [Exception]  + Second exception comment  +     [Exception]  - First exception

this is html

 + First exception 

this is html