8000 [Console] do not leak hidden commands · symfony/symfony@2bb40fe · GitHub
[go: up one dir, main page]

Skip to content

Commit 2bb40fe

Browse files
committed
[Console] do not leak hidden commands
Hidden commands... - should only be accepted if their names match exactly. - should not appear in suggestion lists. - should not interfere with abbreviating other commands (that would otherwise not be distinct).
1 parent 75bad2e commit 2bb40fe

File tree

1 file changed

+44
-0
lines changed

1 file changed

+44
-0
lines changed

src/Symfony/Component/Console/Application.php

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,10 @@ public function getNamespaces()
529529
{
530530
$namespaces = [];
531531
foreach ($this->all() as $command) {
532+
if ($command->isHidden()) {
533+
continue;
534+
}
535+
532536
$namespaces = array_merge($namespaces, $this->extractAllNamespaces($command->getName()));
533537

534538
foreach ($command->getAliases() as $alias) {
@@ -612,6 +616,12 @@ public function find($name)
612616
$commands = preg_grep('{^'.$expr.'}i', $allCommands);
613617
}
614618

619+
// hidden commands can only be matched exactly and shall not appear otherwise
620+
$hiddenCommands = $this->removeHiddenCommands($commands);
621+
if (isset($hiddenCommands[$name])) {
622+
return $hiddenCommands[$name];
623+
}
624+
615625
// if no commands matched or we just matched namespaces
616626
if (empty($commands) || \count(preg_grep('{^'.$expr.'$}i', $commands)) < 1) {
617627
if (false !== $pos = strrpos($name, ':')) {
@@ -622,6 +632,8 @@ public function find($name)
622632
$message = sprintf('Command "%s" is not defined.', $name);
623633

624634
if ($alternatives = $this->findAlternatives($name, $allCommands)) {
635+
$this->removeHiddenCommands($alternatives);
636+
625637
if (1 == \count($alternatives)) {
626638
$message .= "\n\nDid you mean this?\n ";
627639
} else {
@@ -1155,6 +1167,38 @@ private function findAlternatives($name, $collection)
11551167
return array_keys($alternatives);
11561168
}
11571169

1170+
/**
1171+
* Removes hidden commands commands from a given array of command names and
1172+
* returns them as Command instances.
1173+
*
1174+
* @param string[] $commandNames The command names to filter
1175+
*
1176+
* @return Command[] An associative array of removed commands with
1177+
* command names and command aliases being the keys
1178+
*
1179+
* @internal
1180+
*/
1181+
private function removeHiddenCommands(array &$commandNames)
1182+
{
1183+
$hiddenCommands = [];
1184+
foreach ($commandNames as $key => $commandName) {
1185+
$command = $this->has($commandName) ? $this->commands[$commandName] : $this->commandLoader->get($commandName);
1186+
1187+
if (!$command->isHidden()) {
1188+
continue;
1189+
}
1190+
1191+
$hiddenCommands[$commandName] = $command;
1192+
foreach ($command->getAliases() as $alias) {
1193+
$hiddenCommands[$alias] = $command;
1194+
}
1195+
1196+
unset($commandNames[$key]);
1197+
}
1198+
1199+
return $hiddenCommands;
1200+
}
1201+
11581202
/**
11591203
* Sets the default Command name.
11601204
*

0 commit comments

Comments
 (0)
0