Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: symfony/yaml
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v4.1.9
Choose a base ref
...
head repository: symfony/yaml
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v4.1.10
Choose a head ref
  • 8 commits
  • 5 files changed
  • 5 contributors

Commits on Dec 9, 2018

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    006a538 View commit details

Commits on Dec 11, 2018

  1. [Yaml] ensures that the mb_internal_encoding is reset to its initial …

    …value
    Jörn Lang committed Dec 11, 2018

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    fac7c48 View commit details

Commits on Dec 13, 2018

  1. Merge branch '3.4' into 4.1

    * 3.4:
      [Debug] ignore underscore vs backslash namespaces in DebugClassLoader
      [TwigBridge][Form] Prevent multiple rendering of form collection prototypes
      [FrameworkBundle] fix describing routes with no controllers
      [DI] move RegisterServiceSubscribersPass before DecoratorServicePass
      Update ValidationListener.php
      [Yaml] ensures that the mb_internal_encoding is reset to its initial value
      [WebLink] Fixed documentation link
      [Security] getTargetPath of TargetPathTrait must return string or null
      [Hackday][Serializer] Deserialization ignores argument type hint from phpdoc for array in constructor argument
      [Security] defer log message in guard authenticator
      merge conflicts
      Fix HeaderBag::get phpdoc
    nicolas-grekas committed Dec 13, 2018
    Copy the full SHA
    32f16c3 View commit details

Commits on Dec 18, 2018

  1. Copy the full SHA
    463d57b View commit details

Commits on Dec 19, 2018

  1. bug #29639 [Yaml] detect circular references (xabbuh)

    This PR was merged into the 3.4 branch.
    
    Discussion
    ----------
    
    [Yaml] detect circular references
    
    | Q             | A
    | ------------- | ---
    | Branch?       | 3.4
    | Bug fix?      | yes
    | New feature?  | no
    | BC breaks?    | no
    | Deprecations? | no
    | Tests pass?   | yes
    | Fixed tickets | #29462
    | License       | MIT
    | Doc PR        |
    
    Commits
    -------
    
    b7487f476b [Yaml] detect circular references
    nicolas-grekas committed Dec 19, 2018
    Copy the full SHA
    dfb3b1e View commit details

Commits on Dec 23, 2018

  1. Merge branch '3.4' into 4.1

    * 3.4:
      [Tests] Change to willThrowException
      [Console] fix PHPDoc in Command
      Fix wrong calls to clearstatcache
      Add Vietnamese translation for validators
      Allow running PHPUnit with "xdebug.scream" ON
      [Yaml] detect circular references
    fabpot committed Dec 23, 2018
    Copy the full SHA
    e441723 View commit details

Commits on Jan 1, 2019

  1. update year in license files

    xabbuh committed Jan 1, 2019
    Copy the full SHA
    554a59a View commit details

Commits on Jan 3, 2019

  1. Merge branch '3.4' into 4.1

    * 3.4:
      Fix: Adjust DocBlock
      \"ParserTest->getParserTestData()\" -> only some more tests
      [Lock] Pedantic improvements for lock
      [EventDispatcher] Fixed phpdoc on interface
      update year in license files
      [Console] Fix help text for single command applications
      Fix random test failure on lock
      improve error message when using test client without the BrowserKit component
      [Event Dispatcher] fixed 29703: TraceableEventDispatcher reset now sets callStack to null with test to dispatch after reset.
      Fixed minor typos
      Fix: Method can also return null
      [Stopwatch] Fixed phpdoc for category name
    xabbuh committed Jan 3, 2019
    Copy the full SHA
    dd31d71 View commit details
Showing with 86 additions and 28 deletions.
  1. +2 −2 Command/LintCommand.php
  2. +27 −25 Inline.php
  3. +1 −1 LICENSE
  4. +14 −0 Parser.php
  5. +42 −0 Tests/ParserTest.php
4 changes: 2 additions & 2 deletions Command/LintCommand.php
Original file line number Diff line number Diff line change
@@ -229,7 +229,7 @@ private function getDirectoryIterator($directory)
};

if (null !== $this->directoryIteratorProvider) {
return \call_user_func($this->directoryIteratorProvider, $directory, $default);
return ($this->directoryIteratorProvider)($directory, $default);
}

return $default($directory);
@@ -242,7 +242,7 @@ private function isReadable($fileOrDirectory)
};

if (null !== $this->isReadableProvider) {
return \call_user_func($this->isReadableProvider, $fileOrDirectory, $default);
return ($this->isReadableProvider)($fileOrDirectory, $default);
}

return $default($fileOrDirectory);
52 changes: 27 additions & 25 deletions Inline.php
Original file line number Diff line number Diff line change
@@ -78,35 +78,37 @@ public static function parse(string $value = null, int $flags = 0, array $refere
mb_internal_encoding('ASCII');
}

$i = 0;
$tag = self::parseTag($value, $i, $flags);
switch ($value[$i]) {
case '[':
$result = self::parseSequence($value, $flags, $i, $references);
++$i;
break;
case '{':
$result = self::parseMapping($value, $flags, $i, $references);
++$i;
break;
default:
$result = self::parseScalar($value, $flags, null, $i, null === $tag, $references);
}
try {
$i = 0;
$tag = self::parseTag($value, $i, $flags);
switch ($value[$i]) {
case '[':
$result = self::parseSequence($value, $flags, $i, $references);
++$i;
break;
case '{':
$result = self::parseMapping($value, $flags, $i, $references);
++$i;
break;
default:
$result = self::parseScalar($value, $flags, null, $i, null === $tag, $references);
}

if (null !== $tag && '' !== $tag) {
return new TaggedValue($tag, $result);
}
if (null !== $tag && '' !== $tag) {
return new TaggedValue($tag, $result);
}

// some comments are allowed at the end
if (preg_replace('/\s+#.*$/A', '', substr($value, $i))) {
throw new ParseException(sprintf('Unexpected characters near "%s".', substr($value, $i)), self::$parsedLineNumber + 1, $value, self::$parsedFilename);
}
// some comments are allowed at the end
if (preg_replace('/\s+#.*$/A', '', substr($value, $i))) {
throw new ParseException(sprintf('Unexpected characters near "%s".', substr($value, $i)), self::$parsedLineNumber + 1, $value, self::$parsedFilename);
}

if (isset($mbEncoding)) {
mb_internal_encoding($mbEncoding);
return $result;
} finally {
if (isset($mbEncoding)) {
mb_internal_encoding($mbEncoding);
}
}

return $result;
}

