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 | namespace Robo\Common; |
||
4 | |||
5 | use Robo\ResultData; |
||
6 | use Symfony\Component\Process\Process; |
||
7 | |||
8 | /** |
||
9 | * Class ExecTrait |
||
10 | * @package Robo\Common |
||
11 | */ |
||
12 | trait ExecTrait |
||
13 | { |
||
14 | /** |
||
15 | * @var bool |
||
16 | */ |
||
17 | protected $background = false; |
||
18 | |||
19 | /** |
||
20 | * @var null|int |
||
21 | */ |
||
22 | protected $timeout = null; |
||
23 | |||
24 | /** |
||
25 | * @var null|int |
||
26 | */ |
||
27 | protected $idleTimeout = null; |
||
28 | |||
29 | /** |
||
30 | * @var null|array |
||
31 | */ |
||
32 | protected $env = null; |
||
33 | |||
34 | /** |
||
35 | * @var Process |
||
36 | */ |
||
37 | protected $process; |
||
38 | |||
39 | /** |
||
40 | * @var resource|string |
||
41 | */ |
||
42 | protected $input; |
||
43 | |||
44 | /** |
||
45 | * @var boolean |
||
46 | */ |
||
47 | protected $interactive = null; |
||
48 | |||
49 | /** |
||
50 | * @var bool |
||
51 | */ |
||
52 | protected $isPrinted = true; |
||
53 | |||
54 | /** |
||
55 | * @var bool |
||
56 | */ |
||
57 | protected $isMetadataPrinted = true; |
||
58 | |||
59 | /** |
||
60 | * @var string |
||
61 | */ |
||
62 | protected $workingDirectory; |
||
63 | |||
64 | /** |
||
65 | * @return string |
||
66 | */ |
||
67 | abstract public function getCommandDescription(); |
||
68 | |||
69 | /** |
||
70 | * @see \Robo\Common\ProgressIndicatorAwareTrait |
||
71 | * @see \Robo\Common\Timer |
||
72 | */ |
||
73 | abstract protected function startTimer(); |
||
74 | |||
75 | /** |
||
76 | * @see \Robo\Common\ProgressIndicatorAwareTrait |
||
77 | * @see \Robo\Common\Timer |
||
78 | */ |
||
79 | abstract protected function stopTimer(); |
||
80 | |||
81 | /** |
||
82 | * @return null|float |
||
83 | * |
||
84 | * @see \Robo\Common\ProgressIndicatorAwareTrait |
||
85 | * @see \Robo\Common\Timer |
||
86 | */ |
||
87 | abstract protected function getExecutionTime(); |
||
88 | |||
89 | /** |
||
90 | * @return bool |
||
91 | * |
||
92 | * @see \Robo\Common\TaskIO |
||
93 | */ |
||
94 | abstract protected function hideTaskProgress(); |
||
95 | |||
96 | /** |
||
97 | * @param bool $inProgress |
||
98 | * |
||
99 | * @see \Robo\Common\TaskIO |
||
100 | */ |
||
101 | abstract protected function showTaskProgress($inProgress); |
||
102 | |||
103 | /** |
||
104 | * @param string $text |
||
105 | * @param null|array $context |
||
106 | * |
||
107 | * @see \Robo\Common\TaskIO |
||
108 | */ |
||
109 | abstract protected function printTaskInfo($text, $context = null); |
||
110 | |||
111 | /** |
||
112 | * @return bool |
||
113 | * |
||
114 | * @see \Robo\Common\VerbosityThresholdTrait |
||
115 | */ |
||
116 | abstract public function verbosityMeetsThreshold(); |
||
117 | |||
118 | /** |
||
119 | * @param string $message |
||
120 | * |
||
121 | * @see \Robo\Common\VerbosityThresholdTrait |
||
122 | */ |
||
123 | abstract public function writeMessage($message); |
||
124 | |||
125 | /** |
||
126 | * Sets $this->interactive() based on posix_isatty(). |
||
127 | * |
||
128 | * @return $this |
||
129 | */ |
||
130 | public function detectInteractive() |
||
131 | { |
||
132 | // If the caller did not explicity set the 'interactive' mode, |
||
133 | // and output should be produced by this task (verbosityMeetsThreshold), |
||
134 | // then we will automatically set interactive mode based on whether |
||
135 | // or not output was redirected when robo was executed. |
||
136 | if (!isset($this->interactive) && function_exists('posix_isatty') && $this->verbosityMeetsThreshold()) { |
||
137 | $this->interactive = posix_isatty(STDOUT); |
||
138 | } |
||
139 | |||
140 | return $this; |
||
141 | } |
||
142 | |||
143 | /** |
||
144 | * Executes command in background mode (asynchronously) |
||
145 | * |
||
146 | * @param bool $arg |
||
147 | * |
||
148 | * @return $this |
||
149 | */ |
||
150 | public function background($arg = true) |
||
151 | { |
||
152 | $this->background = $arg; |
||
153 | return $this; |
||
154 | } |
||
155 | |||
156 | /** |
||
157 | * Stop command if it runs longer then $timeout in seconds |
||
158 | * |
||
159 | * @param int $timeout |
||
160 | * |
||
161 | * @return $this |
||
162 | */ |
||
163 | public function timeout($timeout) |
||
164 | { |
||
165 | $this->timeout = $timeout; |
||
166 | return $this; |
||
167 | } |
||
168 | |||
169 | /** |
||
170 | * Stops command if it does not output something for a while |
||
171 | * |
||
172 | * @param int $timeout |
||
173 | * |
||
174 | * @return $this |
||
175 | */ |
||
176 | public function idleTimeout($timeout) |
||
177 | { |
||
178 | $this->idleTimeout = $timeout; |
||
179 | return $this; |
||
180 | } |
||
181 | |||
182 | /** |
||
183 | * Set a single environment variable, or multiple. |
||
184 | * |
||
185 | * @param string|array $env |
||
186 | * @param bool|string $value |
||
187 | * |
||
188 | * @return $this |
||
189 | */ |
||
190 | public function env($env, $value = null) |
||
191 | { |
||
192 | if (!is_array($env)) { |
||
193 | $env = [$env => ($value ? $value : true)]; |
||
194 | } |
||
195 | return $this->envVars($env); |
||
196 | } |
||
197 | |||
198 | /** |
||
199 | * Sets the environment variables for the command |
||
200 | * |
||
201 | * @param array $env |
||
202 | * |
||
203 | * @return $this |
||
204 | */ |
||
205 | public function envVars(array $env) |
||
206 | { |
||
207 | $this->env = $this->env ? $env + $this->env : $env; |
||
208 | return $this; |
||
209 | } |
||
210 | |||
211 | /** |
||
212 | * Pass an input to the process. Can be resource created with fopen() or string |
||
213 | * |
||
214 | * @param resource|string $input |
||
215 | * |
||
216 | * @return $this |
||
217 | */ |
||
218 | public function setInput($input) |
||
219 | { |
||
220 | $this->input = $input; |
||
221 | return $this; |
||
222 | } |
||
223 | |||
224 | /** |
||
225 | * Attach tty to process for interactive input |
||
226 | * |
||
227 | * @param bool $interactive |
||
228 | * |
||
229 | * @return $this |
||
230 | */ |
||
231 | public function interactive($interactive = true) |
||
232 | { |
||
233 | $this->interactive = $interactive; |
||
234 | return $this; |
||
235 | } |
||
236 | |||
237 | |||
238 | /** |
||
239 | * Is command printing its output to screen |
||
240 | * |
||
241 | * @return bool |
||
242 | */ |
||
243 | public function getPrinted() |
||
244 | { |
||
245 | return $this->isPrinted; |
||
246 | } |
||
247 | |||
248 | /** |
||
249 | * Changes working directory of command |
||
250 | * |
||
251 | * @param string $dir |
||
252 | * |
||
253 | * @return $this |
||
254 | */ |
||
255 | public function dir($dir) |
||
256 | { |
||
257 | $this->workingDirectory = $dir; |
||
258 | return $this; |
||
259 | } |
||
260 | |||
261 | /** |
||
262 | * Shortcut for setting isPrinted() and isMetadataPrinted() to false. |
||
263 | * |
||
264 | * @param bool $arg |
||
265 | * |
||
266 | * @return $this |
||
267 | */ |
||
268 | public function silent($arg) |
||
269 | { |
||
270 | if (is_bool($arg)) { |
||
271 | $this->isPrinted = !$arg; |
||
272 | $this->isMetadataPrinted = !$arg; |
||
273 | } |
||
274 | return $this; |
||
275 | } |
||
276 | |||
277 | /** |
||
278 | * Should command output be printed |
||
279 | * |
||
280 | * @param bool $arg |
||
281 | * |
||
282 | * @return $this |
||
283 | * |
||
284 | * @deprecated |
||
285 | */ |
||
286 | public function printed($arg) |
||
287 | { |
||
288 | $this->logger->warning("printed() is deprecated. Please use printOutput()."); |
||
0 ignored issues
–
show
|
|||
289 | return $this->printOutput($arg); |
||
290 | } |
||
291 | |||
292 | /** |
||
293 | * Should command output be printed |
||
294 | * |
||
295 | * @param bool $arg |
||
296 | * |
||
297 | * @return $this |
||
298 | */ |
||
299 | public function printOutput($arg) |
||
300 | { |
||
301 | if (is_bool($arg)) { |
||
302 | $this->isPrinted = $arg; |
||
303 | } |
||
304 | return $this; |
||
305 | } |
||
306 | |||
307 | /** |
||
308 | * Should command metadata be printed. I,e., command and timer. |
||
309 | * |
||
310 | * @param bool $arg |
||
311 | * |
||
312 | * @return $this |
||
313 | */ |
||
314 | public function printMetadata($arg) |
||
315 | { |
||
316 | if (is_bool($arg)) { |
||
317 | $this->isMetadataPrinted = $arg; |
||
318 | } |
||
319 | return $this; |
||
320 | } |
||
321 | |||
322 | /** |
||
323 | * @param \Symfony\Component\Process\Process $process |
||
324 | * @param callable $output_callback |
||
325 | * |
||
326 | * @return \Robo\ResultData |
||
327 | */ |
||
328 | protected function execute($process, $output_callback = null) |
||
329 | { |
||
330 | $this->process = $process; |
||
331 | |||
332 | if (!$output_callback) { |
||
333 | $output_callback = function ($type, $buffer) { |
||
334 | $progressWasVisible = $this->hideTaskProgress(); |
||
335 | $this->writeMessage($buffer); |
||
336 | $this->showTaskProgress($progressWasVisible); |
||
337 | }; |
||
338 | } |
||
339 | |||
340 | $this->detectInteractive(); |
||
341 | |||
342 | if ($this->isMetadataPrinted) { |
||
343 | $this->printAction(); |
||
344 | } |
||
345 | $this->process->setTimeout($this->timeout); |
||
346 | $this->process->setIdleTimeout($this->idleTimeout); |
||
347 | if ($this->workingDirectory) { |
||
348 | $this->process->setWorkingDirectory($this->workingDirectory); |
||
349 | } |
||
350 | if ($this->input) { |
||
351 | $this->process->setInput($this->input); |
||
352 | } |
||
353 | |||
354 | if ($this->interactive && $this->isPrinted) { |
||
355 | $this->process->setTty(true); |
||
356 | } |
||
357 | |||
358 | if (isset($this->env)) { |
||
359 | // Symfony 4 will inherit environment variables by default, but until |
||
360 | // then, manually ensure they are inherited. |
||
361 | if (method_exists($this->process, 'inheritEnvironmentVariables')) { |
||
362 | $this->process->inheritEnvironmentVariables(); |
||
363 | } |
||
364 | $this->process->setEnv($this->env); |
||
365 | } |
||
366 | |||
367 | View Code Duplication | if (!$this->background && !$this->isPrinted) { |
|
0 ignored issues
–
show
This code seems to be duplicated across 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.
Loading history...
|
|||
368 | $this->startTimer(); |
||
369 | $this->process->run(); |
||
370 | $this->stopTimer(); |
||
371 | $output = rtrim($this->process->getOutput()); |
||
372 | return new ResultData( |
||
373 | $this->process->getExitCode(), |
||
374 | $output, |
||
375 | $this->getResultData() |
||
376 | ); |
||
377 | } |
||
378 | |||
379 | View Code Duplication | if (!$this->background && $this->isPrinted) { |
|
0 ignored issues
–
show
This code seems to be duplicated across 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.
Loading history...
|
|||
380 | $this->startTimer(); |
||
381 | $this->process->run($output_callback); |
||
382 | $this->stopTimer(); |
||
383 | return new ResultData( |
||
384 | $this->process->getExitCode(), |
||
385 | $this->process->getOutput(), |
||
386 | $this->getResultData() |
||
387 | ); |
||
388 | } |
||
389 | |||
390 | try { |
||
391 | $this->process->start(); |
||
392 | } catch (\Exception $e) { |
||
393 | return new ResultData( |
||
394 | $this->process->getExitCode(), |
||
395 | $e->getMessage(), |
||
396 | $this->getResultData() |
||
397 | ); |
||
398 | } |
||
399 | return new ResultData($this->process->getExitCode()); |
||
400 | } |
||
401 | |||
402 | protected function stop() |
||
403 | { |
||
404 | if ($this->background && isset($this->process) && $this->process->isRunning()) { |
||
405 | $this->process->stop(); |
||
406 | $this->printTaskInfo( |
||
407 | "Stopped {command}", |
||
408 | ['command' => $this->getCommandDescription()] |
||
409 | ); |
||
410 | } |
||
411 | } |
||
412 | |||
413 | /** |
||
414 | * @param array $context |
||
415 | */ |
||
416 | protected function printAction($context = []) |
||
417 | { |
||
418 | $command = $this->getCommandDescription(); |
||
419 | $formatted_command = $this->formatCommandDisplay($command); |
||
420 | |||
421 | $dir = $this->workingDirectory ? " in {dir}" : ""; |
||
422 | $this->printTaskInfo("Running {command}$dir", [ |
||
423 | 'command' => $formatted_command, |
||
424 | 'dir' => $this->workingDirectory |
||
425 | ] + $context); |
||
426 | } |
||
427 | |||
428 | /** |
||
429 | * @param string $command |
||
430 | * |
||
431 | * @return string |
||
432 | */ |
||
433 | protected function formatCommandDisplay($command) |
||
434 | { |
||
435 | $formatted_command = str_replace("&&", "&&\n", $command); |
||
436 | $formatted_command = str_replace("||", "||\n", $formatted_command); |
||
437 | |||
438 | return $formatted_command; |
||
439 | } |
||
440 | |||
441 | /** |
||
442 | * Gets the data array to be passed to Result(). |
||
443 | * |
||
444 | * @return array |
||
445 | * The data array passed to Result(). |
||
446 | */ |
||
447 | protected function getResultData() |
||
448 | { |
||
449 | if ($this->isMetadataPrinted) { |
||
450 | return ['time' => $this->getExecutionTime()]; |
||
451 | } |
||
452 | |||
453 | return []; |
||
454 | } |
||
455 | } |
||
456 |
In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:
Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion: