8000 [Yaml] recognize when a block scalar is left · PBWebMedia/symfony@3a22165 · GitHub
[go: up one dir, main page]

Skip to content

Commit 3a22165

Browse files
committed
[Yaml] recognize when a block scalar is left
The parser did not recognize when the block scalar was completely parsed and thus treated following comments as they need to be kept leading to parse errors on the following lines.
1 parent a89fe42 commit 3a22165

File tree

2 files changed

+67
-15
lines changed

2 files changed

+67
-15
lines changed

src/Symfony/Component/Yaml/Parser.php

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,11 @@ private function getCurrentLineIndentation()
303303
private function getNextEmbedBlock($indentation = null, $inSequence = false)
304304
{
305305
$oldLineIndentation = $this->getCurrentLineIndentation();
306-
$insideBlockScalar = $this->isBlockScalarHeader();
306+
$blockScalarIndentations = array();
307+
308+
if ($this->isBlockScalarHeader()) {
309+
$blockScalarIndentations[] = $this->getCurrentLineIndentation();
310+
}
307311

308312
if (!$this->moveToNextLine()) {
309313
return;
@@ -340,17 +344,26 @@ private function getNextEmbedBlock($indentation = null, $inSequence = false)
340344

341345
$isItUnindentedCollection = $this->isStringUnIndentedCollectionItem();
342346

343-
if (!$insideBlockScalar) {
344-
$insideBlockScalar = $this->isBlockScalarHeader();
347+
if (empty($blockScalarIndentations) && $this->isBlockScalarHeader()) {
348+
$blockScalarIndentations[] = $this->getCurrentLineIndentation();
345349
}
346350

347351
$previousLineIndentation = $this->getCurrentLineIndentation();
348352

349353
while ($this->moveToNextLine()) {
350354
$indent = $this->getCurrentLineIndentation();
351355

352-
if (!$insideBlockScalar && $indent === $previousLineIndentation) {
353-
$insideBlockScalar = $this->isBlockScalarHeader();
356+
// terminate all block scalars that are more indented than the current line
357+
if (!empty($blockScalarIndentations) && $indent < $previousLineIndentation && trim($this->currentLine) !== '') {
358+
foreach ($blockScalarIndentations as $key => $blockScalarIndentation) {
359+
if ($blockScalarIndentation >= $this->getCurrentLineIndentation()) {
360+
unset($blockScalarIndentations[$key]);
361+
}
362+
}
363+
}
364+
365+
if (empty($blockScalarIndentations) && !$this->isCurrentLineComment() && $this->isBlockScalarHeader()) {
366+
$blockScalarIndentations[] = $this->getCurrentLineIndentation();
354367
}
355368

356369
$previousLineIndentation = $indent;
@@ -366,7 +379,7 @@ private function getNextEmbedBlock($indentation = null, $inSequence = false)
366379
}
367380

368381
// we ignore "comment" lines only when we are not inside a scalar block
369-
if (!$insideBlockScalar && $this->isCurrentLineComment()) {
382+
if (empty($blockScalarIndentations) && $this->isCurrentLineComment()) {
370383
continue;
371384
}
372385

@@ -523,7 +536,7 @@ private function parseBlockScalar($style, $chomping = '', $indentation = 0)
523536
$previousLineIndented = false;
524537
$previousLineBlank = false;
525538

526-
for ($i = 0; $i < count($blockLines); $i++) {
539+
for ($i = 0; $i < count($blockLines); ++$i) {
527540
if ('' === $blockLines[$i]) {
528541
$text .= "\n";
529542
$previousLineIndented = false;
@@ -618,7 +631,7 @@ private function isCurrentLineComment()
618631
//checking explicitly the first char of the trim is faster than loops or strpos
619632
$ltrimmedLine = ltrim($this->currentLine, ' ');
620633

621-
return $ltrimmedLine[0] === '#';
634+
return '' !== $ltrimmedLine && $ltrimmedLine[0] === '#';
622635
}
623636

624637
/**

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

Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -737,7 +737,9 @@ public function testCommentLikeStringsAreNotStrippedInBlockScalars($yaml, $expec
737737

738738
public function getCommentLikeStringInScalarBlockData()
739739
{
740-
$yaml1 = <<<'EOT'
740+
$tests = array();
741+
742+
$yaml = <<<'EOT'
741743
pages:
742744
-
743745
title: some title
@@ -752,7 +754,7 @@ public function getCommentLikeStringInScalarBlockData()
752754
753755
footer # comment3
754756
EOT;
755-
$expected1 = array(
757+
$expected = array(
756758
'pages' => array(
757759
array(
758760
'title' => 'some title',
@@ -771,8 +773,9 @@ public function getCommentLikeStringInScalarBlockData()
771773
),
772774
),
773775
);
776+
$tests[] = array($yaml, $expected);
774777

775-
$yaml2 = <<<'EOT'
778+
$yaml = <<<'EOT'
776779
test: |
777780
foo
778781
# bar
@@ -787,7 +790,7 @@ public function getCommentLikeStringInScalarBlockData()
787790
# bar
788791
baz
789792
EOT;
790-
$expected2 = array(
793+
$expected = array(
791794
'test' => <<<'EOT'
792< B41A code>795
foo
793796
# bar
@@ -814,11 +817,47 @@ public function getCommentLikeStringInScalarBlockData()
814817
),
815818
),
816819
);
820+
$tests[] = array($yaml, $expected);
817821

818-
return array(
819-
array($yaml1, $expected1),
820-
array($yaml2, $expected2),
822+
$yaml = <<<EOT
823+
foo:
824+
bar:
825+
scalar-block: >
826+
line1
827+
line2>
828+
baz:
829+
# comment
830+
foobar: ~
831+
EOT;
832+
$expected = array(
833+
'foo' => array(
834+
'bar' => array(
835+
'scalar-block' => 'line1 line2>',
836+
),
837+
'baz' => array(
838+
'foobar' => null,
839+
),
840+
),
821841
);
842+
$tests[] = array($yaml, $expected);
843+
844+
$yaml = <<<'EOT'
845+
a:
846+
b: hello
847+
# c: |
848+
# first row
849+
# second row
850+
d: hello
851+
EOT;
852+
$expected = array(
853+
'a' => array(
854+
'b' => 'hello',
855+
'd' => 'hello',
856+
),
857+
);
858+
$tests[] = array($yaml, $expected);
859+
860+
return $tests;
822861
}
823862

824863
public function testBlankLinesAreParsedAsNewLinesInFoldedBlocks()

0 commit comments

Comments
 (0)
0