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
This commit is contained in:
Fabien Potencier 2018-12-23 15:06:12 +01:00
commit 729edde312
31 changed files with 137 additions and 59 deletions

View File

@ -103,7 +103,7 @@ class TranslationDebugCommandTest extends TestCase
$kernel->expects($this->once())
->method('getBundle')
->with($this->equalTo('dir'))
->will($this->throwException(new \InvalidArgumentException()));
->willThrowException(new \InvalidArgumentException());
$tester = $this->createCommandTester(array(), array(), $kernel);
$tester->execute(array('locale' => 'en', 'bundle' => 'dir'));

View File

@ -60,7 +60,7 @@ class TemplateLocatorTest extends TestCase
$fileLocator
->expects($this->once())
->method('locate')
->will($this->throwException(new \InvalidArgumentException($errorMessage)))
->willThrowException(new \InvalidArgumentException($errorMessage))
;
$locator = new TemplateLocator($fileLocator);

View File

@ -68,7 +68,7 @@ class FilesystemLoaderTest extends TestCase
$locator
->expects($this->once())
->method('locate')
->will($this->throwException(new \InvalidArgumentException('Unable to find template "NonExistent".')))
->willThrowException(new \InvalidArgumentException('Unable to find template "NonExistent".'))
;
$loader = new FilesystemLoader($locator, $parser);

View File

@ -252,7 +252,7 @@ class WebDebugToolbarListenerTest extends TestCase
->expects($this->once())
->method('generate')
->with('_profiler', array('token' => 'xxxxxxxx'))
->will($this->throwException(new \Exception('foo')))
->willThrowException(new \Exception('foo'))
;
$event = new FilterResponseEvent($this->getKernelMock(), $this->getRequestMock(), HttpKernelInterface::MASTER_REQUEST, $response);
@ -273,7 +273,7 @@ class WebDebugToolbarListenerTest extends TestCase
->expects($this->once())
->method('generate')
->with('_profiler', array('token' => 'xxxxxxxx'))
->will($this->throwException(new \Exception("This\nmultiline\r\ntabbed text should\tcome out\r on\n \ta single plain\r\nline")))
->willThrowException(new \Exception("This\nmultiline\r\ntabbed text should\tcome out\r on\n \ta single plain\r\nline"))
;
$event = new FilterResponseEvent($this->getKernelMock(), $this->getRequestMock(), HttpKernelInterface::MASTER_REQUEST, $response);

View File

@ -361,9 +361,9 @@ class Command
* Adds an argument.
*
* @param string $name The argument name
* @param int|null $mode The argument mode: self::REQUIRED or self::OPTIONAL
* @param int|null $mode The argument mode: InputArgument::REQUIRED or InputArgument::OPTIONAL
* @param string $description A description text
* @param string|string[]|null $default The default value (for self::OPTIONAL mode only)
* @param string|string[]|null $default The default value (for InputArgument::OPTIONAL mode only)
*
* @throws InvalidArgumentException When argument mode is not valid
*
@ -381,9 +381,9 @@ class Command
*
* @param string $name The option name
* @param string|array $shortcut The shortcuts, can be null, a string of shortcuts delimited by | or an array of shortcuts
* @param int|null $mode The option mode: One of the VALUE_* constants
* @param int|null $mode The option mode: One of the InputOption::VALUE_* constants
* @param string $description A description text
* @param string|string[]|int|bool|null $default The default value (must be null for self::VALUE_NONE)
* @param string|string[]|int|bool|null $default The default value (must be null for InputOption::VALUE_NONE)
*
* @throws InvalidArgumentException If option mode is invalid or incompatible
*

View File

@ -967,7 +967,7 @@ class ApplicationTest extends TestCase
$application->setAutoExit(false);
$application->expects($this->once())
->method('doRun')
->will($this->throwException($exception));
->willThrowException($exception);
$exitCode = $application->run(new ArrayInput(array()), new NullOutput());
@ -1006,7 +1006,7 @@ class ApplicationTest extends TestCase
$application->setAutoExit(false);
$application->expects($this->once())
->method('doRun')
->will($this->throwException($exception));
->willThrowException($exception);
$exitCode = $application->run(new ArrayInput(array()), new NullOutput());

View File

