From e787ecfc3f8fa42e38c90971a0624c779ed4b5c3 Mon Sep 17 00:00:00 2001 From: Anto Date: Sat, 3 Mar 2018 15:10:27 +0100 Subject: [PATCH] [Yaml] Fix regression when trying to parse multiline --- src/Symfony/Component/Yaml/Parser.php | 6 ++- .../Component/Yaml/Tests/ParserTest.php | 46 +++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Yaml/Parser.php b/src/Symfony/Component/Yaml/Parser.php index dbb6f716dee3..7446ae065cd4 100644 --- a/src/Symfony/Component/Yaml/Parser.php +++ b/src/Symfony/Component/Yaml/Parser.php @@ -402,7 +402,7 @@ private function doParse($value, $flags) throw new ParseException('Multiple documents are not supported.', $this->currentLineNb + 1, $this->currentLine, $this->filename); } - if (isset($this->currentLine[1]) && '?' === $this->currentLine[0] && ' ' === $this->currentLine[1]) { + if ($deprecatedUsage = (isset($this->currentLine[1]) && '?' === $this->currentLine[0] && ' ' === $this->currentLine[1])) { @trigger_error($this->getDeprecationMessage('Starting an unquoted string with a question mark followed by a space is deprecated since Symfony 3.3 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0.'), E_USER_DEPRECATED); } @@ -427,6 +427,10 @@ private function doParse($value, $flags) $value = ''; foreach ($this->lines as $line) { + // If the indentation is not consistent at offset 0, it is to be considered as a ParseError + if (0 === $this->offset && !$deprecatedUsage && isset($line[0]) && ' ' === $line[0]) { + throw new ParseException('Unable to parse.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename); + } if ('' === trim($line)) { $value .= "\n"; } elseif (!$previousLineWasNewline && !$previousLineWasTerminatedWithBackslash) { diff --git a/src/Symfony/Component/Yaml/Tests/ParserTest.php b/src/Symfony/Component/Yaml/Tests/ParserTest.php index 617cd22e9c73..86417ab5689a 100644 --- a/src/Symfony/Component/Yaml/Tests/ParserTest.php +++ b/src/Symfony/Component/Yaml/Tests/ParserTest.php @@ -812,6 +812,41 @@ public function testNonStringFollowedByCommentEmbeddedInMapping() $this->assertSame($expected, $this->parser->parse($yaml)); } + public function getParseExceptionNotAffectedMultiLineStringLastResortParsing() + { + $tests = array(); + + $yaml = <<<'EOT' +a + b: +EOT; + $tests['parse error on first line'] = array($yaml); + + $yaml = <<<'EOT' +a + +b + c: +EOT; + $tests['parse error due to inconsistent indentation'] = array($yaml); + + $yaml = <<<'EOT' + & * ! | > ' " % @ ` #, { asd a;sdasd }-@^qw3 +EOT; + $tests['symfony/symfony/issues/22967#issuecomment-322067742'] = array($yaml); + + return $tests; + } + + /** + * @dataProvider getParseExceptionNotAffectedMultiLineStringLastResortParsing + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + */ + public function testParseExceptionNotAffectedByMultiLineStringLastResortParsing($yaml) + { + $this->parser->parse($yaml); + } + public function testMultiLineStringLastResortParsing() { $yaml = <<<'EOT' @@ -825,6 +860,17 @@ public function testMultiLineStringLastResortParsing() ); $this->assertSame($expected, $this->parser->parse($yaml)); + + $yaml = <<<'EOT' +a: + b + c +EOT; + $expected = array( + 'a' => 'b c', + ); + + $this->assertSame($expected, $this->parser->parse($yaml)); } /**