Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 2eeb75d

Browse filesBrowse files
committed
bug #38228 [Yaml Parser] Fix edge cases when parsing multiple documents (digilist)
This PR was merged into the 3.4 branch. Discussion ---------- [Yaml Parser] Fix edge cases when parsing multiple documents | Q | A | ------------- | --- | Branch? | 4.4 | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | | License | MIT | Doc PR | I identified some edge cases when parsing multiple YAML documents with the same parser instance, because the totalNumberOfLines was not reset and so any subsequent parsing considered the number of lines of the first document. Consider this document: ```yaml a: b: | row row2 c: d ``` Normally, `a.b` would be parsed as `row\nrow2\n`. But if the parser parsed a shorter document before, the `\n` after row2 was missing, as the parser considered it as the end of the file (that's why the `c: d` at the end is important). So this fix resets the `totalNumberOfLines` in the YAML parser to `null` so that any subsequent parsing will initialize the value for the new document and does not use the file length of the first parsed document. I stumbled upon this because of a flickering unit test that was using the translation component. Sometimes the translated string contained a trailing `\n` and sometimes not. In the end it was based on this bug, as the translation files were not loaded in the same order every time (not really sure why. It's somehow related to the cache state, but even with a warm cache it was not totally deterministic). Commits ------- 012ee4f [Yaml Parser] Fix edge cases when parsing multiple documents
2 parents 74f41f3 + 012ee4f commit 2eeb75d
Copy full SHA for 2eeb75d

File tree

2 files changed

+34
-0
lines changed
Filter options

2 files changed

+34
-0
lines changed

‎src/Symfony/Component/Yaml/Parser.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Yaml/Parser.php
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ public function parse($value, $flags = 0)
153153
$this->refs = [];
154154
$this->skippedLineNumbers = [];
155155
$this->locallySkippedLineNumbers = [];
156+
$this->totalNumberOfLines = null;
156157

157158
if (null !== $e) {
158159
throw $e;

‎src/Symfony/Component/Yaml/Tests/ParserTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Yaml/Tests/ParserTest.php
+33Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2362,6 +2362,39 @@ public function testParseValueWithNegativeModifiers()
23622362
$this->parser->parse($yaml)
23632363
);
23642364
}
2365+
2366+
/**
2367+
* This is a regression test for a bug where a YAML block with a nested multiline string using | was parsed without
2368+
* a trailing \n when a shorter YAML document was parsed before.
2369+
*
2370+
* When a shorter document was parsed before, the nested string did not have a \n at the end of the string, because
2371+
* the Parser thought it was the end of the file, even though it is not.
2372+
*/
2373+
public function testParsingMultipleDocuments()
2374+
{
2375+
$shortDocument = 'foo: bar';
2376+
$longDocument = <<<YAML
2377+
a:
2378+
b: |
2379+
row
2380+
row2
2381+
c: d
2382+
YAML;
2383+
2384+
$expected = ['a' => ['b' => "row\nrow2\n"], 'c' => 'd'];
2385+
2386+
// The parser was not used before, so there is a new line after row2
2387+
$this->assertSame($expected, $this->parser->parse($longDocument));
2388+
2389+
$parser = new Parser();
2390+
// The first parsing set and fixed the totalNumberOfLines in the Parser before, so parsing the short document here
2391+
// to reproduce the issue. If the issue would not have been fixed, the next assertion will fail
2392+
$parser->parse($shortDocument);
2393+
2394+
// After the total number of lines has been rset the result will be the same as if a new parser was used
2395+
// (before, there was no \n after row2)
2396+
$this->assertSame($expected, $parser->parse($longDocument));
2397+
}
23652398
}
23662399

23672400
class B

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.