Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit dab72ab

Browse files
committed
[Yaml] parse references on merge keys
1 parent 817f594 commit dab72ab

File tree

2 files changed

+38
-6
lines changed

2 files changed

+38
-6
lines changed

src/Symfony/Component/Yaml/Parser.php

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ private function doParse($value, $exceptionOnInvalidType = false, $objectSupport
181181
$key = (string) $key;
182182
}
183183

184-
if ('<<' === $key) {
184+
if ('<<' === $key && (!isset($values['value']) || !self::preg_match('#^&(?P<ref>[^ ]+)#u', $values['value'], $refMatches))) {
185185
$mergeNode = true;
186186
$allowOverwrite = true;
187187
if (isset($values['value']) && 0 === strpos($values['value'], '*')) {
@@ -226,14 +226,14 @@ private function doParse($value, $exceptionOnInvalidType = false, $objectSupport
226226
$data += $parsed; // array union
227227
}
228228
}
229-
} elseif (isset($values['value']) && self::preg_match('#^&(?P<ref>[^ ]+) *(?P<value>.*)#u', $values['value'], $matches)) {
229+
} elseif ('<<' !== $key && isset($values['value']) && self::preg_match('#^&(?P<ref>[^ ]+) *(?P<value>.*)#u', $values['value'], $matches)) {
230230
$isRef = $matches['ref'];
231231
$values['value'] = $matches['value'];
232232
}
233233

234234
if ($mergeNode) {
235235
// Merge keys
236-
} elseif (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#')) {
236+
} elseif (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#') || '<<' === $key) {
237237
// hash
238238
// if next line is less indented or equal, then it means that the current value is null
239239
if (!$this->isNextLineIndented() && !$this->isNextLineUnIndentedCollection()) {
@@ -244,9 +244,13 @@ private function doParse($value, $exceptionOnInvalidType = false, $objectSupport
244244
}
245245
} else {
246246
$value = $this->parseBlock($this->getRealCurrentLineNb() + 1, $this->getNextEmbedBlock(), $exceptionOnInvalidType, $objectSupport, $objectForMap);
247-
// Spec: Keys MUST be unique; first one wins.
248-
// But overwriting is allowed when a merge node is used in current block.
249-
if ($allowOverwrite || !isset($data[$key])) {
247+
248+
if ('<<' === $key) {
249+
$this->refs[$refMatches['ref']] = $value;
250+
$data += $value;
251+
} elseif ($allowOverwrite || !isset($data[$key])) {
252+
// Spec: Keys MUST be unique; first one wins.
253+
// But overwriting is allowed when a merge node is used in current block.
250254
$data[$key] = $value;
251255
}
252256
}

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

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1179,6 +1179,34 @@ public function testParserCleansUpReferencesBetweenRuns()
11791179
YAML;
11801180
$this->parser->parse($yaml);
11811181
}
1182+
1183+
public function testParseReferencesOnMergeKeys()
1184+
{
1185+
$yaml = <<<YAML
1186+
mergekeyrefdef:
1187+
a: foo
1188+
<<: &quux
1189+
b: bar
1190+
c: baz
1191+
mergekeyderef:
1192+
d: quux
1193+
<<: *quux
1194+
YAML;
1195+
$expected = array(
1196+
'mergekeyrefdef' => array(
1197+
'a' => 'foo',
1198+
'b' => 'bar',
1199+
'c' => 'baz',
1200+
),
1201+
'mergekeyderef' => array(
1202+
'd' => 'quux',
1203+
'b' => 'bar',
1204+
'c' => 'baz',
1205+
),
1206+
);
1207+
1208+
$this->assertSame($expected, $this->parser->parse($yaml));
1209+
}
11821210
}
11831211

11841212
class B

0 commit comments

Comments
 (0)