Skip to content

Commit ac84cbb

Browse files
committed
Merge branch '2.7' into 2.8
* 2.7: [2.7] Fixed flatten exception recursion with errors Embedded identifier support Also transform inline mappings to objects Change the ExtensionInterface load method definition to bo identical to the documentation. add and correct armenian translations [Config] Fix array sort on normalization in edge case [Security] Run tests on all PHP versions [Serializer] Make metadata interfaces internal [Yaml] fix indented line handling in folded blocks improve BrowserKit test coverage p1
2 parents 6fbc4e2 + 1d96518 commit ac84cbb

File tree

2 files changed

+115
-16
lines changed

2 files changed

+115
-16
lines changed

Parser.php

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,10 @@ public function parse($value, $exceptionOnInvalidType = false, $objectSupport =
240240
if ($isRef) {
241241
$this->refs[$isRef] = $data[$key];
242242
}
243+
244+
if ($objectForMap && !is_object($data)) {
245+
$data = (object) $data;
246+
}
243247
} else {
244248
// multiple documents are not supported
245249
if ('---' === $this->currentLine) {
@@ -515,13 +519,13 @@ private function parseBlockScalar($style, $chomping = '', $indentation = 0)
515519
}
516520

517521
$isCurrentLineBlank = $this->isCurrentLineBlank();
518-
$text = '';
522+
$blockLines = array();
519523

520524
// leading blank lines are consumed before determining indentation
521525
while ($notEOF && $isCurrentLineBlank) {
522526
// newline only if not EOF
523527
if ($notEOF = $this->moveToNextLine()) {
524-
$text .= "\n";
528+
$blockLines[] = '';
525529
$isCurrentLineBlank = $this->isCurrentLineBlank();
526530
}
527531
}
@@ -542,37 +546,59 @@ private function parseBlockScalar($style, $chomping = '', $indentation = 0)
542546
preg_match($pattern, $this->currentLine, $matches)
543547
)
544548
) {
545-
if ($isCurrentLineBlank) {
546-
$text .= substr($this->currentLine, $indentation);
549+
if ($isCurrentLineBlank && strlen($this->currentLine) > $indentation) {
550+
$blockLines[] = substr($this->currentLine, $indentation);
551+
} elseif ($isCurrentLineBlank) {
552+
$blockLines[] = '';
547553
} else {
548-
$text .= $matches[1];
554+
$blockLines[] = $matches[1];
549555
}
550556

551557
// newline only if not EOF
552558
if ($notEOF = $this->moveToNextLine()) {
553-
$text .= "\n";
554559
$isCurrentLineBlank = $this->isCurrentLineBlank();
555560
}
556561
}
557562
} elseif ($notEOF) {
558-
$text .= "\n";
563+
$blockLines[] = '';
559564
}
560565

561566
if ($notEOF) {
567+
$blockLines[] = '';
562568
$this->moveToPreviousLine();
563569
}
564570

565571
// folded style
566572
if ('>' === $style) {
567-
// folded lines
568-
// replace all non-leading/non-trailing single newlines with spaces
569-
preg_match('/(\n*)$/', $text, $matches);
570-
$text = preg_replace('/(?<!\n|^)\n(?!\n)/', ' ', rtrim($text, "\n"));
571-
$text .= $matches[1];
572-
573-
// empty separation lines
574-
// remove one newline from each group of non-leading/non-trailing newlines
575-
$text = preg_replace('/[^\n]\n+\K\n(?=[^\n])/', '', $text);
573+
$text = '';
574+
$previousLineIndented = false;
575+
$previousLineBlank = false;
576+
577+
for ($i = 0; $i < count($blockLines); $i++) {
578+
if ('' === $blockLines[$i]) {
579+
$text .= "\n";
580+
$previousLineIndented = false;
581+
$previousLineBlank = true;
582+
} elseif (' ' === $blockLines[$i][0]) {
583+
$text .= "\n".$blockLines[$i];
584+
$previousLineIndented = true;
585+
$previousLineBlank = false;
586+
} elseif ($previousLineIndented) {
587+
$text .= "\n".$blockLines[$i];
588+
$previousLineIndented = false;
589+
$previousLineBlank = false;
590+
} elseif ($previousLineBlank || 0 === $i) {
591+
$text .= $blockLines[$i];
592+
$previousLineIndented = false;
593+
$previousLineBlank = false;
594+
} else {
595+
$text .= ' '.$blockLines[$i];
596+
$previousLineIndented = false;
597+
$previousLineBlank = false;
598+
}
599+
}
600+
} else {
601+
$text = implode("\n", $blockLines);
576602
}
577603

578604
// deal with trailing newlines

Tests/ParserTest.php

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,28 @@ public function testObjectSupportDisabledButNoExceptions()
438438
$this->assertEquals(array('foo' => null, 'bar' => 1), $this->parser->parse($input), '->parse() does not parse objects');
439439
}
440440

441+
public function testObjectForMapEnabledWithMapping()
442+
{
443+
$yaml = <<<EOF
444+
foo:
445+
fiz: [cat]
446+
EOF;
447+
$result = $this->parser->parse($yaml, false, false, true);
448+
449+
$this->assertInstanceOf('stdClass', $result);
450+
$this->assertInstanceOf('stdClass', $result->foo);
451+
$this->assertEquals(array('cat'), $result->foo->fiz);
452+
}
453+
454+
public function testObjectForMapEnabledWithInlineMapping()
455+
{
456+
$result = $this->parser->parse('{ "foo": "bar", "fiz": "cat" }', false, false, true);
457+
458+
$this->assertInstanceOf('stdClass', $result);
459+
$this->assertEquals('bar', $result->foo);
460+
$this->assertEquals('cat', $result->fiz);
461+
}
462+
441463
/**
442464
* @expectedException \Symfony\Component\Yaml\Exception\ParseException
443465
*/
@@ -912,6 +934,57 @@ public function getCommentLikeStringInScalarBlockData()
912934
array($yaml2, $expected2),
913935
);
914936
}
937+
938+
public function testBlankLinesAreParsedAsNewLinesInFoldedBlocks()
939+
{
940+
$yaml = <<<EOT
941+
test: >
942+
<h2>A heading</h2>
943+
944+
<ul>
945+
<li>a list</li>
946+
<li>may be a good example</li>
947+
</ul>
948+
EOT;
949+
950+
$this->assertSame(
951+
array(
952+
'test' => <<<EOT
953+
<h2>A heading</h2>
954+
<ul> <li>a list</li> <li>may be a good example</li> </ul>
955+
EOT
956+
,
957+
),
958+
$this->parser->parse($yaml)
959+
);
960+
}
961+
962+
public function testAdditionallyIndentedLinesAreParsedAsNewLinesInFoldedBlocks()
963+
{
964+
$yaml = <<<EOT
965+
test: >
966+
<h2>A heading</h2>
967+
968+
<ul>
969+
<li>a list</li>
970+
<li>may be a good example</li>
971+
</ul>
972+
EOT;
973+
974+
$this->assertSame(
975+
array(
976+
'test' => <<<EOT
977+
<h2>A heading</h2>
978+
<ul>
979+
<li>a list</li>
980+
<li>may be a good example</li>
981+
</ul>
982+
EOT
983+
,
984+
),
985+
$this->parser->parse($yaml)
986+
);
987+
}
915988
}
916989

917990
class B

0 commit comments

Comments
 (0)