@ -697,7 +697,7 @@ class FinderTest extends Iterator\RealIteratorTestCase
// restore original permissions
chmod($testDir, 0777);
clearstatcache($testDir);
clearstatcache(true, $testDir);
if ($couldRead) {
$this->markTestSkipped('could read test files while test requires unreadable');
@ -723,7 +723,7 @@ class FinderTest extends Iterator\RealIteratorTestCase
// restore original permissions
chmod($testDir, 0777);
clearstatcache($testDir);
clearstatcache(true, $testDir);
if ($couldRead) {
$this->markTestSkipped('could read test files while test requires unreadable');

View File

@ -0,0 +1,19 @@
<?xml version="1.0"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file source-language="en" datatype="plaintext" original="file.ext">
<body>
<trans-unit id="28">
<source>This form should not contain extra fields.</source>
<target>Mẫu này không nên chứa trường mở rộng</target>
</trans-unit>
<trans-unit id="29">
<source>The uploaded file was too large. Please try to upload a smaller file.</source>
<target>Tập tin tải lên quá lớn. Vui lòng thử lại với tập tin nhỏ hơn.</target>
</trans-unit>
<trans-unit id="30">
<source>The CSRF token is invalid. Please try to resubmit the form.</source>
<target>CSRF token không hợp lệ. Vui lòng thử lại.</target>
</trans-unit>
</body>
</file>
</xliff>

View File

@ -620,7 +620,7 @@ class SimpleFormTest extends AbstractFormTest
$transformer = $this->getDataTransformer();
$transformer->expects($this->once())
->method('reverseTransform')
->will($this->throwException(new TransformationFailedException()));
->willThrowException(new TransformationFailedException());
$form = $this->getBuilder()
->addViewTransformer($transformer)
@ -636,7 +636,7 @@ class SimpleFormTest extends AbstractFormTest
$transformer = $this->getDataTransformer();
$transformer->expects($this->once())
->method('reverseTransform')
->will($this->throwException(new TransformationFailedException()));
->willThrowException(new TransformationFailedException());
$form = $this->getBuilder()
->addModelTransformer($transformer)

View File

@ -708,7 +708,10 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl
$fs->dumpFile($dir.$file, $code);
@chmod($dir.$file, 0666 & ~umask());
}
@unlink(\dirname($dir.$file).'.legacy');
$legacyFile = \dirname($dir.$file).'.legacy';
if (file_exists($legacyFile)) {
@unlink($legacyFile);
}
$cache->write($rootCode, $container->getResources());
}

View File

@ -47,7 +47,7 @@ class TranslatorListenerTest extends TestCase
$this->translator
->expects($this->at(0))
->method('setLocale')
->will($this->throwException(new \InvalidArgumentException()));
->willThrowException(new \InvalidArgumentException());
$this->translator
->expects($this->at(1))
->method('setLocale')
@ -84,7 +84,7 @@ class TranslatorListenerTest extends TestCase
$this->translator
->expects($this->at(0))
->method('setLocale')
->will($this->throwException(new \InvalidArgumentException()));
->willThrowException(new \InvalidArgumentException());
$this->translator
->expects($this->at(1))
->method('setLocale')

View File

@ -80,7 +80,7 @@ class HIncludeFragmentRendererTest extends TestCase
$engine->expects($this->once())
->method('exists')
->with('default')
->will($this->throwException(new \InvalidArgumentException()));
->willThrowException(new \InvalidArgumentException());
// only default
$strategy = new HIncludeFragmentRenderer($engine);
@ -93,7 +93,7 @@ class HIncludeFragmentRendererTest extends TestCase
$engine->expects($this->once())
->method('exists')
->with('loading...')
->will($this->throwException(new \RuntimeException()));
->willThrowException(new \RuntimeException());
// only default
$strategy = new HIncludeFragmentRenderer($engine);

View File

@ -148,7 +148,7 @@ class BundleEntryReaderTest extends TestCase
$this->readerImpl->expects($this->at(0))
->method('read')
->with(self::RES_DIR, 'en_GB')
->will($this->throwException(new ResourceBundleNotFoundException()));
->willThrowException(new ResourceBundleNotFoundException());
$this->readerImpl->expects($this->at(1))
->method('read')
@ -166,7 +166,7 @@ class BundleEntryReaderTest extends TestCase
$this->readerImpl->expects($this->once())
->method('read')
->with(self::RES_DIR, 'en_GB')
->will($this->throwException(new ResourceBundleNotFoundException()));
->willThrowException(new ResourceBundleNotFoundException());
$this->reader->readEntry(self::RES_DIR, 'en_GB', array('Entries', 'Bam'), false);
}

View File

@ -188,7 +188,7 @@ class AuthenticationProviderManagerTest extends TestCase
} elseif (null !== $exception) {
$provider->expects($this->once())
->method('authenticate')
->will($this->throwException($this->getMockBuilder($exception)->setMethods(null)->getMock()))
->willThrowException($this->getMockBuilder($exception)->setMethods(null)->getMock())
;
}