/**
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright (c) 2004-2018 Fabien Potencier
Copyright (c) 2004-2019 Fabien Potencier

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
14 changes: 14 additions & 0 deletions Parser.php
Original file line number Diff line number Diff line change
@@ -35,6 +35,7 @@ class Parser
private $refs = array();
private $skippedLineNumbers = array();
private $locallySkippedLineNumbers = array();
private $refsBeingParsed = array();

/**
* Parses a YAML file into a PHP value.
@@ -169,6 +170,7 @@ private function doParse(string $value, int $flags)

if (isset($values['value']) && self::preg_match('#^&(?P<ref>[^ ]+) *(?P<value>.*)#u', $values['value'], $matches)) {
$isRef = $matches['ref'];
$this->refsBeingParsed[] = $isRef;
$values['value'] = $matches['value'];
}

@@ -201,6 +203,7 @@ private function doParse(string $value, int $flags)
}
if ($isRef) {
$this->refs[$isRef] = end($data);
array_pop($this->refsBeingParsed);
}
} elseif (
self::preg_match('#^(?P<key>(?:![^\s]++\s++)?(?:'.Inline::REGEX_QUOTED_STRING.'|(?:!?!php/const:)?[^ \'"\[\{!].*?)) *\:(\s++(?P<value>.+))?$#u', rtrim($this->currentLine), $values)
@@ -235,6 +238,10 @@ private function doParse(string $value, int $flags)
if (isset($values['value'][0]) && '*' === $values['value'][0]) {
$refName = substr(rtrim($values['value']), 1);
if (!array_key_exists($refName, $this->refs)) {
if (false !== $pos = array_search($refName, $this->refsBeingParsed, true)) {
throw new ParseException(sprintf('Circular reference [%s, %s] detected for reference "%s".', implode(', ', \array_slice($this->refsBeingParsed, $pos)), $refName, $refName), $this->currentLineNb + 1, $this->currentLine, $this->filename);
}

throw new ParseException(sprintf('Reference "%s" does not exist.', $refName), $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename);
}

@@ -288,6 +295,7 @@ private function doParse(string $value, int $flags)
}
} elseif ('<<' !== $key && isset($values['value']) && self::preg_match('#^&(?P<ref>[^ ]++) *+(?P<value>.*)#u', $values['value'], $matches)) {
$isRef = $matches['ref'];
$this->refsBeingParsed[] = $isRef;
$values['value'] = $matches['value'];
}

@@ -345,6 +353,7 @@ private function doParse(string $value, int $flags)
}
if ($isRef) {
$this->refs[$isRef] = $data[$key];
array_pop($this->refsBeingParsed);
}
} else {
// multiple documents are not supported
@@ -450,6 +459,7 @@ private function parseBlock(int $offset, string $yaml, int $flags)
$parser->totalNumberOfLines = $this->totalNumberOfLines;
$parser->skippedLineNumbers = $skippedLineNumbers;
$parser->refs = &$this->refs;
$parser->refsBeingParsed = $this->refsBeingParsed;

return $parser->doParse($yaml, $flags);
}
@@ -639,6 +649,10 @@ private function parseValue(string $value, int $flags, string $context)
}

if (!array_key_exists($value, $this->refs)) {
if (false !== $pos = array_search($value, $this->refsBeingParsed, true)) {
throw new ParseException(sprintf('Circular reference [%s, %s] detected for reference "%s".', implode(', ', \array_slice($this->refsBeingParsed, $pos)), $value, $value), $this->currentLineNb + 1, $this->currentLine, $this->filename);
}

throw new ParseException(sprintf('Reference "%s" does not exist.', $value), $this->currentLineNb + 1, $this->currentLine, $this->filename);
}

42 changes: 42 additions & 0 deletions Tests/ParserTest.php
Original file line number Diff line number Diff line change
@@ -2023,6 +2023,48 @@ public function testEvalRefException()
$this->parser->parse($yaml);
}

/**
* @dataProvider circularReferenceProvider
* @expectedException \Symfony\Component\Yaml\Exception\ParseException
* @expectedExceptionMessage Circular reference [foo, bar, foo] detected
*/
public function testDetectCircularReferences($yaml)
{
$this->parser->parse($yaml, Yaml::PARSE_CUSTOM_TAGS);
}

public function circularReferenceProvider()
{
$tests = array();

$yaml = <<<YAML
foo:
- &foo
- &bar
bar: foobar
baz: *foo
YAML;
$tests['sequence'] = array($yaml);

$yaml = <<<YAML
foo: &foo
bar: &bar
foobar: baz
baz: *foo
YAML;
$tests['mapping'] = array($yaml);

$yaml = <<<YAML
foo: &foo
bar: &bar
foobar: baz
<<: *foo
YAML;
$tests['mapping with merge key'] = array($yaml);

return $tests;
}

/**
* @dataProvider indentedMappingData
*/