From faf671db0f7493c15fdcef8446b9472a1ce80445 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Tue, 4 Apr 2017 16:26:39 +0200 Subject: [PATCH] don't keep internal state between parser runs --- src/Symfony/Component/Yaml/Parser.php | 52 +++++++++++++------ .../Component/Yaml/Tests/ParserTest.php | 21 ++++++++ 2 files changed, 57 insertions(+), 16 deletions(-) diff --git a/src/Symfony/Component/Yaml/Parser.php b/src/Symfony/Component/Yaml/Parser.php index 345bcbdac1..e4d7fe2839 100644 --- a/src/Symfony/Component/Yaml/Parser.php +++ b/src/Symfony/Component/Yaml/Parser.php @@ -64,23 +64,51 @@ class Parser if (false === preg_match('//u', $value)) { 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->totalNumberOfLines = count($this->lines); - } + $this->refs = array(); + + $mbEncoding = null; + $e = null; + $data = null; if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) { $mbEncoding = mb_internal_encoding(); 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(); $context = null; $allowOverwrite = false; + while ($this->moveToNextLine()) { if ($this->isCurrentLineEmpty()) { continue; @@ -250,10 +278,6 @@ class Parser throw $e; } - if (isset($mbEncoding)) { - mb_internal_encoding($mbEncoding); - } - return $value; } @@ -261,10 +285,6 @@ class Parser } } - if (isset($mbEncoding)) { - mb_internal_encoding($mbEncoding); - } - return empty($data) ? null : $data; } @@ -283,7 +303,7 @@ class Parser $parser = new self($offset, $this->totalNumberOfLines, $skippedLineNumbers); $parser->refs = &$this->refs; - return $parser->parse($yaml, $exceptionOnInvalidType, $objectSupport, $objectForMap); + return $parser->doParse($yaml, $exceptionOnInvalidType, $objectSupport, $objectForMap); } /** diff --git a/src/Symfony/Component/Yaml/Tests/ParserTest.php b/src/Symfony/Component/Yaml/Tests/ParserTest.php index d6e5f77513..1ff5e3e8a5 100644 --- a/src/Symfony/Component/Yaml/Tests/ParserTest.php +++ b/src/Symfony/Component/Yaml/Tests/ParserTest.php @@ -1158,6 +1158,27 @@ YAML $this->assertEquals($trickyVal, $arrayFromYaml); } + + /** + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + * @expectedExceptionMessage Reference "foo" does not exist at line 2 + */ + public function testParserCleansUpReferencesBetweenRuns() + { + $yaml = <<parser->parse($yaml); + + $yaml = <<parser->parse($yaml); + } } class B