This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | /** |
||
4 | * This file is part of the Cubiche component. |
||
5 | * |
||
6 | * Copyright (c) Cubiche |
||
7 | * |
||
8 | * For the full copyright and license information, please view the LICENSE |
||
9 | * file that was distributed with this source code. |
||
10 | */ |
||
11 | |||
12 | namespace Cubiche\Core\Console\Tests\Units; |
||
13 | |||
14 | use Cubiche\Core\EventBus\Event\EventBus; |
||
15 | use Cubiche\Core\Console\Api\Config\ApplicationConfig; |
||
16 | use Cubiche\Core\Console\ConsoleApplication; |
||
17 | use Cubiche\Core\Console\Tests\Fixtures\Command\BlogService; |
||
18 | use Cubiche\Core\Console\Tests\Fixtures\Command\ChangePostTitleCommand; |
||
19 | use Cubiche\Core\Console\Tests\Fixtures\Command\CreateBlogCommand; |
||
20 | use Cubiche\Core\Console\Tests\Fixtures\Command\CreatePostCommand; |
||
21 | use Cubiche\Core\Console\Tests\Fixtures\Command\PostService; |
||
22 | use Cubiche\Core\Cqrs\Command\CommandBus; |
||
23 | use Cubiche\Core\EventDispatcher\EventInterface; |
||
24 | use Webmozart\Console\Api\Args\Format\Argument; |
||
25 | use Webmozart\Console\Api\IO\Input; |
||
26 | use Webmozart\Console\Api\IO\IO; |
||
27 | use Webmozart\Console\Api\IO\Output; |
||
28 | use Webmozart\Console\Args\ArgvArgs; |
||
29 | use Webmozart\Console\Handler\Help\HelpHandler; |
||
30 | use Webmozart\Console\IO\InputStream\StringInputStream; |
||
31 | use Webmozart\Console\IO\OutputStream\BufferedOutputStream; |
||
32 | |||
33 | /** |
||
34 | * ConsoleApplicationTests class. |
||
35 | * |
||
36 | * $commandBus = CommandBus::create(); |
||
37 | * |
||
38 | * $postService = new PostService(); |
||
39 | * $commandBus->addHandler(CreateBlogCommand::class, new BlogService()); |
||
40 | * $commandBus->addHandler(CreatePostCommand::class, $postService); |
||
41 | * $commandBus->addHandler(ChangePostTitleCommand::class, $postService); |
||
42 | * |
||
43 | * class SampleApplicationConfig extends DefaultApplicationConfig |
||
44 | * { |
||
45 | * protected function configure() |
||
46 | * { |
||
47 | * parent::configure(); |
||
48 | * |
||
49 | * $this |
||
50 | * ->setName('test') |
||
51 | * ->setVersion('1.0.0') |
||
52 | * ->beginCommand('blog') |
||
53 | * ->setClass(CreateBlogCommand::class) |
||
54 | * ->setDescription('Create a new blog') |
||
55 | * ->addArgument('name', Argument::REQUIRED | Argument::STRING, 'The blog name') |
||
56 | * ->end() |
||
57 | * ->beginCommand('post') |
||
58 | * ->setDescription('Manage posts') |
||
59 | * ->beginSubCommand('create') |
||
60 | * ->setClass(CreatePostCommand::class) |
||
61 | * ->setDescription('Create a new post') |
||
62 | * ->addArgument('title', Argument::REQUIRED | Argument::STRING, 'The post title') |
||
63 | * ->addArgument('content', Argument::OPTIONAL, 'The post content') |
||
64 | * ->onPreDispatchEvent(function(EventInterface $event, IO $io) { |
||
65 | * $io->writeLine($event->eventName()); |
||
66 | * }) |
||
67 | * ->end() |
||
68 | * ->beginSubCommand('change') |
||
69 | * ->setClass(ChangePostTitleCommand::class) |
||
70 | * ->setDescription('Change the post title') |
||
71 | * ->addArgument('title', Argument::REQUIRED | Argument::STRING, 'The new post title') |
||
72 | * ->onPostDispatchEvent(function(EventInterface $event, IO $io) { |
||
73 | * $io->writeLine($event->eventName()); |
||
74 | * }) |
||
75 | * ->end() |
||
76 | * ->end() |
||
77 | * ; |
||
78 | * } |
||
79 | * } |
||
80 | * |
||
81 | * $cli = new ConsoleApplication(new SampleApplicationConfig(), $commandBus); |
||
82 | * $cli->run(); |
||
83 | */ |
||
84 | class ConsoleApplicationTests extends TestCase |
||
85 | { |
||
86 | /** |
||
87 | * @return ApplicationConfig |
||
88 | */ |
||
89 | protected function createConfiguration() |
||
90 | { |
||
91 | $config = new ApplicationConfig(); |
||
92 | $config->setCatchExceptions(false); |
||
93 | $config->setTerminateAfterRun(false); |
||
94 | $config->setIOFactory(function ($application, $args, $inputStream, $outputStream, $errorStream) { |
||
95 | return new IO(new Input($inputStream), new Output($outputStream), new Output($errorStream)); |
||
96 | }); |
||
97 | |||
98 | return $config; |
||
99 | } |
||
100 | |||
101 | /** |
||
102 | * @param callable|ApplicationConfig $config |
||
103 | * |
||
104 | * @return ConsoleApplication |
||
105 | */ |
||
106 | protected function createApplication($config) |
||
107 | { |
||
108 | $commandBus = CommandBus::create(); |
||
109 | $eventBus = EventBus::create(); |
||
110 | |||
111 | $postService = new PostService($eventBus); |
||
112 | |||
113 | $commandBus->addHandler(CreateBlogCommand::class, new BlogService($eventBus)); |
||
114 | $commandBus->addHandler(CreatePostCommand::class, $postService); |
||
115 | $commandBus->addHandler(ChangePostTitleCommand::class, $postService); |
||
116 | |||
117 | return new ConsoleApplication($config, $commandBus, $eventBus); |
||
118 | } |
||
119 | |||
120 | /** |
||
121 | * Test run help. |
||
122 | */ |
||
123 | public function testRunHelpCommand() |
||
124 | { |
||
125 | $configCallback = function (ApplicationConfig $config) { |
||
126 | $config |
||
0 ignored issues
–
show
|
|||
127 | ->beginCommand('help') |
||
128 | ->markDefault() |
||
129 | ->setHandler(function () { |
||
130 | return new HelpHandler(); |
||
131 | }) |
||
132 | ->end() |
||
133 | ; |
||
134 | }; |
||
135 | |||
136 | $this |
||
137 | ->given($config = $this->createConfiguration()) |
||
138 | ->and($configCallback($config)) |
||
139 | ->and($application = $this->createApplication($config)) |
||
140 | ->and($args = new ArgvArgs(array('test', 'help'))) |
||
141 | ->and($input = new StringInputStream('')) |
||
142 | ->and($output = new BufferedOutputStream()) |
||
143 | ->and($errorOutput = new BufferedOutputStream()) |
||
144 | ->when($application->run($args, $input, $output, $errorOutput)) |
||
145 | ->then() |
||
146 | ->string($output->fetch()) |
||
147 | ->constant('<c1>help</c1>') |
||
148 | ; |
||
149 | |||
150 | $this |
||
151 | ->given($config = $this->createConfiguration()) |
||
152 | ->and($configCallback($config)) |
||
153 | ->and($application = $this->createApplication(function () use ($config) { |
||
154 | return $config; |
||
155 | })) |
||
156 | ->and($args = new ArgvArgs(array('test', 'help'))) |
||
157 | ->and($input = new StringInputStream('')) |
||
158 | ->and($output = new BufferedOutputStream()) |
||
159 | ->and($errorOutput = new BufferedOutputStream()) |
||
160 | ->when($application->run($args, $input, $output, $errorOutput)) |
||
161 | ->then() |
||
162 | ->string($output->fetch()) |
||
163 | ->constant('<c1>help</c1>') |
||
164 | ; |
||
165 | } |
||
166 | |||
167 | /** |
||
168 | * Test run help subcommand. |
||
169 | */ |
||
170 | public function testRunHelpSubCommand() |
||
171 | { |
||
172 | $configCallback = function (ApplicationConfig $config) { |
||
173 | $config |
||
0 ignored issues
–
show
It seems like you code against a specific sub-type and not the parent class
Webmozart\Console\Api\Config\SubCommandConfig as the method setClass() does only exist in the following sub-classes of Webmozart\Console\Api\Config\SubCommandConfig : Cubiche\Core\Console\Api\Config\SubCommandConfig . Maybe you want to instanceof check for one of these explicitly?
Let’s take a look at an example: abstract class User
{
/** @return string */
abstract public function getPassword();
}
class MyUser extends User
{
public function getPassword()
{
// return something
}
public function getDisplayName()
{
// return some name.
}
}
class AuthSystem
{
public function authenticate(User $user)
{
$this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
// do something.
}
}
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break. Available Fixes
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types
inside the if block in such a case.
![]() |
|||
174 | ->beginCommand('post') |
||
175 | ->setDescription('Manage posts') |
||
176 | ->beginSubCommand('create') |
||
177 | ->setClass(CreatePostCommand::class) |
||
178 | ->setDescription('Create a new post') |
||
179 | ->end() |
||
180 | ->beginSubCommand('change') |
||
181 | ->setClass(ChangePostTitleCommand::class) |
||
182 | ->setDescription('Change the post title') |
||
183 | ->end() |
||
184 | ->end() |
||
185 | ->beginCommand('help') |
||
186 | ->markDefault() |
||
187 | ->addArgument('command', Argument::OPTIONAL, 'The command name') |
||
188 | ->setHandler(function () { |
||
189 | return new HelpHandler(); |
||
190 | }) |
||
191 | ->end() |
||
192 | ; |
||
193 | }; |
||
194 | |||
195 | $this |
||
196 | ->given($config = $this->createConfiguration()) |
||
197 | ->and($configCallback($config)) |
||
198 | ->and($application = $this->createApplication($config)) |
||
199 | ->and($args = new ArgvArgs(array('test', 'post'))) |
||
200 | ->and($input = new StringInputStream('')) |
||
201 | ->and($output = new BufferedOutputStream()) |
||
202 | ->and($errorOutput = new BufferedOutputStream()) |
||
203 | ->when($application->run($args, $input, $output, $errorOutput)) |
||
204 | ->then() |
||
205 | ->string($output->fetch()) |
||
206 | ->constant('<c1>help</c1>') |
||
207 | ; |
||
208 | } |
||
209 | |||
210 | /** |
||
211 | * Test run command without class. |
||
212 | */ |
||
213 | View Code Duplication | public function testRunCommandWithoutClass() |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
214 | { |
||
215 | $configCallback = function (ApplicationConfig $config) { |
||
216 | $config |
||
0 ignored issues
–
show
The call to the method
Cubiche\Core\Console\Api...ig\CommandConfig::end() seems un-needed as the method has no side-effects.
PHP Analyzer performs a side-effects analysis of your code. A side-effect is basically anything that might be visible after the scope of the method is left. Let’s take a look at an example: class User
{
private $email;
public function getEmail()
{
return $this->email;
}
public function setEmail($email)
{
$this->email = $email;
}
}
If we look at the $user = new User();
$user->getEmail(); // This line could safely be removed as it has no effect.
On the hand, if we look at the $user = new User();
$user->setEmail('email@domain'); // This line has a side-effect (it changes an
// instance variable).
![]() |
|||
217 | ->beginCommand('create-blog') |
||
218 | ->setDescription('Create a new blog') |
||
219 | // should set ->setClass() |
||
220 | ->end() |
||
221 | ; |
||
222 | }; |
||
223 | |||
224 | $this |
||
225 | ->given($config = $this->createConfiguration()) |
||
226 | ->and($configCallback($config)) |
||
227 | ->and($application = $this->createApplication($config)) |
||
228 | ->and($args = new ArgvArgs(array('test', 'create-blog'))) |
||
229 | ->and($input = new StringInputStream('')) |
||
230 | ->and($output = new BufferedOutputStream()) |
||
231 | ->and($errorOutput = new BufferedOutputStream()) |
||
232 | ->then() |
||
233 | ->exception(function () use ($application, $args, $input, $output, $errorOutput) { |
||
234 | $application->run($args, $input, $output, $errorOutput); |
||
235 | }) |
||
236 | ->isInstanceOf(\RuntimeException::class) |
||
237 | ; |
||
238 | } |
||
239 | |||
240 | /** |
||
241 | * Test run command without arguments. |
||
242 | */ |
||
243 | View Code Duplication | public function testRunCommandWithoutArguments() |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
244 | { |
||
245 | $configCallback = function (ApplicationConfig $config) { |
||
246 | $config |
||
0 ignored issues
–
show
The call to the method
Cubiche\Core\Console\Api...ig\CommandConfig::end() seems un-needed as the method has no side-effects.
PHP Analyzer performs a side-effects analysis of your code. A side-effect is basically anything that might be visible after the scope of the method is left. Let’s take a look at an example: class User
{
private $email;
public function getEmail()
{
return $this->email;
}
public function setEmail($email)
{
$this->email = $email;
}
}
If we look at the $user = new User();
$user->getEmail(); // This line could safely be removed as it has no effect.
On the hand, if we look at the $user = new User();
$user->setEmail('email@domain'); // This line has a side-effect (it changes an
// instance variable).
![]() |
|||
247 | ->beginCommand('create-blog') |
||
248 | ->setDescription('Create a new blog') |
||
249 | ->setClass(CreateBlogCommand::class) |
||
250 | // should have ->addArgument('name', Argument::REQUIRED | Argument::STRING, 'The blog name') |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
42% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them. ![]() |
|||
251 | ->end() |
||
252 | ; |
||
253 | }; |
||
254 | |||
255 | $this |
||
256 | ->given($config = $this->createConfiguration()) |
||
257 | ->and($configCallback($config)) |
||
258 | ->and($application = $this->createApplication($config)) |
||
259 | ->and($args = new ArgvArgs(array('test', 'create-blog'))) |
||
260 | ->and($input = new StringInputStream('')) |
||
261 | ->and($output = new BufferedOutputStream()) |
||
262 | ->and($errorOutput = new BufferedOutputStream()) |
||
263 | ->then() |
||
264 | ->exception(function () use ($application, $args, $input, $output, $errorOutput) { |
||
265 | $application->run($args, $input, $output, $errorOutput); |
||
266 | }) |
||
267 | ->isInstanceOf(\InvalidArgumentException::class) |
||
268 | ; |
||
269 | } |
||
270 | |||
271 | /** |
||
272 | * Test run command with default handlers. |
||
273 | */ |
||
274 | public function testRunCommandWithDefaultHanlder() |
||
275 | { |
||
276 | $configCallback = function (ApplicationConfig $config) { |
||
277 | $config |
||
0 ignored issues
–
show
The method
end does only exist in Webmozart\Console\Api\Config\CommandConfig , but not in Webmozart\Console\Api\Config\ApplicationConfig .
It seems like the method you are trying to call exists only in some of the possible types. Let’s take a look at an example: class A
{
public function foo() { }
}
class B extends A
{
public function bar() { }
}
/**
* @param A|B $x
*/
function someFunction($x)
{
$x->foo(); // This call is fine as the method exists in A and B.
$x->bar(); // This method only exists in B and might cause an error.
}
Available Fixes
![]() |
|||
278 | ->beginCommand('create-blog') |
||
279 | ->setDescription('Create a new blog') |
||
280 | ->setClass(CreateBlogCommand::class) |
||
281 | ->addArgument('name', Argument::REQUIRED | Argument::STRING, 'The blog name') |
||
282 | ->end() |
||
283 | ; |
||
284 | }; |
||
285 | |||
286 | $this |
||
287 | ->given($config = $this->createConfiguration()) |
||
288 | ->and($configCallback($config)) |
||
289 | ->and($application = $this->createApplication($config)) |
||
290 | ->and($args = new ArgvArgs(array('test', 'create-blog', 'foo'))) |
||
291 | ->and($input = new StringInputStream('')) |
||
292 | ->and($output = new BufferedOutputStream()) |
||
293 | ->and($errorOutput = new BufferedOutputStream()) |
||
294 | ->when($application->run($args, $input, $output, $errorOutput)) |
||
295 | ->then() |
||
296 | ->string($output->fetch()) |
||
297 | ->contains('blog was created') |
||
298 | ->contains('<c1>blog was created</c1> success') |
||
299 | ->contains('name') |
||
300 | ; |
||
301 | } |
||
302 | |||
303 | /** |
||
304 | * Test run command with custom predispatch handler. |
||
305 | */ |
||
306 | public function testRunCommandWithCustomPreDispatchHanlder() |
||
307 | { |
||
308 | $configCallback = function (ApplicationConfig $config) { |
||
309 | $config |
||
310 | ->beginCommand('post') |
||
311 | ->setDescription('Manage posts') |
||
312 | ->beginSubCommand('create') |
||
313 | ->setClass(CreatePostCommand::class) |
||
314 | ->setDescription('Create a new post') |
||
315 | ->addArgument('title', Argument::REQUIRED | Argument::STRING, 'The post title') |
||
316 | ->addArgument('content', Argument::OPTIONAL, 'The post content') |
||
317 | ->onPreDispatchEvent(function (EventInterface $event, IO $io) { |
||
318 | $io->writeLine('on pre dispatch'); |
||
319 | }) |
||
320 | ->end() |
||
321 | ->beginSubCommand('change') |
||
322 | ->setClass(ChangePostTitleCommand::class) |
||
323 | ->setDescription('Change the post title') |
||
324 | ->addArgument('title', Argument::REQUIRED | Argument::STRING, 'The new post title') |
||
325 | ->onPostDispatchEvent(function (EventInterface $event, IO $io) { |
||
326 | $io->writeLine('on post dispatch'); |
||
327 | }) |
||
328 | ->end() |
||
329 | ->end() |
||
330 | ; |
||
331 | }; |
||
332 | |||
333 | $this |
||
334 | ->given($config = $this->createConfiguration()) |
||
335 | ->and($configCallback($config)) |
||
336 | ->and($application = $this->createApplication($config)) |
||
337 | ->and($args = new ArgvArgs(array('test', 'post', 'create', 'foo', 'bar'))) |
||
338 | ->and($input = new StringInputStream('')) |
||
339 | ->and($output = new BufferedOutputStream()) |
||
340 | ->and($errorOutput = new BufferedOutputStream()) |
||
341 | ->when($application->run($args, $input, $output, $errorOutput)) |
||
342 | ->then() |
||
343 | ->string($output->fetch()) |
||
344 | ->contains('on pre dispatch') |
||
345 | ->contains('<c1>post was created</c1> success') |
||
346 | ; |
||
347 | |||
348 | $this |
||
349 | ->given($config = $this->createConfiguration()) |
||
350 | ->and($configCallback($config)) |
||
351 | ->and($application = $this->createApplication($config)) |
||
352 | ->and($args = new ArgvArgs(array('test', 'post', 'change', 'baz'))) |
||
353 | ->and($input = new StringInputStream('')) |
||
354 | ->and($output = new BufferedOutputStream()) |
||
355 | ->and($errorOutput = new BufferedOutputStream()) |
||
356 | ->when($application->run($args, $input, $output, $errorOutput)) |
||
357 | ->then() |
||
358 | ->string($output->fetch()) |
||
359 | ->contains('post title was changed') |
||
360 | ->contains('on post dispatch') |
||
361 | ->contains('title') |
||
362 | ; |
||
363 | } |
||
364 | } |
||
365 |
It seems like the method you are trying to call exists only in some of the possible types.
Let’s take a look at an example:
Available Fixes
Add an additional type-check:
Only allow a single type to be passed if the variable comes from a parameter: