don't keep internal state between parser runs

This commit is contained in:
Christian Flothmann 2017-04-04 16:26:39 +02:00
parent e580c68899
commit faf671db0f
2 changed files with 57 additions and 16 deletions

View File

@ -64,23 +64,51 @@ class Parser
if (false === preg_match('//u', $value)) { if (false === preg_match('//u', $value)) {
throw new ParseException('The YAML value does not appear to be valid UTF-8.'); throw new ParseException('The YAML value does not appear to be valid UTF-8.');
} }
$this->currentLineNb = -1;
$this->currentLine = '';
$value = $this->cleanup($value);
$this->lines = explode("\n", $value);
if (null === $this->totalNumberOfLines) { $this->refs = array();
$this->totalNumberOfLines = count($this->lines);
} $mbEncoding = null;
$e = null;
$data = null;
if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) { if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) {
$mbEncoding = mb_internal_encoding(); $mbEncoding = mb_internal_encoding();
mb_internal_encoding('UTF-8'); mb_internal_encoding('UTF-8');
} }
try {
$data = $this->doParse($value, $exceptionOnInvalidType, $objectSupport, $objectForMap);
} catch (\Exception $e) {
} catch (\Throwable $e) {
}
if (null !== $mbEncoding) {
mb_internal_encoding($mbEncoding);
}
if (null !== $e) {
throw $e;
}
return $data;
}
private function doParse($value, $exceptionOnInvalidType = false, $objectSupport = false, $objectForMap = false)
{
$this->currentLineNb = -1;
$this->currentLine = '';
$value = $this->cleanup($value);
$this->lines = explode("\n", $value);
$this->locallySkippedLineNumbers = array();
if (null === $this->totalNumberOfLines) {
$this->totalNumberOfLines = count($this->lines);
}
$data = array(); $data = array();
$context = null; $context = null;
$allowOverwrite = false; $allowOverwrite = false;
while ($this->moveToNextLine()) { while ($this->moveToNextLine()) {
if ($this->isCurrentLineEmpty()) { if ($this->isCurrentLineEmpty()) {
continue; continue;
@ -250,10 +278,6 @@ class Parser
throw $e; throw $e;
} }
if (isset($mbEncoding)) {
mb_internal_encoding($mbEncoding);
}
return $value; return $value;
} }
@ -261,10 +285,6 @@ class Parser
} }
} }
if (isset($mbEncoding)) {
mb_internal_encoding($mbEncoding);
}
return empty($data) ? null : $data; return empty($data) ? null : $data;
} }
@ -283,7 +303,7 @@ class Parser
$parser = new self($offset, $this->totalNumberOfLines, $skippedLineNumbers); $parser = new self($offset, $this->totalNumberOfLines, $skippedLineNumbers);
$parser->refs = &$this->refs; $parser->refs = &$this->refs;
return $parser->parse($yaml, $exceptionOnInvalidType, $objectSupport, $objectForMap); return $parser->doParse($yaml, $exceptionOnInvalidType, $objectSupport, $objectForMap);
} }
/** /**

View File

@ -1158,6 +1158,27 @@ YAML
$this->assertEquals($trickyVal, $arrayFromYaml); $this->assertEquals($trickyVal, $arrayFromYaml);
} }
/**
* @expectedException \Symfony\Component\Yaml\Exception\ParseException
* @expectedExceptionMessage Reference "foo" does not exist at line 2
*/
public function testParserCleansUpReferencesBetweenRuns()
{
$yaml = <<<YAML
foo: &foo
baz: foobar
bar:
<<: *foo
YAML;
$this->parser->parse($yaml);
$yaml = <<<YAML
bar:
<<: *foo
YAML;
$this->parser->parse($yaml);
}
} }
class B class B