Skip to content

Commit 06766b4

Browse files
committed
Merge branch '2.8' into 3.0
* 2.8: [Yaml] fix exception contexts People - person singularization [Yaml] properly handle unindented collections [Serializer] Add test for ignored attributes during denormalization chomp newlines only at the end of YAML documents Fixed server status command when port has been omitted Update UPGRADE FROM 2.x to 3.0 fix removed commands wording in upgrade file Catch \Throwable Catch \Throwable Use levenshtein level for better Bundle matching [WebProfilerBundle] Fix CORS ajax security issues [DX][DI] Make Autowiring exceptions more future friendly
2 parents 0047c83 + 5190891 commit 06766b4

File tree

2 files changed

+56
-13
lines changed

2 files changed

+56
-13
lines changed

Parser.php

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ class Parser
2323
const BLOCK_SCALAR_HEADER_PATTERN = '(?P<separator>\||>)(?P<modifiers>\+|\-|\d+|\+\d+|\-\d+|\d+\+|\d+\-)?(?P<comments> +#.*)?';
2424

2525
private $offset = 0;
26+
private $totalNumberOfLines;
2627
private $lines = array();
2728
private $currentLineNb = -1;
2829
private $currentLine = '';
@@ -31,11 +32,13 @@ class Parser
3132
/**
3233
* Constructor.
3334
*
34-
* @param int $offset The offset of YAML document (used for line numbers in error messages)
35+
* @param int $offset The offset of YAML document (used for line numbers in error messages)
36+
* @param int|null $totalNumberOfLines The overall number of lines being parsed
3537
*/
36-
public function __construct($offset = 0)
38+
public function __construct($offset = 0, $totalNumberOfLines = null)
3739
{
3840
$this->offset = $offset;
41+
$this->totalNumberOfLines = $totalNumberOfLines;
3942
}
4043

