[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.)
This commit is contained in:
Fabien Potencier 2013-09-12 08:52:33 +02:00
parent 6ec2cbaa6c
commit ce7de37f16
2 changed files with 21 additions and 0 deletions

View File

@ -387,6 +387,12 @@ class PhpDumper extends Dumper
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);

View File

@ -155,4 +155,19 @@ class PhpDumperTest extends \PHPUnit_Framework_TestCase
$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();
}
}