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 | * This file is part of Railt package. |
||
4 | * |
||
5 | * For the full copyright and license information, please view the LICENSE |
||
6 | * file that was distributed with this source code. |
||
7 | */ |
||
8 | declare(strict_types=1); |
||
9 | |||
10 | namespace Railt\Console; |
||
11 | |||
12 | use Symfony\Component\Console\Input\InputArgument; |
||
13 | use Symfony\Component\Console\Input\InputOption; |
||
14 | |||
15 | /** |
||
16 | * Class SignatureParser |
||
17 | */ |
||
18 | class SignatureParser |
||
19 | { |
||
20 | /** |
||
21 | * @var string |
||
22 | */ |
||
23 | private $name; |
||
24 | |||
25 | /** |
||
26 | * @var array |
||
27 | */ |
||
28 | private $arguments = []; |
||
29 | |||
30 | /** |
||
31 | * @var array |
||
32 | */ |
||
33 | private $options = []; |
||
34 | |||
35 | /** |
||
36 | * SignatureParser constructor. |
||
37 | * @param string $signature |
||
38 | * @throws \InvalidArgumentException |
||
39 | */ |
||
40 | public function __construct(string $signature) |
||
41 | { |
||
42 | [$this->name, $this->arguments, $this->options] = $this->parse($signature); |
||
43 | } |
||
44 | |||
45 | /** |
||
46 | * @return string |
||
47 | */ |
||
48 | public function getName(): string |
||
49 | { |
||
50 | return $this->name; |
||
51 | } |
||
52 | |||
53 | /** |
||
54 | * @return array |
||
55 | */ |
||
56 | public function getArguments(): array |
||
57 | { |
||
58 | return $this->arguments; |
||
59 | } |
||
60 | |||
61 | /** |
||
62 | * @return array |
||
63 | */ |
||
64 | public function getOptions(): array |
||
65 | { |
||
66 | return $this->options; |
||
67 | } |
||
68 | |||
69 | /** |
||
70 | * Parse the given console command definition into an array. |
||
71 | * |
||
72 | * @param string $expression |
||
73 | * @return array |
||
74 | * @throws \InvalidArgumentException |
||
75 | */ |
||
76 | protected function parse($expression): array |
||
77 | { |
||
78 | $name = $this->name($expression); |
||
79 | |||
80 | if (\preg_match_all('/\{\s*(.*?)\s*\}/', $expression, $matches) && \count($matches[1])) { |
||
81 | return \array_merge([$name], $this->parameters($matches[1])); |
||
82 | } |
||
83 | |||
84 | return [$name, [], []]; |
||
85 | } |
||
86 | |||
87 | /** |
||
88 | * Extract the name of the command from the expression. |
||
89 | * |
||
90 | * @param string $expression |
||
91 | * @return string |
||
92 | * @throws \InvalidArgumentException |
||
93 | */ |
||
94 | protected function name($expression): string |
||
95 | { |
||
96 | if (\trim($expression) === '') { |
||
97 | throw new \InvalidArgumentException('Console command definition is empty.'); |
||
98 | } |
||
99 | |||
100 | if (! \preg_match('/[\S]+/', $expression, $matches)) { |
||
101 | throw new \InvalidArgumentException('Unable to determine command name from signature.'); |
||
102 | } |
||
103 | |||
104 | return $matches[0]; |
||
105 | } |
||
106 | |||
107 | /** |
||
108 | * Extract all of the parameters from the tokens. |
||
109 | * |
||
110 | * @param array $tokens |
||
111 | * @return array |
||
112 | * @throws \Symfony\Component\Console\Exception\InvalidArgumentException |
||
113 | */ |
||
114 | protected function parameters(array $tokens): array |
||
115 | { |
||
116 | [$arguments, $options] = [[], []]; |
||
0 ignored issues
–
show
The variable
$options seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?
This error can happen if you refactor code and forget to move the variable initialization. Let’s take a look at a simple example: function someFunction() {
$x = 5;
echo $x;
}
The above code is perfectly fine. Now imagine that we re-order the statements: function someFunction() {
echo $x;
$x = 5;
}
In that case, ![]() |
|||
117 | |||
118 | foreach ($tokens as $token) { |
||
119 | if (\preg_match('/-{2,}(.*)/', $token, $matches)) { |
||
120 | $options[] = $this->parseOption($matches[1]); |
||
0 ignored issues
–
show
Coding Style
Comprehensibility
introduced
by
$options was never initialized. Although not strictly required by PHP, it is generally a good practice to add $options = array(); before regardless.
Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code. Let’s take a look at an example: foreach ($collection as $item) {
$myArray['foo'] = $item->getFoo();
if ($item->hasBar()) {
$myArray['bar'] = $item->getBar();
}
// do something with $myArray
}
As you can see in this example, the array This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop. ![]() |
|||
121 | } else { |
||
122 | $arguments[] = $this->parseArgument($token); |
||
0 ignored issues
–
show
Coding Style
Comprehensibility
introduced
by
$arguments was never initialized. Although not strictly required by PHP, it is generally a good practice to add $arguments = array(); before regardless.
Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code. Let’s take a look at an example: foreach ($collection as $item) {
$myArray['foo'] = $item->getFoo();
if ($item->hasBar()) {
$myArray['bar'] = $item->getBar();
}
// do something with $myArray
}
As you can see in this example, the array This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop. ![]() |
|||
123 | } |
||
124 | } |
||
125 | |||
126 | return [$arguments, $options]; |
||
0 ignored issues
–
show
The variable
$arguments does not seem to be defined for all execution paths leading up to this point.
If you define a variable conditionally, it can happen that it is not defined for all execution paths. Let’s take a look at an example: function myFunction($a) {
switch ($a) {
case 'foo':
$x = 1;
break;
case 'bar':
$x = 2;
break;
}
// $x is potentially undefined here.
echo $x;
}
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined. Available Fixes
![]() The variable
$options does not seem to be defined for all execution paths leading up to this point.
If you define a variable conditionally, it can happen that it is not defined for all execution paths. Let’s take a look at an example: function myFunction($a) {
switch ($a) {
case 'foo':
$x = 1;
break;
case 'bar':
$x = 2;
break;
}
// $x is potentially undefined here.
echo $x;
}
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined. Available Fixes
![]() |
|||
127 | } |
||
128 | |||
129 | /** |
||
130 | * Parse an option expression. |
||
131 | * |
||
132 | * @param string $token |
||
133 | * @return \Symfony\Component\Console\Input\InputOption |
||
134 | * @throws \Symfony\Component\Console\Exception\InvalidArgumentException |
||
135 | */ |
||
136 | protected function parseOption($token): ?InputOption |
||
137 | { |
||
138 | [$token, $description] = $this->extractDescription($token); |
||
0 ignored issues
–
show
The variable
$description does not exist. Did you forget to declare it?
This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug. ![]() |
|||
139 | |||
140 | $matches = \preg_split('/\s*\|\s*/', $token, 2); |
||
141 | |||
142 | if (isset($matches[1])) { |
||
143 | [$shortcut, $token] = [$matches[0], $matches[1]]; |
||
0 ignored issues
–
show
The variable
$shortcut seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?
This error can happen if you refactor code and forget to move the variable initialization. Let’s take a look at a simple example: function someFunction() {
$x = 5;
echo $x;
}
The above code is perfectly fine. Now imagine that we re-order the statements: function someFunction() {
echo $x;
$x = 5;
}
In that case, ![]() |
|||
144 | } else { |
||
145 | $shortcut = null; |
||
146 | } |
||
147 | |||
148 | switch (true) { |
||
0 ignored issues
–
show
|
|||
149 | case $this->endsWith($token, '='): |
||
150 | return new InputOption(\trim($token, '='), $shortcut, InputOption::VALUE_OPTIONAL, $description); |
||
0 ignored issues
–
show
The variable
$shortcut does not seem to be defined for all execution paths leading up to this point.
If you define a variable conditionally, it can happen that it is not defined for all execution paths. Let’s take a look at an example: function myFunction($a) {
switch ($a) {
case 'foo':
$x = 1;
break;
case 'bar':
$x = 2;
break;
}
// $x is potentially undefined here.
echo $x;
}
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined. Available Fixes
![]() |
|||
151 | |||
152 | case $this->endsWith($token, '=*'): |
||
153 | return new InputOption(\trim($token, '=*'), $shortcut, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, $description); |
||
154 | |||
155 | case \preg_match('/(.+)\=\*(.+)/', $token, $matches): |
||
156 | return new InputOption($matches[1], $shortcut, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, $description, \preg_split('/,\s?/', $matches[2])); |
||
157 | |||
158 | case \preg_match('/(.+)\=(.+)/', $token, $matches): |
||
159 | return new InputOption($matches[1], $shortcut, InputOption::VALUE_OPTIONAL, $description, $matches[2]); |
||
160 | |||
161 | default: |
||
162 | return new InputOption($token, $shortcut, InputOption::VALUE_NONE, $description); |
||
163 | } |
||
164 | } |
||
165 | |||
166 | /** |
||
167 | * Parse the token into its token and description segments. |
||
168 | * |
||
169 | * @param string $token |
||
170 | * @return array |
||
171 | */ |
||
172 | protected function extractDescription($token): array |
||
173 | { |
||
174 | $parts = \preg_split('/\s+:\s+/', \trim($token), 2); |
||
175 | |||
176 | return \count($parts) === 2 ? $parts : [$token, '']; |
||
177 | } |
||
178 | |||
179 | /** |
||
180 | * @param string $haystack |
||
181 | * @param string $needle |
||
182 | * @return bool |
||
183 | */ |
||
184 | private function endsWith(string $haystack, string $needle): bool |
||
185 | { |
||
186 | return \substr($haystack, -\strlen($needle)) === $needle; |
||
187 | } |
||
188 | |||
189 | /** |
||
190 | * Parse an argument expression. |
||
191 | * |
||
192 | * @param string $token |
||
193 | * @return \Symfony\Component\Console\Input\InputArgument |
||
194 | * @throws \Symfony\Component\Console\Exception\InvalidArgumentException |
||
195 | */ |
||
196 | protected function parseArgument($token): ?InputArgument |
||
197 | { |
||
198 | [$token, $description] = $this->extractDescription($token); |
||
0 ignored issues
–
show
The variable
$description does not exist. Did you forget to declare it?
This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug. ![]() |
|||
199 | |||
200 | switch (true) { |
||
0 ignored issues
–
show
|
|||
201 | case $this->endsWith($token, '?*'): |
||
202 | return new InputArgument(\trim($token, '?*'), InputArgument::IS_ARRAY, $description); |
||
203 | |||
204 | case $this->endsWith($token, '*'): |
||
205 | return new InputArgument(\trim($token, '*'), InputArgument::IS_ARRAY | InputArgument::REQUIRED, $description); |
||
206 | |||
207 | case $this->endsWith($token, '?'): |
||
208 | return new InputArgument(\trim($token, '?'), InputArgument::OPTIONAL, $description); |
||
209 | |||
210 | case \preg_match('/(.+)\=\*(.+)/', $token, $matches): |
||
211 | return new InputArgument($matches[1], InputArgument::IS_ARRAY, $description, \preg_split('/,\s?/', $matches[2])); |
||
0 ignored issues
–
show
The variable
$matches seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?
This error can happen if you refactor code and forget to move the variable initialization. Let’s take a look at a simple example: function someFunction() {
$x = 5;
echo $x;
}
The above code is perfectly fine. Now imagine that we re-order the statements: function someFunction() {
echo $x;
$x = 5;
}
In that case, ![]() |
|||
212 | |||
213 | case \preg_match('/(.+)\=(.+)/', $token, $matches): |
||
214 | return new InputArgument($matches[1], InputArgument::OPTIONAL, $description, $matches[2]); |
||
0 ignored issues
–
show
The variable
$matches seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?
This error can happen if you refactor code and forget to move the variable initialization. Let’s take a look at a simple example: function someFunction() {
$x = 5;
echo $x;
}
The above code is perfectly fine. Now imagine that we re-order the statements: function someFunction() {
echo $x;
$x = 5;
}
In that case, ![]() |
|||
215 | |||
216 | default: |
||
217 | return new InputArgument($token, InputArgument::REQUIRED, $description); |
||
218 | } |
||
219 | } |
||
220 | } |
||
221 |
This error can happen if you refactor code and forget to move the variable initialization.
Let’s take a look at a simple example:
The above code is perfectly fine. Now imagine that we re-order the statements:
In that case,
$x
would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.