-
-
Notifications
You must be signed in to change notification settings - Fork 9.7k
Description
Symfony version(s) affected
≥ 3.3.7
Description
When ContainerBuilder::compile
is called with $resolveEnvPlaceholders
, it will end up creating a new ParameterBag
from the old one:
symfony/src/Symfony/Component/DependencyInjection/ContainerBuilder.php
Lines 825 to 827 in 05d5bb3
if ($resolveEnvPlaceholders) { | |
$this->parameterBag = new ParameterBag($this->resolveEnvPlaceholders($bag->all(), true)); | |
} |
With true
as its second parameter, resolveEnvPlaceholders
will start by calling the bag’s resolveValue
method:
symfony/src/Symfony/Component/DependencyInjection/ContainerBuilder.php
Lines 1480 to 1482 in 05d5bb3
if (true === $format ??= '%%env(%s)%%') { | |
$value = $bag->resolveValue($value); | |
} |
Problem is, at this point the parameter bag already has been resolved by the ResolveParameterPlaceHoldersPass
, which means parameters’ value have been unescaped:
$parameters[$key] = $this->unescapeValue($value); |
Since unescaped parameters can appear as if they contain a placeholder, those will trigger a ParameterNotFoundException
.
How to reproduce
$builder = new ContainerBuilder();
$builder->setParameter('foo', '%%bar%%');
$builder->compile(true);
Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException: You have requested a non-existent parameter "bar".
Possible Solution
I guess an easy fix would be to ignore ParameterNotFoundException
s when creating the new ParameterBag
? It feels like addressing a symptom rather than a cause though.
Additional Context
Spotted while investigating #59028.