Skip to content

Commit dd26c80

Browse files
committed
substitute aliases in inline mappings
1 parent 675a3fe commit dd26c80

File tree

3 files changed

+23
-60
lines changed

3 files changed

+23
-60
lines changed

src/Symfony/Component/Yaml/Inline.php

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,7 @@ private static function parseMapping($mapping, &$i = 0, $references = array())
365365
$output = array();
366366
$len = strlen($mapping);
367367
++$i;
368+
$allowOverwrite = false;
368369

369370
// {foo: bar, bar:foo, ...}
370371
while ($i < $len) {
@@ -384,6 +385,10 @@ private static function parseMapping($mapping, &$i = 0, $references = array())
384385
// key
385386
$key = self::parseScalar($mapping, array(':', ' '), array('"', "'"), $i, false);
386387

388+
if ('<<' === $key) {
389+
$allowOverwrite = true;
390+
}
391+
387392
// value
388393
$done = false;
389394

@@ -395,7 +400,12 @@ private static function parseMapping($mapping, &$i = 0, $references = array())
395400
// Spec: Keys MUST be unique; first one wins.
396401
// Parser cannot abort this mapping earlier, since lines
397402
// are processed sequentially.
398-
if (!isset($output[$key])) {
403+
// But overwriting is allowed when a merge node is used in current block.
404+
if ('<<' === $key) {
405+
foreach ($value as $parsedValue) {
406+
$output += $parsedValue;
407+
}
408+
} elseif ($allowOverwrite || !isset($output[$key])) {
399409
$output[$key] = $value;
400410
}
401411
$done = true;
@@ -406,7 +416,10 @@ private static function parseMapping($mapping, &$i = 0, $references = array())
406416
// Spec: Keys MUST be unique; first one wins.
407417
// Parser cannot abort this mapping earlier, since lines
408418
// are processed sequentially.
409-
if (!isset($output[$key])) {
419+
// But overwriting is allowed when a merge node is used in current block.
420+
if ('<<' === $key) {
421+
$output += $value;
422+
} elseif ($allowOverwrite || !isset($output[$key])) {
410423
$output[$key] = $value;
411424
}
412425
$done = true;
@@ -419,7 +432,10 @@ private static function parseMapping($mapping, &$i = 0, $references = array())
419432
// Spec: Keys MUST be unique; first one wins.
420433
// Parser cannot abort this mapping earlier, since lines
421434
// are processed sequentially.
422-
if (!isset($output[$key])) {
435+
// But overwriting is allowed when a merge node is used in current block.
436+
if ('<<' === $key) {
437+
$output += $value;
438+
} elseif ($allowOverwrite || !isset($output[$key])) {
423439
$output[$key] = $value;
424440
}
425441
$done = true;

src/Symfony/Component/Yaml/Parser.php

Lines changed: 1 addition & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -491,59 +491,6 @@ private function moveToPreviousLine()
491491
return true;
492492
}
493493

494-
/**
495-
* Substitute from alias where is used a <<
496-
*
497-
* @param mixed $values Parsed YAML in which aliases are not substituted
498-
*
499-
* @return mixed YAML with substituted aliases
500-
*
501-
* @throws Exception\ParseException When indentation problem are detected
502-
*/
503-
private function substituteAliases($values)
504-
{
505-
if (is_array($values)) {
506-
$keys = array();
507-
foreach ($values as $key => $value) {
508-
if ($key ==='<<' && preg_grep('/^\*.+/', (array) $value) === array_values((array) $value)) {
509-
$values[$key] = array();
510-
foreach ((array) $value as $ref) {
511-
$refName = substr($ref, 1);
512-
if (!array_key_exists($refName, $this->refs)) {
513-
throw new ParseException(
514-
sprintf('Reference "%s" does not exist.', $refName),
515-
$this->getRealCurrentLineNb() + 1,
516-
$this->currentLine
517-
);
518-
}
519-
520-
$keys = array_merge(
521-
$keys,
522-
array_diff(array_keys($this->refs[$refName]), $keys)
523-
);
524-
$values[$key] = array_replace($this->refs[$refName], $values[$key]);
525-
}
526-
} elseif (!isset($result[$key]) || is_array($result[$key])) {
527-
$keys[] = $key;
528-
$values[$key] = $this->substituteAliases($value);
529-
}
530-
}
531-
532-
if (isset($values['<<'])) {
533-
$values = array_replace($values['<<'], $values);
534-
unset($values['<<']);
535-
uksort(
536-
$values,
537-
function ($a, $b) use ($keys) {
538-
return array_search($a, $keys, true) - array_search($b, $keys, true);
539-
}
540-
);
541-
}
542-
}
543-
544-
return $values;
545-
}
546-
547494
/**
548495
* Parses a YAML value.
549496
*
@@ -579,7 +526,7 @@ private function parseValue($value, $exceptionOnInvalidType, $objectSupport, $ob
579526
}
580527

581528
try {
582-
return $this->substituteAliases(Inline::parse($value, $exceptionOnInvalidType, $objectSupport, $objectForMap, $this->refs));
529+
return Inline::parse($value, $exceptionOnInvalidType, $objectSupport, $objectForMap, $this->refs);
583530
} catch (ParseException $e) {
584531
$e->setParsedLine($this->getRealCurrentLineNb() + 1);
585532
$e->setSnippet($this->currentLine);

src/Symfony/Component/Yaml/Tests/Fixtures/sfMergeKey.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,14 @@ php: |
5353
array(
5454
'foo' => array('a' => 'Steve', 'b' => 'Clark', 'c' => 'Brian', 'e' => 'notnull'),
5555
'bar' => array('a' => 'before', 'd' => 'other', 'e' => null, 'b' => 'new', 'c' => array('foo' => 'bar', 'bar' => 'foo'), 'x' => 'Oren'),
56-
'bar_inline' => array('a' => 'before', 'd' => 'other', 'b' => 'new', 'c' => array('foo' => 'bar', 'bar' => 'foo'), 'x' => 'Oren'),
56+
'bar_inline' => array('a' => 'before', 'd' => 'other', 'b' => 'new', 'c' => array('foo' => 'bar', 'bar' => 'foo'), 'e' => 'notnull', 'x' => 'Oren'),
5757
'duplicate' => array('foo' => 'bar'),
5858
'foo2' => array('a' => 'Ballmer'),
5959
'ding' => array('fi', 'fei', 'fo', 'fam'),
6060
'check' => array('a' => 'Steve', 'b' => 'Clark', 'c' => 'Brian', 'e' => 'notnull', 'fi', 'fei', 'fo', 'fam', 'isit' => 'tested'),
6161
'head' => array('a' => 'Steve', 'b' => 'Clark', 'c' => 'Brian', 'e' => 'notnull', 'fi', 'fei', 'fo', 'fam'),
6262
'taz' => array('a' => 'Steve', 'w' => array('p' => 1234)),
6363
'nested' => array('a' => 'Steve', 'w' => array('p' => 12345), 'd' => 'Doug', 'z' => array('p' => 12345)),
64-
'head_inline' => array('a' => 'Steve', 'b' => 'Clark', 'c' => 'Brian', 'fi', 'fei', 'fo', 'fam'),
65-
'recursive_inline' => array('a' => 'Steve', 'b' => 'Clark', 'c' => array('a' => 'Ballmer'), 'fi', 'fei', 'fo', 'fam')
64+
'head_inline' => array('a' => 'Steve', 'b' => 'Clark', 'c' => 'Brian', 'e' => 'notnull', 'fi', 'fei', 'fo', 'fam'),
65+
'recursive_inline' => array('a' => 'Steve', 'b' => 'Clark', 'c' => array('a' => 'Ballmer'), 'e' => 'notnull', 'fi', 'fei', 'fo', 'fam'),
6666
)

0 commit comments

Comments
 (0)