8000 Merge branch '2.8' into 3.3 · symfony/symfony@01644c5 · GitHub
[go: up one dir, main page]

Skip to content

Commit 01644c5

Browse files
commi 8000 tted
Merge branch '2.8' into 3.3
* 2.8: [Yaml] parse references on merge keys
2 parents 7a4fe8c + 4e897a2 commit 01644c5

File tree

2 files changed

+37
-6
lines changed

2 files changed

+37
-6
lines changed

src/Symfony/Component/Yaml/Parser.php

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ private function doParse($value, $flags)
246246
$key = (string) $key;
247247
}
248248

249-
if ('<<' === $key) {
249+
if ('<<' === $key && (!isset($values['value']) || !self::preg_match('#^&(?P<ref>[^ ]+)#u', $values['value'], $refMatches))) {
250250
$mergeNode = true;
251251
$allowOverwrite = true;
252252
if (isset($values['value'][0]) && '*' === $values['value'][0]) {
@@ -303,15 +303,15 @@ private function doParse($value, $flags)
303303
$data += $parsed; // array union
304304
}
305305
}
306-
} elseif (isset($values['value']) && self::preg_match('#^&(?P<ref>[^ ]++) *+(?P<value>.*)#u', $values['value'], $matches)) {
306+
} elseif ('<<' !== $key && isset($values['value']) && self::preg_match('#^&(?P<ref>[^ ]++) *+(?P<value>.*)#u', $values['value'], $matches)) {
307307
$isRef = $matches['ref'];
308308
$values['value'] = $matches['value'];
309309
}
310310

311311
$subTag = null;
312312
if ($mergeNode) {
313313
// Merge keys
314-
} elseif (!isset($values['value']) || '' === $values['value'] || 0 === strpos($values['value'], '#') || (null !== $subTag = $this->getLineTag($values['value'], $flags))) {
314+
} elseif (!isset($values['value']) || '' === $values['value'] || 0 === strpos($values['value'], '#') || (null !== $subTag = $this->getLineTag($values['value'], $flags)) || '<<' === $key) {
315315
// hash
316316
// if next line is less indented or equal, then it means that the current value is null
317317
if (!$this->isNextLineIndented() && !$this->isNextLineUnIndentedCollection()) {
@@ -330,9 +330,12 @@ private function doParse($value, $flags)
330330
// remember the parsed line number here in case we need it to provide some contexts in error messages below
331331
$realCurrentLineNbKey = $this->getRealCurrentLineNb();
332332
$value = $this->parseBlock($this->getRealCurrentLineNb() + 1, $this->getNextEmbedBlock(), $flags);
333-
// Spec: Keys MUST be unique; first one wins.
334-
// But overwriting is allowed when a merge node is used in current block.
335-
if ($allowOverwrite || !isset($data[$key])) {
333+
if ('<<' === $key) {
334+
$this->refs[$refMatches['ref']] = $value;
335+
$data += $value;
336+
} elseif ($allowOverwrite || !isset($data[$key])) {
337+
// Spec: Keys MUST be unique; first one wins.
338+
// But overwriting is allowed when a merge node is used in current block.
336339
if (null !== $subTag) {
337340
$data[$key] = new TaggedValue($subTag, $value);
338341
} else {

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

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1913,6 +1913,34 @@ public function testMergeKeysWhenMappingsAreParsedAsObjects()
19131913

19141914
$this->assertEquals($expected, $this->parser->parse($yaml, Yaml::PARSE_OBJECT_FOR_MAP));
19151915
}
1916+
1917+
public function testParseReferencesOnMergeKeys()
1918+
{
1919+
$yaml = <<<YAML
1920+
mergekeyrefdef:
1921+
a: foo
1922+
<<: &quux
1923+
b: bar
1924+
c: baz
1925+
mergekeyderef:
1926+
d: quux
1927+
<<: *quux
1928+
YAML;
1929+
$expected = array(
1930+
'mergekeyrefdef' => array(
1931+
'a' => 'foo',
1932+
'b' => 'bar',
1933+
'c' => 'baz',
1934+
),
1935+
'mergekeyderef' => array(
1936+
'd' => 'quux',
1937+
'b' => 'bar',
1938+
'c' => 'baz',
1939+
),
1940+
);
1941+
1942+
$this->assertSame($expected, $this->parser->parse($yaml));
1943+
}
19161944
}
19171945

19181946
class B

0 commit comments

Comments
 (0)
0