From a4b1fa669432ff433df65a7e89e122c3d7d8b892 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Sat, 14 May 2016 17:57:37 +0200 Subject: [PATCH] chomp newlines only at the end of YAML documents --- src/Symfony/Component/Yaml/Parser.php | 26 ++++++++++++++----- .../Component/Yaml/Tests/ParserTest.php | 3 ++- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/Symfony/Component/Yaml/Parser.php b/src/Symfony/Component/Yaml/Parser.php index a37e3e6948..67f780aaae 100644 --- a/src/Symfony/Component/Yaml/Parser.php +++ b/src/Symfony/Component/Yaml/Parser.php @@ -25,6 +25,7 @@ class Parser const FOLDED_SCALAR_PATTERN = self::BLOCK_SCALAR_HEADER_PATTERN; private $offset = 0; + private $totalNumberOfLines; private $lines = array(); private $currentLineNb = -1; private $currentLine = ''; @@ -33,11 +34,13 @@ class Parser /** * Constructor. * - * @param int $offset The offset of YAML document (used for line numbers in error messages) + * @param int $offset The offset of YAML document (used for line numbers in error messages) + * @param int|null $totalNumberOfLines The overall number of lines being parsed */ - public function __construct($offset = 0) + public function __construct($offset = 0, $totalNumberOfLines = null) { $this->offset = $offset; + $this->totalNumberOfLines = $totalNumberOfLines; } /** @@ -61,6 +64,10 @@ class Parser $value = $this->cleanup($value); $this->lines = explode("\n", $value); + if (null === $this->totalNumberOfLines) { + $this->totalNumberOfLines = count($this->lines); + } + if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) { $mbEncoding = mb_internal_encoding(); mb_internal_encoding('UTF-8'); @@ -93,7 +100,7 @@ class Parser // array if (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#')) { $c = $this->getRealCurrentLineNb() + 1; - $parser = new self($c); + $parser = new self($c, $this->totalNumberOfLines); $parser->refs = &$this->refs; $data[] = $parser->parse($this->getNextEmbedBlock(null, true), $exceptionOnInvalidType, $objectSupport); } else { @@ -102,7 +109,7 @@ class Parser ) { // this is a compact notation element, add to next block and parse $c = $this->getRealCurrentLineNb(); - $parser = new self($c); + $parser = new self($c, $this->totalNumberOfLines); $parser->refs = &$this->refs; $block = $values['value']; @@ -153,7 +160,7 @@ class Parser $value = $this->getNextEmbedBlock(); } $c = $this->getRealCurrentLineNb() + 1; - $parser = new self($c); + $parser = new self($c, $this->totalNumberOfLines); $parser->refs = &$this->refs; $parsed = $parser->parse($value, $exceptionOnInvalidType, $objectSupport); @@ -190,7 +197,7 @@ class Parser $data[$key] = null; } else { $c = $this->getRealCurrentLineNb() + 1; - $parser = new self($c); + $parser = new self($c, $this->totalNumberOfLines); $parser->refs = &$this->refs; $data[$key] = $parser->parse($this->getNextEmbedBlock(), $exceptionOnInvalidType, $objectSupport); } @@ -528,6 +535,8 @@ class Parser if ($notEOF) { $blockLines[] = ''; $this->moveToPreviousLine(); + } elseif (!$notEOF && !$this->isCurrentLineLastLineInDocument()) { + $blockLines[] = ''; } // folded style @@ -634,6 +643,11 @@ class Parser return '' !== $ltrimmedLine && $ltrimmedLine[0] === '#'; } + private function isCurrentLineLastLineInDocument() + { + return ($this->offset + $this->currentLineNb) >= ($this->totalNumberOfLines - 1); + } + /** * Cleanups a YAML string to be parsed. * diff --git a/src/Symfony/Component/Yaml/Tests/ParserTest.php b/src/Symfony/Component/Yaml/Tests/ParserTest.php index 34cc81b2d3..6645c36108 100644 --- a/src/Symfony/Component/Yaml/Tests/ParserTest.php +++ b/src/Symfony/Component/Yaml/Tests/ParserTest.php @@ -826,6 +826,7 @@ EOT foo # bar baz + EOT , ), @@ -854,7 +855,7 @@ EOT; $expected = array( 'foo' => array( 'bar' => array( - 'scalar-block' => 'line1 line2>', + 'scalar-block' => "line1 line2>\n", ), 'baz' => array( 'foobar' => null,