Skip to content

[Yaml] Fix wrong line number when comments are inserted in the middle of a block. #17733

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

50 changes: 49 additions & 1 deletion src/Symfony/Component/Yaml/Parser.php
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,7 @@ private function getNextEmbedBlock($indentation = null, $inSequence = false)
}

// we ignore "comment" lines only when we are not inside a scalar block
if (empty($blockScalarIndentations) && $this->isCurrentLineComment()) {
if (empty($blockScalarIndentations) && $this->isCurrentLineComment() && false === $this->checkIfPreviousNonCommentLineIsCollectionItem()) {
continue;
}

Expand Down Expand Up @@ -484,10 +484,18 @@ private function moveToNextLine()

/**
* Moves the parser to the previous line.
*
* @return bool
*/
private function moveToPreviousLine()
{
if ($this->currentLineNb < 1) {
return false;
}

$this->currentLine = $this->lines[--$this->currentLineNb];

return true;
}

/**
Expand Down Expand Up @@ -804,4 +812,44 @@ private function isBlockScalarHeader()
{
return (bool) preg_match('~'.self::BLOCK_SCALAR_HEADER_PATTERN.'$~', $this->currentLine);
}

/**
* Returns true if the current line is a collection item.
*
* @return bool
*/
private function isCurrentLineCollectionItem()
{
$ltrimmedLine = ltrim($this->currentLine, ' ');

return '' !== $ltrimmedLine && '-' === $ltrimmedLine[0];
}

/**
* Tests whether the current comment line is in a collection.
*
* @return bool
*/
private function checkIfPreviousNonCommentLineIsCollectionItem()
{
$isCollectionItem = false;
$moves = 0;
while ($this->moveToPreviousLine()) {
++$moves;
// If previous line is a comment, move back again.
if ($this->isCurrentLineComment()) {
continue;
}
$isCollectionItem = $this->isCurrentLineCollectionItem();
break;
}

// Move parser back to previous line.
while ($moves > 0) {
$this->moveToNextLine();
--$moves;
}

return $isCollectionItem;
}
}
68 changes: 68 additions & 0 deletions src/Symfony/Component/Yaml/Tests/ParserTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1201,6 +1201,74 @@ public function getInvalidBinaryData()
),
);
}

/**
* @param $lineNumber
* @param $yaml
* @dataProvider parserThrowsExceptionWithCorrectLineNumberProvider
*/
public function testParserThrowsExceptionWithCorrectLineNumber($lineNumber, $yaml)
{
$this->setExpectedException(
'\Symfony\Component\Yaml\Exception\ParseException',
sprintf('Unexpected characters near "," at line %d (near "bar: "123",").', $lineNumber)
);

$this->parser->parse($yaml);
}

public function parserThrowsExceptionWithCorrectLineNumberProvider()
{
return array(
array(
4,
<<<YAML
foo:
-
# bar
bar: "123",
YAML
),
array(
5,
<<<YAML
foo:
-
# bar
# bar
bar: "123",
YAML
),
array(
8,
<<<YAML
foo:
-
# foobar
baz: 123
bar:
-
# bar
bar: "123",
YAML
),
array(
10,
<<<YAML
foo:
-
# foobar
# foobar
baz: 123
bar:
-
# bar
# bar
bar: "123",
YAML
),
);
}
}

class B
Expand Down