Skip to content

Commit 8b47864

Browse files
bradtreloarfabpot
authored andcommitted
[Dumper] Trim leading newlines when checking if value begins with a space
1 parent 2a2fc8a commit 8b47864

File tree

2 files changed

+55
-9
lines changed

2 files changed

+55
-9
lines changed

src/Symfony/Component/Yaml/Dumper.php

+19-9
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,7 @@ public function dump($input, int $inline = 0, int $indent = 0, int $flags = 0):
6969
}
7070

7171
if (Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK & $flags && \is_string($value) && false !== strpos($value, "\n") && false === strpos($value, "\r")) {
72-
// If the first line starts with a space character, the spec requires a blockIndicationIndicator
73-
// http://www.yaml.org/spec/1.2/spec.html#id2793979
74-
$blockIndentationIndicator = (' ' === substr($value, 0, 1)) ? (string) $this->indentation : '';
72+
$blockIndentationIndicator = $this->getBlockIndentationIndicator($value);
7573

7674
if (isset($value[-2]) && "\n" === $value[-2] && "\n" === $value[-1]) {
7775
$blockChompingIndicator = '+';
@@ -98,9 +96,7 @@ public function dump($input, int $inline = 0, int $indent = 0, int $flags = 0):
9896
$output .= sprintf('%s%s !%s', $prefix, $dumpAsMap ? Inline::dump($key, $flags).':' : '-', $value->getTag());
9997

10098
if (Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK & $flags && \is_string($value->getValue()) && false !== strpos($value->getValue(), "\n") && false === strpos($value->getValue(), "\r\n")) {
101-
// If the first line starts with a space character, the spec requires a blockIndicationIndicator
102-
// http://www.yaml.org/spec/1.2/spec.html#id2793979
103-
$blockIndentationIndicator = (' ' === substr($value->getValue(), 0, 1)) ? (string) $this->indentation : '';
99+
$blockIndentationIndicator = $this->getBlockIndentationIndicator($value->getValue());
104100
$output .= sprintf(' |%s', $blockIndentationIndicator);
105101

106102
foreach (explode("\n", $value->getValue()) as $row) {
@@ -145,9 +141,7 @@ private function dumpTaggedValue(TaggedValue $value, int $inline, int $indent, i
145141
$output = sprintf('%s!%s', $prefix ? $prefix.' ' : '', $value->getTag());
146142

147143
if (Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK & $flags && \is_string($value->getValue()) && false !== strpos($value->getValue(), "\n") && false === strpos($value->getValue(), "\r\n")) {
148-
// If the first line starts with a space character, the spec requires a blockIndicationIndicator
149-
// http://www.yaml.org/spec/1.2/spec.html#id2793979
150-
$blockIndentationIndicator = (' ' === substr($value->getValue(), 0, 1)) ? (string) $this->indentation : '';
144+
$blockIndentationIndicator = $this->getBlockIndentationIndicator($value->getValue());
151145
$output .= sprintf(' |%s', $blockIndentationIndicator);
152146

153147
foreach (explode("\n", $value->getValue()) as $row) {
@@ -163,4 +157,20 @@ private function dumpTaggedValue(TaggedValue $value, int $inline, int $indent, i
163157

164158
return $output."\n".$this->dump($value->getValue(), $inline - 1, $indent, $flags);
165159
}
160+
161+
private function getBlockIndentationIndicator(string $value): string
162+
{
163+
$lines = explode("\n", $value);
164+
165+
// If the first line (that is neither empty nor contains only spaces)
166+
// starts with a space character, the spec requires a block indentation indicator
167+
// http://www.yaml.org/spec/1.2/spec.html#id2793979
168+
foreach ($lines as $line) {
169+
if ('' !== trim($line, ' ')) {
170+
return (' ' === substr($line, 0, 1)) ? (string) $this->indentation : '';
171+
}
172+
}
173+
174+
return '';
175+
}
166176
}

src/Symfony/Component/Yaml/Tests/DumperTest.php

+36
Original file line numberDiff line numberDiff line change
@@ -710,6 +710,42 @@ public function testDumpMultiLineStringAsScalarBlockWhenFirstLineHasLeadingSpace
710710
$this->assertSame($data, $this->parser->parse($yml));
711711
}
712712

713+
public function testDumpMultiLineStringAsScalarBlockWhenFirstLineIsEmptyAndSecondLineHasLeadingSpace()
714+
{
715+
$data = [
716+
'data' => [
717+
'multi_line' => "\n the second line has leading spaces\nThe third line does not.",
718+
],
719+
];
720+
721+
$expected = "data:\n multi_line: |4-\n\n the second line has leading spaces\n The third line does not.";
722+
723+
$yml = $this->dumper->dump($data, 2, 0, Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK);
724+
$this->assertSame($expected, $yml);
725+
$this->assertSame($data, $this->parser->parse($yml));
726+
}
727+
728+
public function testDumpMultiLineStringAsScalarBlockWhenFirstLineHasOnlySpaces()
729+
{
730+
$data = [
731+
'data' => [
732+
'multi_line' => " \nthe second line\nThe third line.",
733+
],
734+
];
735+
736+
$expectedData = [
737+
'data' => [
738+
'multi_line' => "\nthe second line\nThe third line.",
739+
],
740+
];
741+
742+
$expectedYml = "data:\n multi_line: |-\n \n the second line\n The third line.";
743+
744+
$yml = $this->dumper->dump($data, 2, 0, Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK);
745+
$this->assertSame($expectedYml, $yml);
746+
$this->assertSame($expectedData, $this->parser->parse($yml));
747+
}
748+
713749
public function testCarriageReturnFollowedByNewlineIsMaintainedWhenDumpingAsMultiLineLiteralBlock()
714750
{
715751
$data = ["a\r\nb\nc"];

0 commit comments

Comments
 (0)