Skip to content

Commit

Permalink
bug #50478 [DependencyInjection] Escape % from parameter-like defau…
Browse files Browse the repository at this point in the history
…lt values (MatTheCat)

This PR was merged into the 5.4 branch.

Discussion
----------

[DependencyInjection] Escape `%` from parameter-like default values

| Q             | A
| ------------- | ---
| Branch?       | 5.4
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       | Fix #50469
| License       | MIT
| Doc PR        | N/A

When string default values are autowired, they shouldn’t reference parameters.

This PR tries to address the issue by escaping them in the `AutowirePass`.

Commits
-------

bb4eeb0 [DependencyInjection] Escape `%` from parameter-like default values
  • Loading branch information
nicolas-grekas committed May 30, 2023
2 parents 3bc1a40 + bb4eeb0 commit cc6c007
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 4 deletions.
Expand Up @@ -52,6 +52,15 @@ public function __construct(bool $throwOnAutowireException = true)
$this->defaultArgument = new class() {
public $value;
public $names;
public $bag;

public function withValue(\ReflectionParameter $parameter): self
{
$clone = clone $this;
$clone->value = $this->bag->escapeValue($parameter->getDefaultValue());

return $clone;
}
};
}

Expand All @@ -60,13 +69,16 @@ public function __construct(bool $throwOnAutowireException = true)
*/
public function process(ContainerBuilder $container)
{
$this->defaultArgument->bag = $container->getParameterBag();

try {
$this->typesClone = clone $this;
parent::process($container);
} finally {
$this->decoratedClass = null;
$this->decoratedId = null;
$this->methodCalls = null;
$this->defaultArgument->bag = null;
$this->defaultArgument->names = null;
$this->getPreviousValue = null;
$this->decoratedMethodIndex = null;
Expand Down Expand Up @@ -287,8 +299,7 @@ private function autowireMethod(\ReflectionFunctionAbstract $reflectionMethod, a
}

// specifically pass the default value
$arguments[$index] = clone $this->defaultArgument;
$arguments[$index]->value = $parameter->getDefaultValue();
$arguments[$index] = $this->defaultArgument->withValue($parameter);

continue;
}
Expand All @@ -298,8 +309,7 @@ private function autowireMethod(\ReflectionFunctionAbstract $reflectionMethod, a
$failureMessage = $this->createTypeNotFoundMessageCallback($ref, sprintf('argument "$%s" of method "%s()"', $parameter->name, $class !== $this->currentId ? $class.'::'.$method : $method));

if ($parameter->isDefaultValueAvailable()) {
$value = clone $this->defaultArgument;
$value->value = $parameter->getDefaultValue();
$value = $this->defaultArgument->withValue($parameter);
} elseif (!$parameter->allowsNull()) {
throw new AutowiringFailedException($this->currentId, $failureMessage);
}
Expand Down
Expand Up @@ -1219,4 +1219,17 @@ public function testAutowireWithNamedArgs()

$this->assertEquals([new TypedReference(A::class, A::class), 'abc'], $container->getDefinition('foo')->getArguments());
}

public function testAutowireDefaultValueParametersLike()
{
$container = new ContainerBuilder();

$container->register('foo', ParametersLikeDefaultValue::class)
->setAutowired(true)
->setArgument(1, 'ok');

(new AutowirePass())->process($container);

$this->assertSame('%%not%%one%%parameter%%here%%', $container->getDefinition('foo')->getArgument(0));
}
}
Expand Up @@ -431,3 +431,10 @@ public function __construct(NotExisting $notExisting)
{
}
}

class ParametersLikeDefaultValue
{
public function __construct(string $parameterLike = '%not%one%parameter%here%', string $willBeSetToKeepFirstArgumentDefaultValue = 'ok')
{
}
}

0 comments on commit cc6c007

Please sign in to comment.