diff --git a/src/Symfony/Component/Yaml/Parser.php b/src/Symfony/Component/Yaml/Parser.php index 52dedfe078..a37e3e6948 100644 --- a/src/Symfony/Component/Yaml/Parser.php +++ b/src/Symfony/Component/Yaml/Parser.php @@ -303,7 +303,11 @@ class Parser private function getNextEmbedBlock($indentation = null, $inSequence = false) { $oldLineIndentation = $this->getCurrentLineIndentation(); - $insideBlockScalar = $this->isBlockScalarHeader(); + $blockScalarIndentations = array(); + + if ($this->isBlockScalarHeader()) { + $blockScalarIndentations[] = $this->getCurrentLineIndentation(); + } if (!$this->moveToNextLine()) { return; @@ -340,8 +344,8 @@ class Parser $isItUnindentedCollection = $this->isStringUnIndentedCollectionItem(); - if (!$insideBlockScalar) { - $insideBlockScalar = $this->isBlockScalarHeader(); + if (empty($blockScalarIndentations) && $this->isBlockScalarHeader()) { + $blockScalarIndentations[] = $this->getCurrentLineIndentation(); } $previousLineIndentation = $this->getCurrentLineIndentation(); @@ -349,8 +353,17 @@ class Parser while ($this->moveToNextLine()) { $indent = $this->getCurrentLineIndentation(); - if (!$insideBlockScalar && $indent === $previousLineIndentation) { - $insideBlockScalar = $this->isBlockScalarHeader(); + // terminate all block scalars that are more indented than the current line + if (!empty($blockScalarIndentations) && $indent < $previousLineIndentation && trim($this->currentLine) !== '') { + foreach ($blockScalarIndentations as $key => $blockScalarIndentation) { + if ($blockScalarIndentation >= $this->getCurrentLineIndentation()) { + unset($blockScalarIndentations[$key]); + } + } + } + + if (empty($blockScalarIndentations) && !$this->isCurrentLineComment() && $this->isBlockScalarHeader()) { + $blockScalarIndentations[] = $this->getCurrentLineIndentation(); } $previousLineIndentation = $indent; @@ -366,7 +379,7 @@ class Parser } // we ignore "comment" lines only when we are not inside a scalar block - if (!$insideBlockScalar && $this->isCurrentLineComment()) { + if (empty($blockScalarIndentations) && $this->isCurrentLineComment()) { continue; } @@ -523,7 +536,7 @@ class Parser $previousLineIndented = false; $previousLineBlank = false; - for ($i = 0; $i < count($blockLines); $i++) { + for ($i = 0; $i < count($blockLines); ++$i) { if ('' === $blockLines[$i]) { $text .= "\n"; $previousLineIndented = false; @@ -618,7 +631,7 @@ class Parser //checking explicitly the first char of the trim is faster than loops or strpos $ltrimmedLine = ltrim($this->currentLine, ' '); - return $ltrimmedLine[0] === '#'; + return '' !== $ltrimmedLine && $ltrimmedLine[0] === '#'; } /** diff --git a/src/Symfony/Component/Yaml/Tests/ParserTest.php b/src/Symfony/Component/Yaml/Tests/ParserTest.php index 7a1485eb2d..9d6d42befe 100644 --- a/src/Symfony/Component/Yaml/Tests/ParserTest.php +++ b/src/Symfony/Component/Yaml/Tests/ParserTest.php @@ -737,7 +737,9 @@ EOF; public function getCommentLikeStringInScalarBlockData() { - $yaml1 = <<<'EOT' + $tests = array(); + + $yaml = <<<'EOT' pages: - title: some title @@ -752,7 +754,7 @@ pages: footer # comment3 EOT; - $expected1 = array( + $expected = array( 'pages' => array( array( 'title' => 'some title', @@ -771,8 +773,9 @@ EOT ), ), ); + $tests[] = array($yaml, $expected); - $yaml2 = <<<'EOT' + $yaml = <<<'EOT' test: | foo # bar @@ -787,7 +790,7 @@ collection: # bar baz EOT; - $expected2 = array( + $expected = array( 'test' => <<<'EOT' foo # bar @@ -814,11 +817,47 @@ EOT ), ), ); + $tests[] = array($yaml, $expected); - return array( - array($yaml1, $expected1), - array($yaml2, $expected2), + $yaml = << + line1 + line2> + baz: +# comment + foobar: ~ +EOT; + $expected = array( + 'foo' => array( + 'bar' => array( + 'scalar-block' => 'line1 line2>', + ), + 'baz' => array( + 'foobar' => null, + ), + ), ); + $tests[] = array($yaml, $expected); + + $yaml = <<<'EOT' +a: + b: hello +# c: | +# first row +# second row + d: hello +EOT; + $expected = array( + 'a' => array( + 'b' => 'hello', + 'd' => 'hello', + ), + ); + $tests[] = array($yaml, $expected); + + return $tests; } public function testBlankLinesAreParsedAsNewLinesInFoldedBlocks()