View File

@ -38,7 +38,7 @@ class DaoAuthenticationProviderTest extends TestCase
$userProvider = $this->getMockBuilder('Symfony\\Component\\Security\\Core\\User\\UserProviderInterface')->getMock();
$userProvider->expects($this->once())
->method('loadUserByUsername')
->will($this->throwException(new UsernameNotFoundException()))
->willThrowException(new UsernameNotFoundException())
;
$provider = new DaoAuthenticationProvider($userProvider, $this->getMockBuilder('Symfony\\Component\\Security\\Core\\User\\UserCheckerInterface')->getMock(), 'key', $this->getMockBuilder('Symfony\\Component\\Security\\Core\\Encoder\\EncoderFactoryInterface')->getMock());
@ -56,7 +56,7 @@ class DaoAuthenticationProviderTest extends TestCase
$userProvider = $this->getMockBuilder('Symfony\\Component\\Security\\Core\\User\\UserProviderInterface')->getMock();
$userProvider->expects($this->once())
->method('loadUserByUsername')
->will($this->throwException(new \RuntimeException()))
->willThrowException(new \RuntimeException())
;
$provider = new DaoAuthenticationProvider($userProvider, $this->getMockBuilder('Symfony\\Component\\Security\\Core\\User\\UserCheckerInterface')->getMock(), 'key', $this->getMockBuilder('Symfony\\Component\\Security\\Core\\Encoder\\EncoderFactoryInterface')->getMock());

View File

@ -73,7 +73,7 @@ class LdapBindAuthenticationProviderTest extends TestCase
$ldap
->expects($this->once())
->method('bind')
->will($this->throwException(new ConnectionException()))
->willThrowException(new ConnectionException())
;
$userChecker = $this->getMockBuilder(UserCheckerInterface::class)->getMock();

View File

@ -85,7 +85,7 @@ class PreAuthenticatedAuthenticationProviderTest extends TestCase
$userChecker = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserCheckerInterface')->getMock();
$userChecker->expects($this->once())
->method('checkPostAuth')
->will($this->throwException(new LockedException()))
->willThrowException(new LockedException())
;
$provider = $this->getProvider($user, $userChecker);

View File

@ -57,7 +57,7 @@ class RememberMeAuthenticationProviderTest extends TestCase
$userChecker = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserCheckerInterface')->getMock();
$userChecker->expects($this->once())
->method('checkPreAuth')
->will($this->throwException(new DisabledException()));
->willThrowException(new DisabledException());
$provider = $this->getProvider($userChecker);

View File

@ -34,7 +34,7 @@ class SimpleAuthenticationProviderTest extends TestCase
$userChecker = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserCheckerInterface')->getMock();
$userChecker->expects($this->once())
->method('checkPreAuth')
->will($this->throwException(new DisabledException()));
->willThrowException(new DisabledException());
$authenticator = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\SimpleAuthenticatorInterface')->getMock();
$authenticator->expects($this->once())
@ -61,7 +61,7 @@ class SimpleAuthenticationProviderTest extends TestCase
$userChecker = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserCheckerInterface')->getMock();
$userChecker->expects($this->once())
->method('checkPostAuth')
->will($this->throwException(new LockedException()));
->willThrowException(new LockedException());
$authenticator = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\SimpleAuthenticatorInterface')->getMock();
$authenticator->expects($this->once())

View File

@ -48,7 +48,7 @@ class UserAuthenticationProviderTest extends TestCase
$provider = $this->getProvider(false, false);
$provider->expects($this->once())
->method('retrieveUser')
->will($this->throwException(new UsernameNotFoundException()))
->willThrowException(new UsernameNotFoundException())
;
$provider->authenticate($this->getSupportedToken());
@ -62,7 +62,7 @@ class UserAuthenticationProviderTest extends TestCase
$provider = $this->getProvider(false, true);
$provider->expects($this->once())
->method('retrieveUser')
->will($this->throwException(new UsernameNotFoundException()))
->willThrowException(new UsernameNotFoundException())
;
$provider->authenticate($this->getSupportedToken());
@ -90,7 +90,7 @@ class UserAuthenticationProviderTest extends TestCase
$userChecker = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserCheckerInterface')->getMock();
$userChecker->expects($this->once())
->method('checkPreAuth')
->will($this->throwException(new CredentialsExpiredException()))
->willThrowException(new CredentialsExpiredException())
;
$provider = $this->getProvider($userChecker);
@ -110,7 +110,7 @@ class UserAuthenticationProviderTest extends TestCase
$userChecker = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserCheckerInterface')->getMock();
$userChecker->expects($this->once())
->method('checkPostAuth')
->will($this->throwException(new AccountExpiredException()))
->willThrowException(new AccountExpiredException())
;
$provider = $this->getProvider($userChecker);
@ -135,7 +135,7 @@ class UserAuthenticationProviderTest extends TestCase
;
$provider->expects($this->once())
->method('checkAuthentication')
->will($this->throwException(new BadCredentialsException()))
->willThrowException(new BadCredentialsException())
;
$provider->authenticate($this->getSupportedToken());
@ -154,7 +154,7 @@ class UserAuthenticationProviderTest extends TestCase
;
$provider->expects($this->once())
->method('checkAuthentication')
->will($this->throwException(new BadCredentialsException('Foo')))
->willThrowException(new BadCredentialsException('Foo'))
;
$provider->authenticate($this->getSupportedToken());

