bug #16860 [Yaml] do not remove "comments" in scalar blocks (xabbuh)

This PR was merged into the 2.3 branch.

Discussion
----------

[Yaml] do not remove "comments" in scalar blocks

| Q             | A
| ------------- | ---
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #12478, #15857
| License       | MIT
| Doc PR        |

Inside scalar blocks, lines starting with a `#` character must be
treated like every other strings and must not be ignored as comments.

Commits
-------

3c72fcc [Yaml] do not remove "comments" in scalar blocks
This commit is contained in:
Fabien Potencier 2015-12-18 17:24:33 +01:00
commit 8d010230ef
2 changed files with 116 additions and 6 deletions

View File

@ -303,6 +303,7 @@ class Parser
private function getNextEmbedBlock($indentation = null, $inSequence = false)
{
$oldLineIndentation = $this->getCurrentLineIndentation();
$insideBlockScalar = $this->isBlockScalarHeader();
if (!$this->moveToNextLine()) {
return;
@ -339,17 +340,21 @@ class Parser
$isItUnindentedCollection = $this->isStringUnIndentedCollectionItem();
// Comments must not be removed inside a block scalar
$removeCommentsPattern = '~'.self::BLOCK_SCALAR_HEADER_PATTERN.'$~';
$removeComments = !preg_match($removeCommentsPattern, $this->currentLine);
if (!$insideBlockScalar) {
$insideBlockScalar = $this->isBlockScalarHeader();
}
$previousLineIndentation = $this->getCurrentLineIndentation();
while ($this->moveToNextLine()) {
$indent = $this->getCurrentLineIndentation();
if ($indent === $newIndent) {
$removeComments = !preg_match($removeCommentsPattern, $this->currentLine);
if (!$insideBlockScalar && $indent === $previousLineIndentation) {
$insideBlockScalar = $this->isBlockScalarHeader();
}
$previousLineIndentation = $indent;
if ($isItUnindentedCollection && !$this->isStringUnIndentedCollectionItem() && $newIndent === $indent) {
$this->moveToPreviousLine();
break;
@ -360,7 +365,8 @@ class Parser
continue;
}
if ($removeComments && $this->isCurrentLineComment()) {
// we ignore "comment" lines only when we are not inside a scalar block
if (!$insideBlockScalar && $this->isCurrentLineComment()) {
continue;
}
@ -672,4 +678,14 @@ class Parser
{
return 0 === strpos($this->currentLine, '- ');
}
/**
* Tests whether or not the current line is the header of a block scalar.
*
* @return bool
*/
private function isBlockScalarHeader()
{
return (bool) preg_match('~'.self::BLOCK_SCALAR_HEADER_PATTERN.'$~', $this->currentLine);
}
}

View File

@ -726,6 +726,100 @@ EOF;
$this->assertEquals($expected, $this->parser->parse($yaml));
}
/**
* @dataProvider getCommentLikeStringInScalarBlockData
*/
public function testCommentLikeStringsAreNotStrippedInBlockScalars($yaml, $expectedParserResult)
{
$this->assertSame($expectedParserResult, $this->parser->parse($yaml));
}
public function getCommentLikeStringInScalarBlockData()
{
$yaml1 = <<<EOT
pages:
-
title: some title
content: |
# comment 1
header
# comment 2
<body>
<h1>title</h1>
</body>
footer # comment3
EOT;
$expected1 = array(
'pages' => array(
array(
'title' => 'some title',
'content' => <<<EOT
# comment 1
header
# comment 2
<body>
<h1>title</h1>
</body>
footer # comment3
EOT
,
),
),
);
$yaml2 = <<<EOT
test: |
foo
# bar
baz
collection:
- one: |
foo
# bar
baz
- two: |
foo
# bar
baz
EOT;
$expected2 = array(
'test' => <<<EOT
foo
# bar
baz
EOT
,
'collection' => array(
array(
'one' => <<<EOT
foo
# bar
baz
EOT
,
),
array(
'two' => <<<EOT
foo
# bar
baz
EOT
,
),
),
);
return array(
array($yaml1, $expected1),
array($yaml2, $expected2),
);
}
}
class B