Issues (283)

Security Analysis    no request data  

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

src/Args/DefaultArgsParser.php (3 issues)

Upgrade to new PHP Analysis Engine

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 webmozart/console package.
5
 *
6
 * (c) Bernhard Schussek <[email protected]>
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 Webmozart\Console\Args;
13
14
use RuntimeException;
15
use Symfony\Component\Console\Input\ArgvInput;
16
use Symfony\Component\Console\Input\InputArgument;
17
use Webmozart\Console\Adapter\ArgsFormatInputDefinition;
18
use Webmozart\Console\Api\Args\Args;
19
use Webmozart\Console\Api\Args\ArgsParser;
20
use Webmozart\Console\Api\Args\CannotParseArgsException;
21
use Webmozart\Console\Api\Args\Format\ArgsFormat;
22
use Webmozart\Console\Api\Args\RawArgs;
23
24
/**
25
 * Default parser for {@link RawArgs} instances.
26
 *
27
 * This parser delegates most of the work to Symfony's {@link ArgvInput} class.
28
 *
29
 * @since  1.0
30
 *
31
 * @author Bernhard Schussek <[email protected]>
32
 */
33
class DefaultArgsParser extends ArgvInput implements ArgsParser
34
{
35
    /**
36
     * Creates a new parser.
37
     */
38 307
    public function __construct()
39
    {
40
        // Hide the parent arguments from the public signature
41 307
        parent::__construct();
42 307
    }
43
44
    /**
45
     * {@inheritdoc}
46
     */
47 303
    public function parseArgs(RawArgs $args, ArgsFormat $format, $lenient = false)
48
    {
49 303
        $this->setTokens($args->getTokens());
50
51 303
        $formatAdapter = new ArgsFormatInputDefinition($format);
52
53
        try {
54 303
            $this->bind($formatAdapter);
55 13
        } catch (RuntimeException $e) {
56 13
            if (!$lenient) {
57 6
                throw new CannotParseArgsException($e->getMessage());
58
            }
59
        }
60
61
        // Prevent failing validation if not all command names are given
62 297
        $this->insertMissingCommandNames($formatAdapter, $lenient);
63
64
        try {
65 296
            $this->validate();
66 6
        } catch (RuntimeException $e) {
67 6
            if (!$lenient) {
68 3
                throw new CannotParseArgsException($e->getMessage());
69
            }
70
        }
71
72 293
        return $this->createArgs($format, $args);
73
    }
74
75
    /**
76
     * Creates the arguments from the current class state.
77
     *
78
     * @param ArgsFormat $format  The format.
79
     * @param RawArgs    $rawArgs The raw arguments.
80
     *
81
     * @return Args The created console arguments.
82
     */
83 293
    private function createArgs(ArgsFormat $format, RawArgs $rawArgs)
84
    {
85 293
        $args = new Args($format, $rawArgs);
86
87 293
        foreach ($this->arguments as $name => $value) {
88
            // Filter command names
89 290
            if ($format->hasArgument($name)) {
90 290
                $args->setArgument($name, $value);
91
            }
92
        }
93
94 293
        foreach ($this->options as $name => $value) {
95
            // Filter command options
96 235
            if ($format->hasOption($name)) {
97 235
                $args->setOption($name, $value);
98
            }
99
        }
100
101 293
        return $args;
102
    }
103
104 297
    private function insertMissingCommandNames(ArgsFormatInputDefinition $inputDefinition, $lenient = false)
105
    {
106
        // Start with the default values of the arguments.
107 297
        $inputArguments = $inputDefinition->getArguments();
108 297
        $fixedValues = array();
109 297
        $commandNames = $inputDefinition->getCommandNamesByArgumentName();
110
111
        // Flatten the actual arguments, in case they contain a multi-valued
112
        // argument.
113 297
        $actualValues = $this->flatten($this->arguments);
114
115
        // Reset all array pointers.
116 297
        reset($commandNames);
117 297
        reset($actualValues);
118 297
        reset($inputArguments);
119
120
        // Skip the command names. The resulting pointer is like this:
121
        //
122
        // actual: [ 0: remote, 1: origin, 2: foo/bar ]
0 ignored issues
show
Unused Code Comprehensibility introduced by
40% 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.

Loading history...
123
        //                      ^
124
125 297
        $this->skipCommandNames($actualValues, $commandNames);
126
127
        // Copy the command names into the fixed array. The result is:
128
        //
129
        // fixed: [ cmd1: remote, cmd2: add ]
130
131 297
        $this->copyArgumentValues($commandNames, $inputArguments, $fixedValues, $lenient);
132
133
        // Copy the remaining actual values. The result is:
134
        //
135
        // fixed: [ cmd1: remote, cmd2: add, name: origin, target: foo/bar ]
136
137 297
        $this->copyArgumentValues($actualValues, $inputArguments, $fixedValues, $lenient);
138
139
        // Overwrite all current arguments with the fixed values
140 296
        foreach ($fixedValues as $name => $value) {
141 293
            $this->arguments[$name] = $value;
142
        }
143 296
    }
144
145 297
    private function flatten(array $arguments, array &$result = array())
146
    {
147 297
        foreach ($arguments as $value) {
148 238
            if (is_array($value)) {
149 3
                $this->flatten($value, $result);
150
            } else {
151 238
                $result[] = $value;
152
            }
153
        }
154
155 297
        return $result;
156
    }
157
158 297
    private function skipCommandNames(array &$arguments, array $commandNames)
159
    {
160 297
        reset($commandNames);
161
162 297
        while (null !== key($arguments) && null !== key($commandNames) && current($commandNames)->match(current($arguments))) {
163 227
            next($arguments);
164 227
            next($commandNames);
165
        }
166 297
    }
167
168 297
    private function copyArgumentValues(array &$actualValues, array &$inputArguments, array &$fixedValues, $lenient = false)
169
    {
170
        // The starting point are two arrays of arguments with the array
171
        // pointers set:
172
173
        // values: [ 0: remote, 1: origin, 2: foo/bar ]
0 ignored issues
show
Unused Code Comprehensibility introduced by
40% 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.

Loading history...
174
        //                      ^
175
        // args:   [ cmd1: Argument, cmd2: Argument, name: Argument, target: Argument ]
176
        //                                                     ^
177
178
        // The fixed values may already contain values:
179
180
        // fixed: [ cmd1: remote, cmd2: add ]
181
182
        // The goal is to copy the actual values to the fixed array so that the
183
        // end result is:
184
185
        // fixed: [ cmd1: remote, cmd2: add, name: origin, target: foo/bar ]
186
187
        // Multi-valued arguments need special treatment. In this case, the
188
        // actual values are like this:
189
190
        // values: [ 0: remote, 1: one, 2: two, 3: three ]
0 ignored issues
show
Unused Code Comprehensibility introduced by
45% 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.

Loading history...
191
        //                      ^
192
        // args:   [ cmd1: Argument, cmd2: Argument, multi: Argument ]
193
        //                                                     ^
194
195
        // The expected result is:
196
197
        // fixed: [ cmd1: remote, cmd2: add, multi: [ one, two, three ] ]
198
199 297
        while (null !== key($actualValues)) {
200 294
            if (null === key($inputArguments)) {
201 8
                if ($lenient) {
202 1
                    return;
203
                }
204
205 7
                throw new CannotParseArgsException('Too many arguments.');
206
            }
207
208
            /** @var InputArgument $argument */
209 294
            $argument = current($inputArguments);
210 294
            $name = $argument->getName();
211 294
            $value = current($actualValues);
212
213
            // Append the value to multi-valued arguments
214 294
            if ($argument->isArray()) {
215 3
                if (!isset($fixedValues[$name])) {
216 3
                    $fixedValues[$name] = array();
217
                }
218
219 3
                $fixedValues[$name][] = $value;
220
221
                // The multi-valued argument is the last one, so we don't
222
                // need to advance the array pointer anymore.
223
            } else {
224 294
                $fixedValues[$name] = $value;
225
226 294
                next($inputArguments);
227
            }
228
229 294
            next($actualValues);
230
        }
231 297
    }
232
}
233