View File

@ -25,7 +25,7 @@ class ChainUserProviderTest extends TestCase
->expects($this->once())
->method('loadUserByUsername')
->with($this->equalTo('foo'))
->will($this->throwException(new UsernameNotFoundException('not found')))
->willThrowException(new UsernameNotFoundException('not found'))
;
$provider2 = $this->getProvider();
@ -50,7 +50,7 @@ class ChainUserProviderTest extends TestCase
->expects($this->once())
->method('loadUserByUsername')
->with($this->equalTo('foo'))
->will($this->throwException(new UsernameNotFoundException('not found')))
->willThrowException(new UsernameNotFoundException('not found'))
;
$provider2 = $this->getProvider();
@ -58,7 +58,7 @@ class ChainUserProviderTest extends TestCase
->expects($this->once())
->method('loadUserByUsername')
->with($this->equalTo('foo'))
->will($this->throwException(new UsernameNotFoundException('not found')))
->willThrowException(new UsernameNotFoundException('not found'))
;
$provider = new ChainUserProvider(array($provider1, $provider2));
@ -71,7 +71,7 @@ class ChainUserProviderTest extends TestCase
$provider1
->expects($this->once())
->method('refreshUser')
->will($this->throwException(new UnsupportedUserException('unsupported')))
->willThrowException(new UnsupportedUserException('unsupported'))
;
$provider2 = $this->getProvider();
@ -91,7 +91,7 @@ class ChainUserProviderTest extends TestCase
$provider1
->expects($this->once())
->method('refreshUser')
->will($this->throwException(new UsernameNotFoundException('not found')))
->willThrowException(new UsernameNotFoundException('not found'))
;
$provider2 = $this->getProvider();
@ -114,14 +114,14 @@ class ChainUserProviderTest extends TestCase
$provider1
->expects($this->once())
->method('refreshUser')
->will($this->throwException(new UnsupportedUserException('unsupported')))
->willThrowException(new UnsupportedUserException('unsupported'))
;
$provider2 = $this->getProvider();
$provider2
->expects($this->once())
->method('refreshUser')
->will($this->throwException(new UnsupportedUserException('unsupported')))
->willThrowException(new UnsupportedUserException('unsupported'))
;
$provider = new ChainUserProvider(array($provider1, $provider2));
@ -178,7 +178,7 @@ class ChainUserProviderTest extends TestCase
$provider1
->expects($this->once())
->method('refreshUser')
->will($this->throwException(new UnsupportedUserException('unsupported')))
->willThrowException(new UnsupportedUserException('unsupported'))
;
$provider2 = $this->getProvider();

View File

@ -33,7 +33,7 @@ class LdapUserProviderTest extends TestCase
$ldap
->expects($this->once())
->method('bind')
->will($this->throwException(new ConnectionException()))
->willThrowException(new ConnectionException())
;
$provider = new LdapUserProvider($ldap, 'ou=MyBusiness,dc=symfony,dc=com');

View File

@ -183,7 +183,7 @@ class GuardAuthenticationListenerTest extends TestCase
$authenticator
->expects($this->once())
->method('getCredentials')
->will($this->throwException($authException));
->willThrowException($authException);
// this is not called
$this->authenticationManager

View File

