Skip to content

Commit 49c2554

Browse files
committed
don't keep internal state between parser runs
1 parent 596e1fa commit 49c2554

File tree

2 files changed

+55
-14
lines changed

2 files changed

+55
-14
lines changed

Parser.php

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -64,23 +64,51 @@ public function parse($value, $exceptionOnInvalidType = false, $objectSupport =
6464
if (false === preg_match('//u', $value)) {
6565
throw new ParseException('The YAML value does not appear to be valid UTF-8.');
6666
}
67+
68+
$this->refs = array();
69+
70+
$mbEncoding = null;
71+
$e = null;
72+
$data = null;
73+
74+
if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) {
75+
$mbEncoding = mb_internal_encoding();
76+
mb_internal_encoding('UTF-8');
77+
}
78+
79+
try {
80+
$data = $this->doParse($value, $exceptionOnInvalidType, $objectSupport, $objectForMap);
81+
} catch (\Exception $e) {
82+
} catch (\Throwable $e) {
83+
}
84+
85+
if (null !== $mbEncoding) {
86+
mb_internal_encoding($mbEncoding);
87+
}
88+
89+
if (null !== $e) {
90+
throw $e;
91+
}
92+
93+
return $data;
94+
}
95+
96+
private function doParse($value, $exceptionOnInvalidType = false, $objectSupport = false, $objectForMap = false)
97+
{
6798
$this->currentLineNb = -1;
6899
$this->currentLine = '';
69100
$value = $this->cleanup($value);
70101
$this->lines = explode("\n", $value);
102+
$this->locallySkippedLineNumbers = array();
71103

72104
if (null === $this->totalNumberOfLines) {
73105
$this->totalNumberOfLines = count($this->lines);
74106
}
75107

76-
if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) {
77-
$mbEncoding = mb_internal_encoding();
78-
mb_internal_encoding('UTF-8');
79-
}
80-
81108
$data = array();
82109
$context = null;
83110
$allowOverwrite = false;
111+
84112
while ($this->moveToNextLine()) {
85113
if ($this->isCurrentLineEmpty()) {
86114
continue;
@@ -250,21 +278,13 @@ public function parse($value, $exceptionOnInvalidType = false, $objectSupport =
250278
throw $e;
251279
}
252280

253-
if (isset($mbEncoding)) {
254-
mb_internal_encoding($mbEncoding);
255-
}
256-
257281
return $value;
258282
}
259283

260284
throw new ParseException('Unable to parse.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
261285
}
262286
}
263287

264-
if (isset($mbEncoding)) {
265-
mb_internal_encoding($mbEncoding);
266-
}
267-
268288
return empty($data) ? null : $data;
269289
}
270290

@@ -283,7 +303,7 @@ private function parseBlock($offset, $yaml, $exceptionOnInvalidType, $objectSupp
283303
$parser = new self($offset, $this->totalNumberOfLines, $skippedLineNumbers);
284304
$parser->refs = &$this->refs;
285305

286-
return $parser->parse($yaml, $exceptionOnInvalidType, $objectSupport, $objectForMap);
306+
return $parser->doParse($yaml, $exceptionOnInvalidType, $objectSupport, $objectForMap);
287307
}
288308

289309
/**

Tests/ParserTest.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1158,6 +1158,27 @@ public function testCanParseVeryLongValue()
11581158

11591159
$this->assertEquals($trickyVal, $arrayFromYaml);
11601160
}
1161+
1162+
/**
1163+
* @expectedException \Symfony\Component\Yaml\Exception\ParseException
1164+
* @expectedExceptionMessage Reference "foo" does not exist at line 2
1165+
*/
1166+
public function testParserCleansUpReferencesBetweenRuns()
1167+
{
1168+
$yaml = <<<YAML
1169+
foo: &foo
1170+
baz: foobar
1171+
bar:
1172+
<<: *foo
1173+
YAML;
1174+
$this->parser->parse($yaml);
1175+
1176+
$yaml = <<<YAML
1177+
bar:
1178+
<<: *foo
1179+
YAML;
1180+
$this->parser->parse($yaml);
1181+
}
11611182
}
11621183

11631184
class B

0 commit comments

Comments
 (0)