bug #29409 Fix env fallback to an unresolved variable (jderusse)

This PR was submitted for the master branch but it was merged into the 4.2 branch instead (closes #29409).

Discussion
----------

Fix env fallback to an unresolved variable

| Q             | A
| ------------- | ---
| Branch?       | 4.2
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets |
| License       | MIT
| Doc PR        |

This PR fixes a tricky case where an env processor require to resolve another parameter.

For example, allowing a user to either pass a PEM key or the path to a PEM key, I could use this config
```
parameters:
  private_key: '%env(default:raw_key:file:PRIVATE_KEY)%'
  raw_key: '%env(PRIVATE_KEY)%'
```

here, the default processor, performs a `$container->getParameter('raw_key')` which fail because `raw_key` has to be resolved to.

I'm not sure, if this is the right way to do it, please review it carefully.

Here is my reproduct case
```
<?php

require __DIR__.'/vendor/autoload.php';

use Symfony\Component\DependencyInjection\ContainerBuilder;

$containerBuilder = new ContainerBuilder();
$containerBuilder->setParameter('env(PRIVATE_KEY)', 'FOO');
$containerBuilder->setParameter('raw_key', '%env(PRIVATE_KEY)%');
$containerBuilder->setParameter('private_key', '%env(default:raw_key:file:PRIVATE_KEY)%');
$containerBuilder->compile(true);

var_dump($containerBuilder->getParameter('private_key'));
```

Commits
-------

ad6df01b9f Fix env fallback to an unresolved variable
This commit is contained in:
Nicolas Grekas 2018-12-17 14:52:57 +01:00
commit ab95ae3f7a
2 changed files with 22 additions and 4 deletions

View File

@ -1534,11 +1534,15 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
return $value;
}
foreach ($bag->getEnvPlaceholders() as $env => $placeholders) {
if (isset($placeholders[$value])) {
$bag = new ParameterBag($bag->all());
$envPlaceholders = $bag->getEnvPlaceholders();
if (isset($envPlaceholders[$name][$value])) {
$bag = new ParameterBag($bag->all());
return $bag->unescapeValue($bag->get("env($name)"));
return $bag->unescapeValue($bag->get("env($name)"));
}
foreach ($envPlaceholders as $env => $placeholders) {
if (isset($placeholders[$value])) {
return $this->getEnv($env);
}
}

View File

@ -738,6 +738,20 @@ class ContainerBuilderTest extends TestCase
$this->assertSame('someFooBar', $container->getParameter('baz'));
}
public function testFallbackEnv()
{
putenv('DUMMY_FOO=foo');
$container = new ContainerBuilder();
$container->setParameter('foo', '%env(DUMMY_FOO)%');
$container->setParameter('bar', 'bar%env(default:foo:DUMMY_BAR)%');
$container->compile(true);
putenv('DUMMY_FOO');
$this->assertSame('barfoo', $container->getParameter('bar'));
}
public function testCastEnv()
{
$container = new ContainerBuilder();