Skip to content

Commit

Permalink
[Yaml] fix overwriting of keys after merged map
Browse files Browse the repository at this point in the history
fixes #11142
  • Loading branch information
Tobion committed Jun 19, 2014
1 parent 8c621ab commit dee1562
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 11 deletions.
17 changes: 8 additions & 9 deletions src/Symfony/Component/Yaml/Parser.php
Expand Up @@ -66,6 +66,7 @@ public function parse($value, $exceptionOnInvalidType = false, $objectSupport =

$data = array();
$context = null;
$allowOverwrite = false;
while ($this->moveToNextLine()) {
if ($this->isCurrentLineEmpty()) {
continue;
Expand Down Expand Up @@ -133,6 +134,7 @@ public function parse($value, $exceptionOnInvalidType = false, $objectSupport =

if ('<<' === $key) {
$mergeNode = true;
$allowOverwrite = true;
if (isset($values['value']) && 0 === strpos($values['value'], '*')) {
$refName = substr($values['value'], 1);
if (!array_key_exists($refName, $this->refs)) {
Expand Down Expand Up @@ -202,9 +204,8 @@ public function parse($value, $exceptionOnInvalidType = false, $objectSupport =
// if next line is less indented or equal, then it means that the current value is null
if (!$this->isNextLineIndented() && !$this->isNextLineUnIndentedCollection()) {
// Spec: Keys MUST be unique; first one wins.
// Parser cannot abort this mapping earlier, since lines
// are processed sequentially.
if (!isset($data[$key])) {
// But overwriting is allowed when a merge node is used in current block.
if ($allowOverwrite || !isset($data[$key])) {
$data[$key] = null;
}
} else {
Expand All @@ -213,18 +214,16 @@ public function parse($value, $exceptionOnInvalidType = false, $objectSupport =
$parser->refs =& $this->refs;
$value = $parser->parse($this->getNextEmbedBlock(), $exceptionOnInvalidType, $objectSupport);
// Spec: Keys MUST be unique; first one wins.
// Parser cannot abort this mapping earlier, since lines
// are processed sequentially.
if (!isset($data[$key])) {
// But overwriting is allowed when a merge node is used in current block.
if ($allowOverwrite || !isset($data[$key])) {
$data[$key] = $value;
}
}
} else {
$value = $this->parseValue($values['value'], $exceptionOnInvalidType, $objectSupport);
// Spec: Keys MUST be unique; first one wins.
// Parser cannot abort this mapping earlier, since lines
// are processed sequentially.
if (!isset($data[$key])) {
// But overwriting is allowed when a merge node is used in current block.
if ($allowOverwrite || !isset($data[$key])) {
$data[$key] = $value;
}
}
Expand Down
20 changes: 18 additions & 2 deletions src/Symfony/Component/Yaml/Tests/Fixtures/sfMergeKey.yml
Expand Up @@ -10,11 +10,19 @@ yaml: |
a: Steve
b: Clark
c: Brian
bar: &bar
bar:
a: before
d: other
<<: *foo
b: new
x: Oren
c:
foo: bar
foo: ignore
bar: foo
duplicate:
foo: bar
foo: ignore
foo2: &foo2
a: Ballmer
ding: &dong [ fi, fei, fo, fam]
Expand All @@ -26,4 +34,12 @@ yaml: |
head:
<<: [ *foo , *dong , *foo2 ]
php: |
array('foo' => array('a' => 'Steve', 'b' => 'Clark', 'c' => 'Brian'), 'bar' => array('a' => 'before', 'd' => 'other', 'b' => 'Clark', 'c' => 'Brian', 'x' => 'Oren'), 'foo2' => array('a' => 'Ballmer'), 'ding' => array('fi', 'fei', 'fo', 'fam'), 'check' => array('a' => 'Steve', 'b' => 'Clark', 'c' => 'Brian', 'fi', 'fei', 'fo', 'fam', 'isit' => 'tested'), 'head' => array('a' => 'Steve', 'b' => 'Clark', 'c' => 'Brian', 'fi', 'fei', 'fo', 'fam'))
array(
'foo' => array('a' => 'Steve', 'b' => 'Clark', 'c' => 'Brian'),
'bar' => array('a' => 'before', 'd' => 'other', 'b' => 'new', 'c' => array('foo' => 'bar', 'bar' => 'foo'), 'x' => 'Oren'),
'duplicate' => array('foo' => 'bar'),
'foo2' => array('a' => 'Ballmer'),
'ding' => array('fi', 'fei', 'fo', 'fam'),
'check' => array('a' => 'Steve', 'b' => 'Clark', 'c' => 'Brian', 'fi', 'fei', 'fo', 'fam', 'isit' => 'tested'),
'head' => array('a' => 'Steve', 'b' => 'Clark', 'c' => 'Brian', 'fi', 'fei', 'fo', 'fam')
)

0 comments on commit dee1562

Please sign in to comment.