From 40663b49fbddbe72db81ec8a84233e8c31c5c6d1 Mon Sep 17 00:00:00 2001 From: Maxime Steinhausser Date: Fri, 3 Jun 2022 14:46:29 +0200 Subject: [PATCH 1/5] [Console] Escape % in command name & description from getDefault*() --- DependencyInjection/AddConsoleCommandPass.php | 4 +-- .../AddConsoleCommandPassTest.php | 33 +++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/DependencyInjection/AddConsoleCommandPass.php b/DependencyInjection/AddConsoleCommandPass.php index 743e306d0..2c9ebe668 100644 --- a/DependencyInjection/AddConsoleCommandPass.php +++ b/DependencyInjection/AddConsoleCommandPass.php @@ -67,7 +67,7 @@ public function process(ContainerBuilder $container) if (!$r->isSubclassOf(Command::class)) { throw new InvalidArgumentException(sprintf('The service "%s" tagged "%s" must be a subclass of "%s".', $id, $this->commandTag, Command::class)); } - $aliases = $class::getDefaultName(); + $aliases = str_replace('%', '%%', $class::getDefaultName()); } $aliases = explode('|', $aliases ?? ''); @@ -124,7 +124,7 @@ public function process(ContainerBuilder $container) if (!$r->isSubclassOf(Command::class)) { throw new InvalidArgumentException(sprintf('The service "%s" tagged "%s" must be a subclass of "%s".', $id, $this->commandTag, Command::class)); } - $description = $class::getDefaultDescription(); + $description = str_replace('%', '%%', $class::getDefaultDescription()); } if ($description) { diff --git a/Tests/DependencyInjection/AddConsoleCommandPassTest.php b/Tests/DependencyInjection/AddConsoleCommandPassTest.php index aa92c76f1..eec4eff43 100644 --- a/Tests/DependencyInjection/AddConsoleCommandPassTest.php +++ b/Tests/DependencyInjection/AddConsoleCommandPassTest.php @@ -153,6 +153,33 @@ public function testProcessFallsBackToDefaultDescription() $this->assertSame(1 + $initCounter, DescribedCommand::$initCounter); } + public function testEscapesDefaultFromPhp() + { + $container = new ContainerBuilder(); + $container + ->register('to-escape', EscapedDefaultsFromPhpCommand::class) + ->addTag('console.command') + ; + + $pass = new AddConsoleCommandPass(); + $pass->process($container); + + $commandLoader = $container->getDefinition('console.command_loader'); + $commandLocator = $container->getDefinition((string) $commandLoader->getArgument(0)); + + $this->assertSame(ContainerCommandLoader::class, $commandLoader->getClass()); + $this->assertSame(['%%cmd%%' => 'to-escape', '%%cmdalias%%' => 'to-escape'], $commandLoader->getArgument(1)); + $this->assertEquals([['to-escape' => new ServiceClosureArgument(new Reference('.to-escape.lazy'))]], $commandLocator->getArguments()); + $this->assertSame([], $container->getParameter('console.command.ids')); + + $command = $container->get('console.command_loader')->get('%%cmd%%'); + + $this->assertInstanceOf(LazyCommand::class, $command); + $this->assertSame('%cmd%', $command->getName()); + $this->assertSame(['%cmdalias%'], $command->getAliases()); + $this->assertSame('Creates a 80% discount', $command->getDescription()); + } + public function testProcessThrowAnExceptionIfTheServiceIsAbstract() { $this->expectException(\InvalidArgumentException::class); @@ -286,6 +313,12 @@ class NamedCommand extends Command protected static $defaultName = 'default'; } +class EscapedDefaultsFromPhpCommand extends Command +{ + protected static $defaultName = '%cmd%|%cmdalias%'; + protected static $defaultDescription = 'Creates a 80% discount'; +} + class DescribedCommand extends Command { public static $initCounter = 0; From b4a1d2d45124b7ca87ec1e3bae40455c6be0cad8 Mon Sep 17 00:00:00 2001 From: Maxime Steinhausser Date: Fri, 3 Jun 2022 14:46:29 +0200 Subject: [PATCH 2/5] [Console] Escape % in command name & description from getDefault*() --- DependencyInjection/AddConsoleCommandPass.php | 2 +- .../AddConsoleCommandPassTest.php | 29 +++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/DependencyInjection/AddConsoleCommandPass.php b/DependencyInjection/AddConsoleCommandPass.php index 666c8fa59..aff892cc2 100644 --- a/DependencyInjection/AddConsoleCommandPass.php +++ b/DependencyInjection/AddConsoleCommandPass.php @@ -55,7 +55,7 @@ public function process(ContainerBuilder $container) if (!$r->isSubclassOf(Command::class)) { throw new InvalidArgumentException(sprintf('The service "%s" tagged "%s" must be a subclass of "%s".', $id, $this->commandTag, Command::class)); } - $commandName = $class::getDefaultName(); + $commandName = $class::getDefaultName() !== null ? str_replace('%', '%%', $class::getDefaultName()) : null; } if (null === $commandName) { diff --git a/Tests/DependencyInjection/AddConsoleCommandPassTest.php b/Tests/DependencyInjection/AddConsoleCommandPassTest.php index 5e59f8fab..9c86fa98f 100644 --- a/Tests/DependencyInjection/AddConsoleCommandPassTest.php +++ b/Tests/DependencyInjection/AddConsoleCommandPassTest.php @@ -118,6 +118,30 @@ public function visibilityProvider() ]; } + public function testEscapesDefaultFromPhp() + { + $container = new ContainerBuilder(); + $container + ->register('to-escape', EscapedDefaultsFromPhpCommand::class) + ->addTag('console.command') + ; + + $pass = new AddConsoleCommandPass(); + $pass->process($container); + + $commandLoader = $container->getDefinition('console.command_loader'); + $commandLocator = $container->getDefinition((string) $commandLoader->getArgument(0)); + + $this->assertSame(ContainerCommandLoader::class, $commandLoader->getClass()); + $this->assertSame(['%%cmd%%' => 'to-escape'], $commandLoader->getArgument(1)); + $this->assertEquals([['to-escape' => new ServiceClosureArgument(new TypedReference('to-escape', EscapedDefaultsFromPhpCommand::class))]], $commandLocator->getArguments()); + $this->assertSame([], $container->getParameter('console.command.ids')); + + $command = $container->get('console.command_loader')->get('%%cmd%%'); + + $this->assertSame('%cmd%', $command->getName()); + } + public function testProcessThrowAnExceptionIfTheServiceIsAbstract() { $this->expectException(\InvalidArgumentException::class); @@ -250,3 +274,8 @@ class NamedCommand extends Command { protected static $defaultName = 'default'; } + +class EscapedDefaultsFromPhpCommand extends Command +{ + protected static $defaultName = '%cmd%'; +} From 948192497e2bbbb697571a7590ee63d041b21e72 Mon Sep 17 00:00:00 2001 From: Maxime Steinhausser Date: Mon, 6 Jun 2022 14:28:06 +0200 Subject: [PATCH 3/5] [Console] Prevent PHP 8.1 str_replace deprec on null Prevents: > Deprecated: str_replace(): Passing null to parameter #3 ($subject) of type array|string is deprecated on `getDefaultName()` returning `null` --- DependencyInjection/AddConsoleCommandPass.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DependencyInjection/AddConsoleCommandPass.php b/DependencyInjection/AddConsoleCommandPass.php index 2c9ebe668..c55c5db4e 100644 --- a/DependencyInjection/AddConsoleCommandPass.php +++ b/DependencyInjection/AddConsoleCommandPass.php @@ -67,7 +67,7 @@ public function process(ContainerBuilder $container) if (!$r->isSubclassOf(Command::class)) { throw new InvalidArgumentException(sprintf('The service "%s" tagged "%s" must be a subclass of "%s".', $id, $this->commandTag, Command::class)); } - $aliases = str_replace('%', '%%', $class::getDefaultName()); + $aliases = str_replace('%', '%%', $class::getDefaultName() ?? ''); } $aliases = explode('|', $aliases ?? ''); From 56f40c96d6619cd87717a066f7ce65054bfd38b1 Mon Sep 17 00:00:00 2001 From: HypeMC Date: Tue, 7 Jun 2022 04:10:23 +0200 Subject: [PATCH 4/5] [Console] Fix deprecation when description is null str_replace(): Passing null to parameter #3 ($subject) of type array|string is deprecated --- DependencyInjection/AddConsoleCommandPass.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DependencyInjection/AddConsoleCommandPass.php b/DependencyInjection/AddConsoleCommandPass.php index c55c5db4e..1fbb212e7 100644 --- a/DependencyInjection/AddConsoleCommandPass.php +++ b/DependencyInjection/AddConsoleCommandPass.php @@ -124,7 +124,7 @@ public function process(ContainerBuilder $container) if (!$r->isSubclassOf(Command::class)) { throw new InvalidArgumentException(sprintf('The service "%s" tagged "%s" must be a subclass of "%s".', $id, $this->commandTag, Command::class)); } - $description = str_replace('%', '%%', $class::getDefaultDescription()); + $description = str_replace('%', '%%', $class::getDefaultDescription() ?? ''); } if ($description) { From 77972627c95a1c36eefbc1776dbe98dc4ea1d852 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Thu, 23 Jun 2022 12:21:08 +0200 Subject: [PATCH 5/5] Fix global state pollution between tests run with ApplicationTester --- Tester/ApplicationTester.php | 38 +++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/Tester/ApplicationTester.php b/Tester/ApplicationTester.php index 4f99da18d..ce4e5c18d 100644 --- a/Tester/ApplicationTester.php +++ b/Tester/ApplicationTester.php @@ -54,17 +54,37 @@ public function __construct(Application $application) */ public function run(array $input, $options = []) { - $this->input = new ArrayInput($input); - if (isset($options['interactive'])) { - $this->input->setInteractive($options['interactive']); - } + $prevShellVerbosity = getenv('SHELL_VERBOSITY'); - if ($this->inputs) { - $this->input->setStream(self::createStream($this->inputs)); - } + try { + $this->input = new ArrayInput($input); + if (isset($options['interactive'])) { + $this->input->setInteractive($options['interactive']); + } - $this->initOutput($options); + if ($this->inputs) { + $this->input->setStream(self::createStream($this->inputs)); + } - return $this->statusCode = $this->application->run($this->input, $this->output); + $this->initOutput($options); + + return $this->statusCode = $this->application->run($this->input, $this->output); + } finally { + // SHELL_VERBOSITY is set by Application::configureIO so we need to unset/reset it + // to its previous value to avoid one test's verbosity to spread to the following tests + if (false === $prevShellVerbosity) { + if (\function_exists('putenv')) { + @putenv('SHELL_VERBOSITY'); + } + unset($_ENV['SHELL_VERBOSITY']); + unset($_SERVER['SHELL_VERBOSITY']); + } else { + if (\function_exists('putenv')) { + @putenv('SHELL_VERBOSITY='.$prevShellVerbosity); + } + $_ENV['SHELL_VERBOSITY'] = $prevShellVerbosity; + $_SERVER['SHELL_VERBOSITY'] = $prevShellVerbosity; + } + } } } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy