From baab4edf355625b0286fb88b398faa08b0fd1912 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Fri, 3 Oct 2014 17:11:40 +0200 Subject: [PATCH] clean handling of :: passed to find() Commands cannot have a double colon in their name (for example, a command can't be named `foo::bar`). However, one might try to retrieve a `foo::bar` command from the application like this: ```php $command = $application->find('foo::bar'); ``` The `findAlternatives()` method of the `Application` class fails to handle these strings when there are commands registered with a name consisting of at least three parts (e.g. a command is named `foo:bar:baz`). In this case, an empty string is passed to `strpos()` causing PHP to raise a warning. --- src/Symfony/Component/Console/Application.php | 2 +- .../Component/Console/Tests/ApplicationTest.php | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Console/Application.php b/src/Symfony/Component/Console/Application.php index c4154fc934..58230ca180 100644 --- a/src/Symfony/Component/Console/Application.php +++ b/src/Symfony/Component/Console/Application.php @@ -1076,7 +1076,7 @@ class Application } $lev = levenshtein($subname, $parts[$i]); - if ($lev <= strlen($subname) / 3 || false !== strpos($parts[$i], $subname)) { + if ($lev <= strlen($subname) / 3 || '' !== $subname && false !== strpos($parts[$i], $subname)) { $alternatives[$collectionName] = $exists ? $alternatives[$collectionName] + $lev : $lev; } elseif ($exists) { $alternatives[$collectionName] += $threshold; diff --git a/src/Symfony/Component/Console/Tests/ApplicationTest.php b/src/Symfony/Component/Console/Tests/ApplicationTest.php index 42b9d36e5c..eed6c81323 100644 --- a/src/Symfony/Component/Console/Tests/ApplicationTest.php +++ b/src/Symfony/Component/Console/Tests/ApplicationTest.php @@ -445,6 +445,18 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase $this->assertEquals('foo:sublong', $application->findNamespace('f:sub')); } + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage Command "foo::bar" is not defined. + */ + public function testFindWithDoubleColonInNameThrowsException() + { + $application = new Application(); + $application->add(new \FooCommand()); + $application->add(new \Foo4Command()); + $application->find('foo::bar'); + } + public function testSetCatchExceptions() { $application = $this->getMock('Symfony\Component\Console\Application', array('getTerminalWidth'));