From a95cf5ee1d09e032d929f87a1b24edefe7f7506b Mon Sep 17 00:00:00 2001 From: Alex Pott Date: Sat, 13 Jan 2018 21:35:11 +0000 Subject: [PATCH 01/10] Add a failing test case --- .../Component/Yaml/Tests/ParserTest.php | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/Symfony/Component/Yaml/Tests/ParserTest.php b/src/Symfony/Component/Yaml/Tests/ParserTest.php index 8090bd37bbad1..96cabf2d7566d 100644 --- a/src/Symfony/Component/Yaml/Tests/ParserTest.php +++ b/src/Symfony/Component/Yaml/Tests/ParserTest.php @@ -776,6 +776,25 @@ public function testSequenceFollowedByCommentEmbeddedInMapping() $this->assertSame($expected, $this->parser->parse($yaml)); } + public function testEmptyArrayFollowedByCommentEmbeddedInMapping() + { + $yaml = <<<'EOT' +a: + b: + {} +# comment + d: e +EOT; + $expected = array( + 'a' => array( + 'b' => array(), + 'd' => 'e', + ), + ); + + $this->assertSame($expected, $this->parser->parse($yaml)); + } + /** * @expectedException \Symfony\Component\Yaml\Exception\ParseException */ From 231c84465ddbe5683c33f03283b365b7eeb9bf50 Mon Sep 17 00:00:00 2001 From: Alex Pott Date: Sat, 13 Jan 2018 22:06:16 +0000 Subject: [PATCH 02/10] A fix? --- src/Symfony/Component/Yaml/Parser.php | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/Symfony/Component/Yaml/Parser.php b/src/Symfony/Component/Yaml/Parser.php index 752d2d30fd0f9..ff9ce2b5cee4c 100644 --- a/src/Symfony/Component/Yaml/Parser.php +++ b/src/Symfony/Component/Yaml/Parser.php @@ -397,16 +397,7 @@ private function doParse($value, $flags) foreach ($this->lines as $line) { try { - if (isset($line[0]) && ('"' === $line[0] || "'" === $line[0])) { - $parsedLine = $line; - } else { - $parsedLine = Inline::parse($line, $flags, $this->refs); - } - - if (!is_string($parsedLine)) { - $parseError = true; - break; - } + $parsedLine = $line; if ('' === trim($parsedLine)) { $value .= "\n"; From 4b22592a0c8cadbe8e79e4f5c4a23cabe44fb912 Mon Sep 17 00:00:00 2001 From: Alex Pott Date: Sat, 13 Jan 2018 22:16:00 +0000 Subject: [PATCH 03/10] A less disruptive fix --- src/Symfony/Component/Yaml/Parser.php | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Yaml/Parser.php b/src/Symfony/Component/Yaml/Parser.php index ff9ce2b5cee4c..5fbe97d728a89 100644 --- a/src/Symfony/Component/Yaml/Parser.php +++ b/src/Symfony/Component/Yaml/Parser.php @@ -397,7 +397,24 @@ private function doParse($value, $flags) foreach ($this->lines as $line) { try { - $parsedLine = $line; + if (isset($line[0]) && ('"' === $line[0] || "'" === $line[0])) { + $parsedLine = $line; + } else { + $parsedLine = Inline::parse($line, $flags, $this->refs); + } + + // There is a special case where an empty array + // followed by a comment causes us to try to parse + // the value as a multi-line string. In this + // instance, return the empty array + if ([] === $parsedLine) { + return $parsedLine; + } + + if (!is_string($parsedLine)) { + $parseError = true; + break; + } if ('' === trim($parsedLine)) { $value .= "\n"; From 582e6ad6d329d0db9d5d643e7c584db3e738d701 Mon Sep 17 00:00:00 2001 From: Alex Pott Date: Sat, 13 Jan 2018 22:16:47 +0000 Subject: [PATCH 04/10] Coding standards --- src/Symfony/Component/Yaml/Parser.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Yaml/Parser.php b/src/Symfony/Component/Yaml/Parser.php index 5fbe97d728a89..db8222bb2ef69 100644 --- a/src/Symfony/Component/Yaml/Parser.php +++ b/src/Symfony/Component/Yaml/Parser.php @@ -407,7 +407,7 @@ private function doParse($value, $flags) // followed by a comment causes us to try to parse // the value as a multi-line string. In this // instance, return the empty array - if ([] === $parsedLine) { + if (array() === $parsedLine) { return $parsedLine; } From ade75b5b5be114f51d5aee4475722cf4627eb736 Mon Sep 17 00:00:00 2001 From: Alex Pott Date: Sat, 13 Jan 2018 22:21:10 +0000 Subject: [PATCH 05/10] Proof this not just about empty arrays --- src/Symfony/Component/Yaml/Tests/ParserTest.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Yaml/Tests/ParserTest.php b/src/Symfony/Component/Yaml/Tests/ParserTest.php index 96cabf2d7566d..0825af260dccd 100644 --- a/src/Symfony/Component/Yaml/Tests/ParserTest.php +++ b/src/Symfony/Component/Yaml/Tests/ParserTest.php @@ -776,19 +776,21 @@ public function testSequenceFollowedByCommentEmbeddedInMapping() $this->assertSame($expected, $this->parser->parse($yaml)); } - public function testEmptyArrayFollowedByCommentEmbeddedInMapping() + public function testNonStringFollowedByCommentEmbeddedInMapping() { $yaml = <<<'EOT' a: b: {} # comment - d: e + d: + 1.1 +# another comment EOT; $expected = array( 'a' => array( 'b' => array(), - 'd' => 'e', + 'd' => 1.1, ), ); From ee6adadbe27e66454c0e40049190cc4e379b000e Mon Sep 17 00:00:00 2001 From: Alex Pott Date: Sat, 13 Jan 2018 22:22:34 +0000 Subject: [PATCH 06/10] Fix the new test but break a test that expects an specific exception --- src/Symfony/Component/Yaml/Parser.php | 33 ++++++--------------------- 1 file changed, 7 insertions(+), 26 deletions(-) diff --git a/src/Symfony/Component/Yaml/Parser.php b/src/Symfony/Component/Yaml/Parser.php index db8222bb2ef69..75a6744237b44 100644 --- a/src/Symfony/Component/Yaml/Parser.php +++ b/src/Symfony/Component/Yaml/Parser.php @@ -397,41 +397,22 @@ private function doParse($value, $flags) foreach ($this->lines as $line) { try { - if (isset($line[0]) && ('"' === $line[0] || "'" === $line[0])) { - $parsedLine = $line; - } else { - $parsedLine = Inline::parse($line, $flags, $this->refs); - } - - // There is a special case where an empty array - // followed by a comment causes us to try to parse - // the value as a multi-line string. In this - // instance, return the empty array - if (array() === $parsedLine) { - return $parsedLine; - } - - if (!is_string($parsedLine)) { - $parseError = true; - break; - } - - if ('' === trim($parsedLine)) { + if ('' === trim($line)) { $value .= "\n"; } elseif (!$previousLineWasNewline && !$previousLineWasTerminatedWithBackslash) { $value .= ' '; } - if ('' !== trim($parsedLine) && '\\' === substr($parsedLine, -1)) { - $value .= ltrim(substr($parsedLine, 0, -1)); - } elseif ('' !== trim($parsedLine)) { - $value .= trim($parsedLine); + if ('' !== trim($line) && '\\' === substr($line, -1)) { + $value .= ltrim(substr($line, 0, -1)); + } elseif ('' !== trim($line)) { + $value .= trim($line); } - if ('' === trim($parsedLine)) { + if ('' === trim($line)) { $previousLineWasNewline = true; $previousLineWasTerminatedWithBackslash = false; - } elseif ('\\' === substr($parsedLine, -1)) { + } elseif ('\\' === substr($line, -1)) { $previousLineWasNewline = false; $previousLineWasTerminatedWithBackslash = true; } else { From 2508c83426658cd92ce63f30efa80a750879e0b2 Mon Sep 17 00:00:00 2001 From: Alex Pott Date: Sun, 14 Jan 2018 07:30:05 +0000 Subject: [PATCH 07/10] Fix which exception is thrown --- src/Symfony/Component/Yaml/Parser.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Yaml/Parser.php b/src/Symfony/Component/Yaml/Parser.php index 75a6744237b44..6b273429e10b2 100644 --- a/src/Symfony/Component/Yaml/Parser.php +++ b/src/Symfony/Component/Yaml/Parser.php @@ -426,7 +426,12 @@ private function doParse($value, $flags) } if (!$parseError) { - return Inline::parse(trim($value)); + try { + return Inline::parse(trim($value)); + } + catch (ParseException $e) { + // fall-through to the ParseException thrown below + } } } From f841111616cc49e2f25361df312a527a55c0dd6a Mon Sep 17 00:00:00 2001 From: Alex Pott Date: Sun, 14 Jan 2018 07:30:41 +0000 Subject: [PATCH 08/10] Coding standards --- src/Symfony/Component/Yaml/Parser.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Symfony/Component/Yaml/Parser.php b/src/Symfony/Component/Yaml/Parser.php index 6b273429e10b2..8f2fac056cfbe 100644 --- a/src/Symfony/Component/Yaml/Parser.php +++ b/src/Symfony/Component/Yaml/Parser.php @@ -428,8 +428,7 @@ private function doParse($value, $flags) if (!$parseError) { try { return Inline::parse(trim($value)); - } - catch (ParseException $e) { + } catch (ParseException $e) { // fall-through to the ParseException thrown below } } From 4f0c9631bd8ad78f3114ebf330249293a39d8488 Mon Sep 17 00:00:00 2001 From: Alex Pott Date: Sun, 14 Jan 2018 07:34:51 +0000 Subject: [PATCH 09/10] Remove dead code --- src/Symfony/Component/Yaml/Parser.php | 54 ++++++++++++--------------- 1 file changed, 23 insertions(+), 31 deletions(-) diff --git a/src/Symfony/Component/Yaml/Parser.php b/src/Symfony/Component/Yaml/Parser.php index 8f2fac056cfbe..4721a7ea6ec5c 100644 --- a/src/Symfony/Component/Yaml/Parser.php +++ b/src/Symfony/Component/Yaml/Parser.php @@ -390,47 +390,39 @@ private function doParse($value, $flags) // try to parse the value as a multi-line string as a last resort if (0 === $this->currentLineNb) { - $parseError = false; $previousLineWasNewline = false; $previousLineWasTerminatedWithBackslash = false; $value = ''; foreach ($this->lines as $line) { - try { - if ('' === trim($line)) { - $value .= "\n"; - } elseif (!$previousLineWasNewline && !$previousLineWasTerminatedWithBackslash) { - $value .= ' '; - } + if ('' === trim($line)) { + $value .= "\n"; + } elseif (!$previousLineWasNewline && !$previousLineWasTerminatedWithBackslash) { + $value .= ' '; + } - if ('' !== trim($line) && '\\' === substr($line, -1)) { - $value .= ltrim(substr($line, 0, -1)); - } elseif ('' !== trim($line)) { - $value .= trim($line); - } + if ('' !== trim($line) && '\\' === substr($line, -1)) { + $value .= ltrim(substr($line, 0, -1)); + } elseif ('' !== trim($line)) { + $value .= trim($line); + } - if ('' === trim($line)) { - $previousLineWasNewline = true; - $previousLineWasTerminatedWithBackslash = false; - } elseif ('\\' === substr($line, -1)) { - $previousLineWasNewline = false; - $previousLineWasTerminatedWithBackslash = true; - } else { - $previousLineWasNewline = false; - $previousLineWasTerminatedWithBackslash = false; - } - } catch (ParseException $e) { - $parseError = true; - break; + if ('' === trim($line)) { + $previousLineWasNewline = true; + $previousLineWasTerminatedWithBackslash = false; + } elseif ('\\' === substr($line, -1)) { + $previousLineWasNewline = false; + $previousLineWasTerminatedWithBackslash = true; + } else { + $previousLineWasNewline = false; + $previousLineWasTerminatedWithBackslash = false; } } - if (!$parseError) { - try { - return Inline::parse(trim($value)); - } catch (ParseException $e) { - // fall-through to the ParseException thrown below - } + try { + return Inline::parse(trim($value)); + } catch (ParseException $e) { + // fall-through to the ParseException thrown below } } From b592fad536a1d07da599039cce4dfd474f4c7cf3 Mon Sep 17 00:00:00 2001 From: Alex Pott Date: Sat, 20 Jan 2018 21:53:13 +0000 Subject: [PATCH 10/10] Add related test --- src/Symfony/Component/Yaml/Tests/ParserTest.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/Symfony/Component/Yaml/Tests/ParserTest.php b/src/Symfony/Component/Yaml/Tests/ParserTest.php index 0825af260dccd..ca7bd0f244977 100644 --- a/src/Symfony/Component/Yaml/Tests/ParserTest.php +++ b/src/Symfony/Component/Yaml/Tests/ParserTest.php @@ -797,6 +797,21 @@ public function testNonStringFollowedByCommentEmbeddedInMapping() $this->assertSame($expected, $this->parser->parse($yaml)); } + public function testMultiLineStringLastResortParsing() + { + $yaml = <<<'EOT' +test: + You can have things that don't look like strings here + true + yes you can +EOT; + $expected = array( + 'test' => 'You can have things that don\'t look like strings here true yes you can', + ); + + $this->assertSame($expected, $this->parser->parse($yaml)); + } + /** * @expectedException \Symfony\Component\Yaml\Exception\ParseException */