Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 464aaf3

Browse filesBrowse files
committed
parse merge keys with PARSE_OBJECT_FOR_MAP flag
1 parent 3f4c47c commit 464aaf3
Copy full SHA for 464aaf3

File tree

2 files changed

+56
-7
lines changed
Filter options

2 files changed

+56
-7
lines changed

‎src/Symfony/Component/Yaml/Parser.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Yaml/Parser.php
+19-7Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -249,27 +249,35 @@ private function doParse($value, $flags)
249249
if ('<<' === $key) {
250250
$mergeNode = true;
251251
$allowOverwrite = true;
252-
if (isset($values['value']) && 0 === strpos($values['value'], '*')) {
252+
if (isset($values['value']) && isset($values['value'][0]) && '*' === $values['value'][0]) {
253253
$refName = substr(rtrim($values['value']), 1);
254254
if (!array_key_exists($refName, $this->refs)) {
255255
throw new ParseException(sprintf('Reference "%s" does not exist.', $refName), $this->getRealCurrentLineNb() + 1, $this->currentLine);
256256
}
257257

258258
$refValue = $this->refs[$refName];
259259

260+
if ((bool) (Yaml::PARSE_OBJECT_FOR_MAP & $flags) && $refValue instanceof \stdClass) {
261+
$refValue = (array) $refValue;
262+
}
263+
260264
if (!is_array($refValue)) {
261265
throw new ParseException('YAML merge keys used with a scalar value instead of an array.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
262266
}
263267

264268
$data += $refValue; // array union
265269
} else {
266-
if (isset($values['value']) && $values['value'] !== '') {
270+
if (isset($values['value']) && '' !== $values['value']) {
267271
$value = $values['value'];
268272
} else {
269273
$value = $this->getNextEmbedBlock();
270274
}
271275
$parsed = $this->parseBlock($this->getRealCurrentLineNb() + 1, $value, $flags);
272276

277+
if ((bool) (Yaml::PARSE_OBJECT_FOR_MAP & $flags) && $parsed instanceof \stdClass) {
278+
$parsed = (array) $parsed;
279+
}
280+
273281
if (!is_array($parsed)) {
274282
throw new ParseException('YAML merge keys used with a scalar value instead of an array.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
275283
}
@@ -279,6 +287,10 @@ private function doParse($value, $flags)
279287
// and each of these nodes is merged in turn according to its order in the sequence. Keys in mapping nodes earlier
280288
// in the sequence override keys specified in later mapping nodes.
281289
foreach ($parsed as $parsedItem) {
290+
if ((bool) (Yaml::PARSE_OBJECT_FOR_MAP & $flags) && $parsedItem instanceof \stdClass) {
291+
$parsedItem = (array) $parsedItem;
292+
}
293+
282294
if (!is_array($parsedItem)) {
283295
throw new ParseException('Merge items must be arrays.', $this->getRealCurrentLineNb() + 1, $parsedItem);
284296
}
@@ -544,7 +556,7 @@ private function getNextEmbedBlock($indentation = null, $inSequence = false)
544556
$indent = $this->getCurrentLineIndentation();
545557

546558
// terminate all block scalars that are more indented than the current line
547-
if (!empty($blockScalarIndentations) && $indent < $previousLineIndentation && trim($this->currentLine) !== '') {
559+
if (!empty($blockScalarIndentations) && $indent < $previousLineIndentation && '' !== trim($this->currentLine)) {
548560
foreach ($blockScalarIndentations as $key => $blockScalarIndentation) {
549561
if ($blockScalarIndentation >= $indent) {
550562
unset($blockScalarIndentations[$key]);
@@ -680,7 +692,7 @@ private function parseValue($value, $flags, $context)
680692

681693
while ($this->moveToNextLine()) {
682694
// unquoted strings end before the first unindented line
683-
if (null === $quotation && $this->getCurrentLineIndentation() === 0) {
695+
if (null === $quotation && 0 === $this->getCurrentLineIndentation()) {
684696
$this->moveToPreviousLine();
685697

686698
break;
@@ -876,7 +888,7 @@ private function isCurrentLineComment()
876888
//checking explicitly the first char of the trim is faster than loops or strpos
877889
$ltrimmedLine = ltrim($this->currentLine, ' ');
878890

879-
return '' !== $ltrimmedLine && $ltrimmedLine[0] === '#';
891+
return '' !== $ltrimmedLine && '#' === $ltrimmedLine[0];
880892
}
881893

882894
private function isCurrentLineLastLineInDocument()
@@ -902,15 +914,15 @@ private function cleanup($value)
902914

903915
// remove leading comments
904916
$trimmedValue = preg_replace('#^(\#.*?\n)+#s', '', $value, -1, $count);
905-
if ($count == 1) {
917+
if (1 === $count) {
906918
// items have been removed, update the offset
907919
$this->offset += substr_count($value, "\n") - substr_count($trimmedValue, "\n");
908920
$value = $trimmedValue;
909921
}
910922

911923
// remove start of the document marker (---)
912924
$trimmedValue = preg_replace('#^\-\-\-.*?\n#s', '', $value, -1, $count);
913-
if ($count == 1) {
925+
if (1 === $count) {
914926
// items have been removed, update the offset
915927
$this->offset += substr_count($value, "\n") - substr_count($trimmedValue, "\n");
916928
$value = $trimmedValue;

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/Yaml/Tests/ParserTest.php
+37Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1865,6 +1865,43 @@ public function testPhpConstantTagMappingKeyWithKeysCastToStrings()
18651865

18661866
$this->assertSame($expected, $this->parser->parse($yaml, Yaml::PARSE_CONSTANT | Yaml::PARSE_KEYS_AS_STRINGS));
18671867
}
1868+
1869+
public function testMergeKeysWhenMappingsAreParsedAsObjects()
1870+
{
1871+
$yaml = <<<YAML
1872+
foo: &FOO
1873+
bar: 1
1874+
bar: &BAR
1875+
baz: 2
1876+
<<: *FOO
1877+
baz:
1878+
baz_foo: 3
1879+
<<:
1880+
baz_bar: 4
1881+
foobar:
1882+
bar: ~
1883+
<<: [*FOO, *BAR]
1884+
YAML;
1885+
$expected = (object) array(
1886+
'foo' => (object) array(
1887+
'bar' => 1,
1888+
),
1889+
'bar' => (object) array(
1890+
'baz' => 2,
1891+
'bar' => 1,
1892+
),
1893+
'baz' => (object) array(
1894+
'baz_foo' => 3,
1895+
'baz_bar' => 4,
1896+
),
1897+
'foobar' => (object) array(
1898+
'bar' => null,
1899+
'baz' => 2,
1900+
),
1901+
);
1902+
1903+
$this->assertEquals($expected, $this->parser->parse($yaml, Yaml::PARSE_OBJECT_FOR_MAP));
1904+
}
18681905
}
18691906

18701907
class B

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.