Skip to content

Commit

Permalink
[DependencyInjection] Escape % from parameter-like default values
Browse files Browse the repository at this point in the history
  • Loading branch information
MatTheCat authored and nicolas-grekas committed May 30, 2023
1 parent 4645e03 commit e997597
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 4 deletions.
18 changes: 14 additions & 4 deletions Compiler/AutowirePass.php
Original file line number Diff line number Diff line change
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
13 changes: 13 additions & 0 deletions Tests/Compiler/AutowirePassTest.php
Original file line number Diff line number Diff line change
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));
}
}
7 changes: 7 additions & 0 deletions Tests/Fixtures/includes/autowiring_classes.php
Original file line number Diff line number Diff line change
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 e997597

Please sign in to comment.