From ce7de37f1623f7edde972cdbc7ad3c4d733e7bae Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Thu, 12 Sep 2013 08:52:33 +0200 Subject: [PATCH] [DependencyInjection] fixed a non-detected circular reference in PhpDumper (closes #8425) This circular reference cannot be detected by the compiler pass as we don't check for method arguments there. The Container itself already detects such circular references at runtime. So this fix is about circular references that are not detected at compile time, and are not even detected at runtime because the code that would cause the detection is never run (generated after a return statement.) --- .../DependencyInjection/Dumper/PhpDumper.php | 6 ++++++ .../Tests/Dumper/PhpDumperTest.php | 15 +++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index 31be3f416b7a..37f29e8a8861 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -387,6 +387,12 @@ private function addServiceInlinedDefinitionsSetup($id, $definition) continue; } + // if the instance is simple, the return statement has already been generated + // so, the only possible way to get there is because of a circular reference + if ($this->isSimpleInstance($id, $definition)) { + throw new ServiceCircularReferenceException($id, array($id)); + } + $name = (string) $this->definitionVariables->offsetGet($iDefinition); $code .= $this->addServiceMethodCalls(null, $iDefinition, $name); $code .= $this->addServiceProperties(null, $iDefinition, $name); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php index 369ac81bbedd..44043268d38c 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php @@ -155,4 +155,19 @@ public function testOverrideServiceWhenUsingADumpedContainerAndServiceIsUsedFrom $this->assertSame($bar, $container->get('foo')->bar, '->set() overrides an already defined service'); } + + /** + * @expectedException \Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException + */ + public function testCircularReference() + { + $container = new ContainerBuilder(); + $container->register('foo', 'stdClass')->addArgument(new Reference('bar')); + $container->register('bar', 'stdClass')->setPublic(false)->addMethodCall('setA', array(new Reference('baz'))); + $container->register('baz', 'stdClass')->addMethodCall('setA', array(new Reference('foo'))); + $container->compile(); + + $dumper = new PhpDumper($container); + $dumper->dump(); + } }