bug #24673 [DI] Throw when a service name or an alias contains dynamic values (prevent an infinite loop) (dunglas)

This PR was squashed before being merged into the 3.3 branch (closes #24673).

Discussion
----------

[DI] Throw when a service name or an alias contains dynamic values (prevent an infinite loop)

| Q             | A
| ------------- | ---
| Branch?       | 3.4
| Bug fix?      | yes
| New feature?  | no <!-- don't forget to update src/**/CHANGELOG.md files -->
| BC breaks?    | no
| Deprecations? | no <!-- don't forget to update UPGRADE-*.md files -->
| Tests pass?   | yes
| Fixed tickets | n/a
| License       | MIT
| Doc PR        | n/a

If an environment variable is used to build a service name (like in [this snippet](4b3d1abfe5/src/Bridge/Symfony/Bundle/DependencyInjection/ApiPlatformExtension.php (L471))), an infinite loop occurs.

It's common to build dynamic service names (in a compiler pass), if the dynamic part comes from a parameter, this bug can occurs.

Commits
-------

14e30857ea [DI] Throw when a service name or an alias contains dynamic values (prevent an infinite loop)
This commit is contained in:
Fabien Potencier 2017-10-25 18:14:48 -07:00
commit 6cf3d5681a
2 changed files with 37 additions and 0 deletions

View File

@ -12,6 +12,7 @@
namespace Symfony\Component\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Exception\EnvParameterException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
/**
@ -75,6 +76,18 @@ class CheckDefinitionValidityPass implements CompilerPassInterface
}
}
}
$resolvedId = $container->resolveEnvPlaceholders($id, null, $usedEnvs);
if (null !== $usedEnvs) {
throw new EnvParameterException(array($resolvedId), null, 'A service name ("%s") cannot contain dynamic values.');
}
}
foreach ($container->getAliases() as $id => $alias) {
$resolvedId = $container->resolveEnvPlaceholders($id, null, $usedEnvs);
if (null !== $usedEnvs) {
throw new EnvParameterException(array($resolvedId), null, 'An alias name ("%s") cannot contain dynamic values.');
}
}
}
}

View File

@ -76,6 +76,30 @@ class CheckDefinitionValidityPassTest extends TestCase
$this->process($container);
}
/**
* @expectedException \Symfony\Component\DependencyInjection\Exception\EnvParameterException
*/
public function testDynamicServiceName()
{
$container = new ContainerBuilder();
$env = $container->getParameterBag()->get('env(BAR)');
$container->register("foo.$env", 'class');
$this->process($container);
}
/**
* @expectedException \Symfony\Component\DependencyInjection\Exception\EnvParameterException
*/
public function testDynamicAliasName()
{
$container = new ContainerBuilder();
$env = $container->getParameterBag()->get('env(BAR)');
$container->setAlias("foo.$env", 'class');
$this->process($container);
}
protected function process(ContainerBuilder $container)
{
$pass = new CheckDefinitionValidityPass();