@ -90,7 +90,7 @@ class AbstractPreAuthenticatedListenerTest extends TestCase
->expects($this->once())
->method('authenticate')
->with($this->isInstanceOf('Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken'))
->will($this->throwException($exception))
->willThrowException($exception)
;
$listener = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Firewall\AbstractPreAuthenticatedListener', array(
@ -138,7 +138,7 @@ class AbstractPreAuthenticatedListenerTest extends TestCase
->expects($this->once())
->method('authenticate')
->with($this->isInstanceOf('Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken'))
->will($this->throwException($exception))
->willThrowException($exception)
;
$listener = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Firewall\AbstractPreAuthenticatedListener', array(
@ -228,7 +228,7 @@ class AbstractPreAuthenticatedListenerTest extends TestCase
->expects($this->once())
->method('authenticate')
->with($this->isInstanceOf('Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken'))
->will($this->throwException($exception))
->willThrowException($exception)
;
$listener = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Firewall\AbstractPreAuthenticatedListener', array(

View File

@ -90,7 +90,7 @@ class RememberMeListenerTest extends TestCase
$manager
->expects($this->once())
->method('authenticate')
->will($this->throwException($exception))
->willThrowException($exception)
;
$event = $this->getGetResponseEvent();
@ -132,7 +132,7 @@ class RememberMeListenerTest extends TestCase
$manager
->expects($this->once())
->method('authenticate')
->will($this->throwException($exception))
->willThrowException($exception)
;
$event = $this->getGetResponseEvent();
@ -159,7 +159,7 @@ class RememberMeListenerTest extends TestCase
$service
->expects($this->once())
->method('autoLogin')
->will($this->throwException($exception))
->willThrowException($exception)
;
$service

View File

@ -72,7 +72,7 @@ class SimplePreAuthenticationListenerTest extends TestCase
->expects($this->once())
->method('authenticate')
->with($this->equalTo($this->token))
->will($this->throwException($exception))
->willThrowException($exception)
;
$this->tokenStorage->expects($this->once())

View File

@ -200,7 +200,7 @@ class HttpUtilsTest extends TestCase
->expects($this->any())
->method('match')
->with('/')
->will($this->throwException(new ResourceNotFoundException()))
->willThrowException(new ResourceNotFoundException())
;
$utils = new HttpUtils(null, $urlMatcher);
@ -215,7 +215,7 @@ class HttpUtilsTest extends TestCase
->expects($this->any())
->method('matchRequest')
->with($request)
->will($this->throwException(new MethodNotAllowedException(array())))
->willThrowException(new MethodNotAllowedException(array()))
;
$utils = new HttpUtils(null, $urlMatcher);
@ -260,7 +260,7 @@ class HttpUtilsTest extends TestCase
$urlMatcher
->expects($this->any())
->method('match')
->will($this->throwException(new \RuntimeException()))
->willThrowException(new \RuntimeException())
;
$utils = new HttpUtils(null, $urlMatcher);

View File

@ -65,7 +65,7 @@ class PersistentTokenBasedRememberMeServicesTest extends TestCase
$tokenProvider
->expects($this->once())
->method('loadTokenBySeries')
->will($this->throwException(new TokenNotFoundException('Token not found.')))
->willThrowException(new TokenNotFoundException('Token not found.'))
;
$service->setTokenProvider($tokenProvider);
@ -91,7 +91,7 @@ class PersistentTokenBasedRememberMeServicesTest extends TestCase
$userProvider
->expects($this->once())
->method('loadUserByUsername')
->will($this->throwException(new UsernameNotFoundException('user not found')))
->willThrowException(new UsernameNotFoundException('user not found'))
;
$this->assertNull($service->autoLogin($request));

View File

@ -49,7 +49,7 @@ class TokenBasedRememberMeServicesTest extends TestCase
$userProvider
->expects($this->once())
->method('loadUserByUsername')
->will($this->throwException(new UsernameNotFoundException('user not found')))
->willThrowException(new UsernameNotFoundException('user not found'))
;
$this->assertNull($service->autoLogin($request));

View File

@ -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 @@ class Parser
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 @@ class Parser
}
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 @@ class Parser
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 @@ class Parser
}
} 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 @@ class Parser
}
if ($isRef) {
$this->refs[$isRef] = $data[$key];
array_pop($this->refsBeingParsed);
}
} else {
// multiple documents are not supported
@ -450,6 +459,7 @@ class Parser
$parser->totalNumberOfLines = $this->totalNumberOfLines;
$parser->skippedLineNumbers = $skippedLineNumbers;
$parser->refs = &$this->refs;
$parser->refsBeingParsed = $this->refsBeingParsed;
return $parser->doParse($yaml, $flags);
}
@ -639,6 +649,10 @@ class Parser
}
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);
}

View File

@ -2023,6 +2023,48 @@ EOE;
$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
*/