[Console] Fix allowing invalid #[Autowire] references in command arguments

This commit is contained in:
valtzu
2026-03-22 15:39:51 +02:00
parent a7a89a11b4
commit 56f4b1f44c
2 changed files with 58 additions and 0 deletions

View File

@@ -142,6 +142,7 @@ final class RegisterCommandArgumentLocatorsPass implements CompilerPassInterface
}
if ($autowireAttributes) {
$invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE;
$attribute = $autowireAttributes[0]->newInstance();
$value = $parameterBag->resolveValue($attribute->value);

View File

@@ -11,11 +11,14 @@
namespace Symfony\Component\Console\Tests\DependencyInjection;
use PHPUnit\Framework\Attributes\DoesNotPerformAssertions;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
use Symfony\Component\Console\DependencyInjection\RegisterCommandArgumentLocatorsPass;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\ServiceLocator;
@@ -58,6 +61,42 @@ class RegisterCommandArgumentLocatorsPassTest extends TestCase
$this->assertArrayHasKey('test:command', $commands);
}
#[DoesNotPerformAssertions]
public function testProcessServiceArgumentWithAutowireAttribute()
{
$container = new ContainerBuilder();
$container->register('console.argument_resolver.service')->setSynthetic(true)->addArgument(null);
$container->register('logger')->setSynthetic(true);
$command = new Definition(CommandWithAutowireAttribute::class);
$command->addTag('console.command', ['command' => 'test:command']);
$command->addTag('console.command.service_arguments');
$container->setDefinition('test.command', $command);
$pass = new RegisterCommandArgumentLocatorsPass();
$pass->process($container);
$container->compile();
}
public function testProcessThrowsOnInvalidAutowiredService()
{
$container = new ContainerBuilder();
$container->register('console.argument_resolver.service')->setSynthetic(true)->addArgument(null);
$command = new Definition(CommandWithAutowireAttributeInvalidReference::class);
$command->setAutowired(true);
$command->addTag('console.command', ['command' => 'test:command']);
$command->addTag('console.command.service_arguments');
$container->setDefinition('test.command', $command);
$pass = new RegisterCommandArgumentLocatorsPass();
$pass->process($container);
$this->expectException(ServiceNotFoundException::class);
$container->compile();
}
public function testProcessWithManualArgumentMapping()
{
$container = new ContainerBuilder();
@@ -177,6 +216,24 @@ class CommandWithServiceArguments
}
}
class CommandWithAutowireAttribute
{
public function __invoke(
#[Autowire(service: 'logger')]
LoggerInterface $logger,
) {
}
}
class CommandWithAutowireAttributeInvalidReference
{
public function __invoke(
#[Autowire(service: 'invalid.id')]
?\stdClass $service2 = null,
) {
}
}
class CommandWithInputOutput
{
public function __invoke(\Symfony\Component\Console\Input\InputInterface $input, \Symfony\Component\Console\Output\OutputInterface $output): void