[Yaml] fix overwriting of keys after merged map
fixes symfony/symfony#11142
This commit is contained in:
parent
8c621ab4b5
commit
dee15623ae
@ -66,6 +66,7 @@ class Parser
|
|||||||
|
|
||||||
$data = array();
|
$data = array();
|
||||||
$context = null;
|
$context = null;
|
||||||
|
$allowOverwrite = false;
|
||||||
while ($this->moveToNextLine()) {
|
while ($this->moveToNextLine()) {
|
||||||
if ($this->isCurrentLineEmpty()) {
|
if ($this->isCurrentLineEmpty()) {
|
||||||
continue;
|
continue;
|
||||||
@ -133,6 +134,7 @@ class Parser
|
|||||||
|
|
||||||
if ('<<' === $key) {
|
if ('<<' === $key) {
|
||||||
$mergeNode = true;
|
$mergeNode = true;
|
||||||
|
$allowOverwrite = true;
|
||||||
if (isset($values['value']) && 0 === strpos($values['value'], '*')) {
|
if (isset($values['value']) && 0 === strpos($values['value'], '*')) {
|
||||||
$refName = substr($values['value'], 1);
|
$refName = substr($values['value'], 1);
|
||||||
if (!array_key_exists($refName, $this->refs)) {
|
if (!array_key_exists($refName, $this->refs)) {
|
||||||
@ -202,9 +204,8 @@ class Parser
|
|||||||
// if next line is less indented or equal, then it means that the current value is null
|
// if next line is less indented or equal, then it means that the current value is null
|
||||||
if (!$this->isNextLineIndented() && !$this->isNextLineUnIndentedCollection()) {
|
if (!$this->isNextLineIndented() && !$this->isNextLineUnIndentedCollection()) {
|
||||||
// Spec: Keys MUST be unique; first one wins.
|
// Spec: Keys MUST be unique; first one wins.
|
||||||
// Parser cannot abort this mapping earlier, since lines
|
// But overwriting is allowed when a merge node is used in current block.
|
||||||
// are processed sequentially.
|
if ($allowOverwrite || !isset($data[$key])) {
|
||||||
if (!isset($data[$key])) {
|
|
||||||
$data[$key] = null;
|
$data[$key] = null;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -213,18 +214,16 @@ class Parser
|
|||||||
$parser->refs =& $this->refs;
|
$parser->refs =& $this->refs;
|
||||||
$value = $parser->parse($this->getNextEmbedBlock(), $exceptionOnInvalidType, $objectSupport);
|
$value = $parser->parse($this->getNextEmbedBlock(), $exceptionOnInvalidType, $objectSupport);
|
||||||
// Spec: Keys MUST be unique; first one wins.
|
// Spec: Keys MUST be unique; first one wins.
|
||||||
// Parser cannot abort this mapping earlier, since lines
|
// But overwriting is allowed when a merge node is used in current block.
|
||||||
// are processed sequentially.
|
if ($allowOverwrite || !isset($data[$key])) {
|
||||||
if (!isset($data[$key])) {
|
|
||||||
$data[$key] = $value;
|
$data[$key] = $value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$value = $this->parseValue($values['value'], $exceptionOnInvalidType, $objectSupport);
|
$value = $this->parseValue($values['value'], $exceptionOnInvalidType, $objectSupport);
|
||||||
// Spec: Keys MUST be unique; first one wins.
|
// Spec: Keys MUST be unique; first one wins.
|
||||||
// Parser cannot abort this mapping earlier, since lines
|
// But overwriting is allowed when a merge node is used in current block.
|
||||||
// are processed sequentially.
|
if ($allowOverwrite || !isset($data[$key])) {
|
||||||
if (!isset($data[$key])) {
|
|
||||||
$data[$key] = $value;
|
$data[$key] = $value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,11 +10,19 @@ yaml: |
|
|||||||
a: Steve
|
a: Steve
|
||||||
b: Clark
|
b: Clark
|
||||||
c: Brian
|
c: Brian
|
||||||
bar: &bar
|
bar:
|
||||||
a: before
|
a: before
|
||||||
d: other
|
d: other
|
||||||
<<: *foo
|
<<: *foo
|
||||||
|
b: new
|
||||||
x: Oren
|
x: Oren
|
||||||
|
c:
|
||||||
|
foo: bar
|
||||||
|
foo: ignore
|
||||||
|
bar: foo
|
||||||
|
duplicate:
|
||||||
|
foo: bar
|
||||||
|
foo: ignore
|
||||||
foo2: &foo2
|
foo2: &foo2
|
||||||
a: Ballmer
|
a: Ballmer
|
||||||
ding: &dong [ fi, fei, fo, fam]
|
ding: &dong [ fi, fei, fo, fam]
|
||||||
@ -26,4 +34,12 @@ yaml: |
|
|||||||
head:
|
head:
|
||||||
<<: [ *foo , *dong , *foo2 ]
|
<<: [ *foo , *dong , *foo2 ]
|
||||||
php: |
|
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')
|
||||||
|
)
|
||||||
|
Reference in New Issue
Block a user