4144
/**
@@ -60,6 +63,10 @@ public function parse($value, $exceptionOnInvalidType = false, $objectSupport =
6063
$value = $this->cleanup($value);
6164
$this->lines = explode("\n", $value);
6265

66+
if (null === $this->totalNumberOfLines) {
67+
$this->totalNumberOfLines = count($this->lines);
68+
}
69+
6370
if (2 /* MB_OVERLOAD_STRING */ & (int) ini_get('mbstring.func_overload')) {
6471
$mbEncoding = mb_internal_encoding();
6572
mb_internal_encoding('UTF-8');
@@ -81,7 +88,7 @@ public function parse($value, $exceptionOnInvalidType = false, $objectSupport =
8188
$isRef = $mergeNode = false;
8289
if (preg_match('#^\-((?P<leadspaces>\s+)(?P<value>.+?))?\s*$#u', $this->currentLine, $values)) {
8390
if ($context && 'mapping' == $context) {
84-
throw new ParseException('You cannot define a sequence item when in a mapping');
91+
throw new ParseException('You cannot define a sequence item when in a mapping', $this->getRealCurrentLineNb() + 1, $this->currentLine);
8592
}
8693
$context = 'sequence';
8794

@@ -93,7 +100,7 @@ public function parse($value, $exceptionOnInvalidType = false, $objectSupport =
93100
// array
94101
if (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#')) {
95102
$c = $this->getRealCurrentLineNb() + 1;
96-
$parser = new self($c);
103+
$parser = new self($c, $this->totalNumberOfLines);
97104
$parser->refs = &$this->refs;
98105
$data[] = $parser->parse($this->getNextEmbedBlock(null, true), $exceptionOnInvalidType, $objectSupport, $objectForMap);
99106
} else {
@@ -102,7 +109,7 @@ public function parse($value, $exceptionOnInvalidType = false, $objectSupport =
102109
) {
103110
// this is a compact notation element, add to next block and parse
104111
$c = $this->getRealCurrentLineNb();
105-
$parser = new self($c);
112+
$parser = new self($c, $this->totalNumberOfLines);
106113
$parser->refs = &$this->refs;
107114

108115
$block = $values['value'];
@@ -120,7 +127,7 @@ public function parse($value, $exceptionOnInvalidType = false, $objectSupport =
120127
}
121128
} elseif (preg_match('#^(?P<key>'.Inline::REGEX_QUOTED_STRING.'|[^ \'"\[\{].*?) *\:(\s+(?P<value>.+?))?\s*$#u', $this->currentLine, $values) && (false === strpos($values['key'], ' #') || in_array($values['key'][0], array('"', "'")))) {
122129
if ($context && 'sequence' == $context) {
123-
throw new ParseException('You cannot define a mapping item when in a sequence');
130+
throw new ParseException('You cannot define a mapping item when in a sequence', $this->currentLineNb + 1, $this->currentLine);
124131
}
125132
$context = 'mapping';
126133

@@ -167,7 +174,7 @@ public function parse($value, $exceptionOnInvalidType = false, $objectSupport =
167174
$value = $this->getNextEmbedBlock();
168175
}
169176
$c = $this->getRealCurrentLineNb() + 1;
170-
$parser = new self($c);
177+
$parser = new self($c, $this->totalNumberOfLines);
171178
$parser->refs = &$this->refs;
172179
$parsed = $parser->parse($value, $exceptionOnInvalidType, $objectSupport, $objectForMap);
173180

@@ -218,7 +225,7 @@ public function parse($value, $exceptionOnInvalidType = false, $objectSupport =
218225
}
219226
} else {
220227
$c = $this->getRealCurrentLineNb() + 1;
221-
$parser = new self($c);
228+
$parser = new self($c, $this->totalNumberOfLines);
222229
$parser->refs = &$this->refs;
223230
$value = $parser->parse($this->getNextEmbedBlock(), $exceptionOnInvalidType, $objectSupport, $objectForMap);
224231
// Spec: Keys MUST be unique; first one wins.
@@ -241,7 +248,7 @@ public function parse($value, $exceptionOnInvalidType = false, $objectSupport =
241248
} else {
242249
// multiple documents are not supported
243250
if ('---' === $this->currentLine) {
244-
throw new ParseException('Multiple documents are not supported.');
251+
throw new ParseException('Multiple documents are not supported.', $this->currentLineNb + 1, $this->currentLine);
245252
}
246253

247254
// 1-liner optionally followed by newline(s)
@@ -488,7 +495,7 @@ private function parseValue($value, $exceptionOnInvalidType, $objectSupport, $ob
488495
}
489496

490497
if (!array_key_exists($value, $this->refs)) {
491-
throw new ParseException(sprintf('Reference "%s" does not exist.', $value), $this->currentLine);
498+
throw new ParseException(sprintf('Reference "%s" does not exist.', $value), $this->currentLineNb + 1, $this->currentLine);
492499
}
493500

494501
return $this->refs[$value];
@@ -580,6 +587,8 @@ private function parseBlockScalar($style, $chomping = '', $indentation = 0)
580587
if ($notEOF) {
581588
$blockLines[] = '';
582589
$this->moveToPreviousLine();
590+
} elseif (!$notEOF && !$this->isCurrentLineLastLineInDocument()) {
591+
$blockLines[] = '';
583592
}
584593

585594
// folded style
@@ -686,6 +695,11 @@ private function isCurrentLineComment()
686695
return '' !== $ltrimmedLine && $ltrimmedLine[0] === '#';
687696
}
688697

698+
private function isCurrentLineLastLineInDocument()
699+
{
700+
return ($this->offset + $this->currentLineNb) >= ($this->totalNumberOfLines - 1);
701+
}
702+
689703
/**
690704
* Cleanups a YAML string to be parsed.
691705
*
@@ -763,7 +777,7 @@ private function isNextLineUnIndentedCollection()
763777
*/
764778
private function isStringUnIndentedCollectionItem()
765779
{
766-
return 0 === strpos($this->currentLine, '- ');
780+
return '-' === rtrim($this->currentLine) || 0 === strpos($this->currentLine, '- ');
767781
}
768782

769783
/**

Tests/ParserTest.php

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -596,7 +596,7 @@ public function testShortcutKeyUnindentedCollectionException()
596596

597597
/**
598598
* @expectedException \Symfony\Component\Yaml\Exception\ParseException
599-
* @expectedExceptionMessage Multiple documents are not supported.
599+
* @expectedExceptionMessageRegExp /^Multiple documents are not supported.+/
600600
*/
601601
public function testMultipleDocumentsNotSupportedException()
602602
{
@@ -628,6 +628,34 @@ public function testSequenceInAMapping()
628628
);
629629
}
630630

631+
public function testSequenceInMappingStartedBySingleDashLine()
632+
{
633+
$yaml = <<<EOT
634+
a:
635+
-
636+
b:
637+
-
638+
bar: baz
639+
- foo
640+
d: e
641+
EOT;
642+
$expected = array(
643+
'a' => array(
644+
array(
645+
'b' => array(
646+
array(
647+
'bar' => 'baz',
648+
),
649+
),
650+
),
651+
'foo',
652+
),
653+
'd' => 'e',
654+
);
655+
656+
$this->assertSame($expected, $this->parser->parse($yaml));
657+
}
658+
631659
/**
632660
* @expectedException \Symfony\Component\Yaml\Exception\ParseException
633661
*/
@@ -977,6 +1005,7 @@ public function getCommentLikeStringInScalarBlockData()
9771005
foo
9781006
# bar
9791007
baz
1008+
9801009
EOT
9811010
,
9821011
),
@@ -1005,7 +1034,7 @@ public function getCommentLikeStringInScalarBlockData()
10051034
$expected = array(
10061035
'foo' => array(
10071036
'bar' => array(
1008-
'scalar-block' => 'line1 line2>',
1037+
'scalar-block' => "line1 line2>\n",
10091038
),
10101039
'baz' => array(
10111040
'foobar' => null,

0 commit comments

Comments
 (0)