8000 bug #40514 [Yaml] Allow tabs as separators between tokens (bertramakers) · symfony/symfony@df6b1eb · GitHub
[go: up one dir, main page]

Skip to content

Commit df6b1eb

Browse files
committed
bug #40514 [Yaml] Allow tabs as separators between tokens (bertramakers)
This PR was merged into the 4.4 branch. Discussion ---------- [Yaml] Allow tabs as separators between tokens | Q | A | ------------- | --- | Branch? | 4.4 | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | Fix #40507 | License | MIT | Doc PR | None As described in #40507, the Yaml spec allows tabs as whitespace characters between tokens. However, the Yaml parser crashes on this as it only expects spaces after the colon. https://yaml.org/spec/1.2/spec.html#id2778241 While I'm not a huge fan of it personally, it's an issue when a different linter tells us that a given YAML file with content that we have little control over has valid syntax in an unrelated check, and then our app crashes because it cannot be parsed after all. Commits ------- 9a130ae Fix issue 40507: Tabs as separators between tokens
2 parents f8518ca + 9a130ae commit df6b1eb

File tree

2 files changed

+58
-17
lines changed

2 files changed

+58
-17
lines changed

src/Symfony/Component/Yaml/Parser.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ private function doParse(string $value, int $flags)
209209
array_pop($this->refsBeingParsed);
210210
}
211211
} elseif (
212-
self::preg_match('#^(?P<key>(?:![^\s]++\s++)?(?:'.Inline::REGEX_QUOTED_STRING.'|(?:!?!php/const:)?[^ \'"\[\{!].*?)) *\:( ++(?P<value>.+))?$#u', rtrim($this->currentLine), $values)
212+
self::preg_match('#^(?P<key>(?:![^\s]++\s++)?(?:'.Inline::REGEX_QUOTED_STRING.'|(?:!?!php/const:)?[^ \'"\[\{!].*?)) *\:(( |\t)++(?P<value>.+))?$#u', rtrim($this->currentLine), $values)
213213
&& (false === strpos($values['key'], ' #') || \in_array($values['key'][0], ['"', "'"]))
214214
) {
215215
if ($context && 'sequence' == $context) {

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

Lines changed: 57 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -52,26 +52,67 @@ public function getNonStringMappingKeysData()
5252
return $this->loadTestsFromFixtureFiles('nonStringKeys.yml');
5353
}
5454

55-
public function testTabsInYaml()
55+
/**
56+
* @dataProvider invalidIndentation
57+
*/
58+
public function testTabsAsIndentationInYaml(string $given, string $expectedMessage)
5659
{
57-
// test tabs in YAML
58-
$yamls = [
59-
"foo:\n bar",
60-
"foo:\n bar",
61-
"foo:\n bar",
62-
"foo:\n bar",
60+
$this->expectException(ParseException::class);
61+
$this->expectExceptionMessage($expectedMessage);
62+
$this->parser->parse($given);
63+
}
64+
65+
public function invalidIndentation(): array
66+
{
67+
return [
68+
[
69+
"foo:\n\tbar",
70+
"A YAML file cannot contain tabs as indentation at line 2 (near \"\tbar\").",
71+
],
72+
[
73+
"foo:\n \tbar",
74+
"A YAML file cannot contain tabs as indentation at line 2 (near \"\tbar\").",
75+
],
76+
[
77+
"foo:\n\t bar",
78+
"A YAML file cannot contain tabs as indentation at line 2 (near \"\t bar\").",
79+
],
80+
[
81+
"foo:\n \t bar",
82+
"A YAML file cannot contain tabs as indentation at line 2 (near \"\t bar\").",
83+
],
6384
];
85+
}
6486

65-
foreach ($yamls as $yaml) {
66-
try {
67-
$this->parser->parse($yaml);
87+
/**
88+
* @dataProvider validTokenSeparators
89+
*/
90+
public function testValidTokenSeparation(string $given, array $expected)
91+
{
92+
$actual = $this->parser->parse($given);
93+
$this->assertEquals($expected, $actual);
94+
}
6895

69-
$this->fail('YAML files must not contain tabs');
70-
} catch (\Exception $e) {
71-
$this->assertInstanceOf(\Exception::class, $e, 'YAML files must not contain tabs');
72-
$this->assertEquals('A YAML file cannot contain tabs as indentation at line 2 (near "'.strpbrk($yaml, "\t").'").', $e->getMessage(), 'YAML files must not contain tabs');
73-
}
74-
}
96+
public function validTokenSeparators(): array
97+
{
98+
return [
99+
[
100+
'foo: bar',
101+
['foo' => 'bar'],
102+
],
103+
[
104+
"foo:\tbar",
105+
['foo' => 'bar'],
106+
],
107+
[
108+
"foo: \tbar",
109+
['foo' => 'bar'],
110+
],
111+
[
112+
"foo:\t bar",
113+
['foo' => 'bar'],
114+
],
115+
];
75116
}
76117

77118
public function testEndOfTheDocumentMarker()

0 commit comments

Comments
 (0)
0