Issues (55)

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/Parameter.php (4 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
namespace GuzzleHttp\Command\Guzzle;
3
4
use GuzzleHttp\Command\ToArrayInterface;
5
6
/**
7
 * API parameter object used with service descriptions
8
 */
9
class Parameter implements ToArrayInterface
10
{
11
    private $originalData;
12
13
    /** @var string $name */
14
    private $name;
15
16
    /** @var string $description */
17
    private $description;
18
19
    /** @var string|array $type */
20
    private $type;
21
22
    /** @var bool $required*/
23
    private $required;
24
25
    /** @var array|null $enum */
26
    private $enum;
27
28
    /** @var string $pattern */
29
    private $pattern;
30
31
    /** @var int $minimum*/
32
    private $minimum;
33
34
    /** @var int $maximum */
35
    private $maximum;
36
37
    /** @var int $minLength */
38
    private $minLength;
39
40
    /** @var int $maxLength */
41
    private $maxLength;
42
43
    /** @var int $minItems */
44
    private $minItems;
45
46
    /** @var int $maxItems */
47
    private $maxItems;
48
49
    /** @var mixed $default */
50
    private $default;
51
52
    /** @var bool $static */
53
    private $static;
54
55
    /** @var array $filters */
56
    private $filters;
57
58
    /** @var string $location */
59
    private $location;
60
61
    /** @var string $sentAs */
62
    private $sentAs;
63
64
    /** @var array $data */
65
    private $data;
66
67
    /** @var array $properties */
68
    private $properties = [];
69
70
    /** @var array|bool|Parameter $additionalProperties */
71
    private $additionalProperties;
72
73
    /** @var array|Parameter $items */
74
    private $items;
75
76
    /** @var string $format */
77
    private $format;
78
79
    private $propertiesCache = null;
80
81
    /** @var Description */
82
    private $serviceDescription;
83
84
    /**
85
     * Create a new Parameter using an associative array of data.
86
     *
87
     * The array can contain the following information:
88
     *
89
     * - name: (string) Unique name of the parameter
90
     *
91
     * - type: (string|array) Type of variable (string, number, integer,
92
     *   boolean, object, array, numeric, null, any). Types are used for
93
     *   validation and determining the structure of a parameter. You can use a
94
     *   union type by providing an array of simple types. If one of the union
95
     *   types matches the provided value, then the value is valid.
96
     *
97
     * - required: (bool) Whether or not the parameter is required
98
     *
99
     * - default: (mixed) Default value to use if no value is supplied
100
     *
101
     * - static: (bool) Set to true to specify that the parameter value cannot
102
     *   be changed from the default.
103
     *
104
     * - description: (string) Documentation of the parameter
105
     *
106
     * - location: (string) The location of a request used to apply a parameter.
107
     *   Custom locations can be registered with a command, but the defaults
108
     *   are uri, query, header, body, json, xml, formParam, multipart.
109
     *
110
     * - sentAs: (string) Specifies how the data being modeled is sent over the
111
     *   wire. For example, you may wish to include certain headers in a
112
     *   response model that have a normalized casing of FooBar, but the actual
113
     *   header is x-foo-bar. In this case, sentAs would be set to x-foo-bar.
114
     *
115
     * - filters: (array) Array of static method names to run a parameter
116
     *   value through. Each value in the array must be a string containing the
117
     *   full class path to a static method or an array of complex filter
118
     *   information. You can specify static methods of classes using the full
119
     *   namespace class name followed by '::' (e.g. Foo\Bar::baz). Some
120
     *   filters require arguments in order to properly filter a value. For
121
     *   complex filters, use a hash containing a 'method' key pointing to a
122
     *   static method, and an 'args' key containing an array of positional
123
     *   arguments to pass to the method. Arguments can contain keywords that
124
     *   are replaced when filtering a value: '@value' is replaced with the
125
     *   value being validated, '@api' is replaced with the Parameter object.
126
     *
127
     * - properties: When the type is an object, you can specify nested parameters
128
     *
129
     * - additionalProperties: (array) This attribute defines a schema for all
130
     *   properties that are not explicitly defined in an object type
131
     *   definition. If specified, the value MUST be a schema or a boolean. If
132
     *   false is provided, no additional properties are allowed beyond the
133
     *   properties defined in the schema. The default value is an empty schema
134
     *   which allows any value for additional properties.
135
     *
136
     * - items: This attribute defines the allowed items in an instance array,
137
     *   and MUST be a schema or an array of schemas. The default value is an
138
     *   empty schema which allows any value for items in the instance array.
139
     *   When this attribute value is a schema and the instance value is an
140
     *   array, then all the items in the array MUST be valid according to the
141
     *   schema.
142
     *
143
     * - pattern: When the type is a string, you can specify the regex pattern
144
     *   that a value must match
145
     *
146
     * - enum: When the type is a string, you can specify a list of acceptable
147
     *   values.
148
     *
149
     * - minItems: (int) Minimum number of items allowed in an array
150
     *
151
     * - maxItems: (int) Maximum number of items allowed in an array
152
     *
153
     * - minLength: (int) Minimum length of a string
154
     *
155
     * - maxLength: (int) Maximum length of a string
156
     *
157
     * - minimum: (int) Minimum value of an integer
158
     *
159
     * - maximum: (int) Maximum value of an integer
160
     *
161
     * - data: (array) Any additional custom data to use when serializing,
162
     *   validating, etc
163
     *
164
     * - format: (string) Format used to coax a value into the correct format
165
     *   when serializing or unserializing. You may specify either an array of
166
     *   filters OR a format, but not both. Supported values: date-time, date,
167
     *   time, timestamp, date-time-http, and boolean-string.
168
     *
169
     * - $ref: (string) String referencing a service description model. The
170
     *   parameter is replaced by the schema contained in the model.
171
     *
172
     * @param array $data    Array of data as seen in service descriptions
173
     * @param array $options Options used when creating the parameter. You can
174
     *     specify a Guzzle service description in the 'description' key.
175
     *
176
     * @throws \InvalidArgumentException
177
     */
178 34
    public function __construct(array $data = [], array $options = [])
179
    {
180 34
        $this->originalData = $data;
181
182 34
        if (isset($options['description'])) {
183 7
            $this->serviceDescription = $options['description'];
184 7
            if (!($this->serviceDescription instanceof DescriptionInterface)) {
185 1
                throw new \InvalidArgumentException('description must be a Description');
186
            }
187 6
            if (isset($data['$ref'])) {
188 1
                if ($model = $this->serviceDescription->getModel($data['$ref'])) {
189 1
                    $name = isset($data['name']) ? $data['name'] : null;
190 1
                    $data = $model->toArray() + $data;
191 1
                    if ($name) {
192
                        $data['name'] = $name;
193
                    }
194 1
                }
195 6
            } elseif (isset($data['extends'])) {
196
                // If this parameter extends from another parameter then start
197
                // with the actual data union in the parent's data (e.g. actual
198
                // supersedes parent)
199 1
                if ($extends = $this->serviceDescription->getModel($data['extends'])) {
200 1
                    $data += $extends->toArray();
201 1
                }
202 1
            }
203 6
        }
204
205
        // Pull configuration data into the parameter
206 33
        foreach ($data as $key => $value) {
207 31
            $this->{$key} = $value;
208 33
        }
209
210 33
        $this->required = (bool) $this->required;
211 33
        $this->data = (array) $this->data;
212
213 33
        if ($this->filters) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->filters of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
214 10
            $this->setFilters((array) $this->filters);
215 9
        }
216
217 32
        if ($this->type == 'object' && $this->additionalProperties === null) {
218 2
            $this->additionalProperties = true;
219 2
        }
220 32
    }
221
222
    /**
223
     * Convert the object to an array
224
     *
225
     * @return array
226
     */
227 7
    public function toArray()
228
    {
229 7
        return $this->originalData;
230
    }
231
232
    /**
233
     * Get the default or static value of the command based on a value
234
     *
235
     * @param string $value Value that is currently set
236
     *
237
     * @return mixed Returns the value, a static value if one is present, or a default value
238
     */
239 4
    public function getValue($value)
240
    {
241 4
        if ($this->static || ($this->default !== null && $value === null)) {
242 2
            return $this->default;
243
        }
244
245 2
        return $value;
246
    }
247
248
    /**
249
     * Run a value through the filters OR format attribute associated with the
250
     * parameter.
251
     *
252
     * @param mixed $value Value to filter
253
     *
254
     * @return mixed Returns the filtered value
255
     * @throws \RuntimeException when trying to format when no service
256
     *     description is available.
257
     */
258 8
    public function filter($value)
259
    {
260
        // Formats are applied exclusively and supersed filters
261 8
        if ($this->format) {
262 5
            if (!$this->serviceDescription) {
263 1
                throw new \RuntimeException('No service description was set so '
264 1
                    . 'the value cannot be formatted.');
265
            }
266 4
            return $this->serviceDescription->format($this->format, $value);
267
        }
268
269
        // Convert Boolean values
270 3
        if ($this->type == 'boolean' && !is_bool($value)) {
271 1
            $value = filter_var($value, FILTER_VALIDATE_BOOLEAN);
272 1
        }
273
274
        // Apply filters to the value
275 3
        if ($this->filters) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->filters of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
276 2
            foreach ($this->filters as $filter) {
277 2
                if (is_array($filter)) {
278
                    // Convert complex filters that hold value place holders
279 1
                    foreach ($filter['args'] as &$data) {
280 1
                        if ($data == '@value') {
281 1
                            $data = $value;
282 1
                        } elseif ($data == '@api') {
283 1
                            $data = $this;
284 1
                        }
285 1
                    }
286 1
                    $value = call_user_func_array(
287 1
                        $filter['method'],
288 1
                        $filter['args']
289 1
                    );
290 1
                } else {
291 1
                    $value = call_user_func($filter, $value);
292
                }
293 2
            }
294 2
        }
295
296 3
        return $value;
297
    }
298
299
    /**
300
     * Get the name of the parameter
301
     *
302
     * @return string
303
     */
304 1
    public function getName()
305
    {
306 1
        return $this->name;
307
    }
308
309
    /**
310
     * Set the name of the parameter
311
     *
312
     * @param string $name Name to set
313
     */
314 1
    public function setName($name)
315
    {
316 1
        $this->name = $name;
317 1
    }
318
319
    /**
320
     * Get the key of the parameter, where sentAs will supersede name if it is
321
     * set.
322
     *
323
     * @return string
324
     */
325 1
    public function getWireName()
326
    {
327 1
        return $this->sentAs ?: $this->name;
328
    }
329
330
    /**
331
     * Get the type(s) of the parameter
332
     *
333
     * @return string|array
334
     */
335 2
    public function getType()
336
    {
337 2
        return $this->type;
338
    }
339
340
    /**
341
     * Get if the parameter is required
342
     *
343
     * @return bool
344
     */
345 1
    public function isRequired()
346
    {
347 1
        return $this->required;
348
    }
349
350
    /**
351
     * Get the default value of the parameter
352
     *
353
     * @return string|null
354
     */
355 1
    public function getDefault()
356
    {
357 1
        return $this->default;
358
    }
359
360
    /**
361
     * Get the description of the parameter
362
     *
363
     * @return string|null
364
     */
365 1
    public function getDescription()
366
    {
367 1
        return $this->description;
368
    }
369
370
    /**
371
     * Get the minimum acceptable value for an integer
372
     *
373
     * @return int|null
374
     */
375 1
    public function getMinimum()
376
    {
377 1
        return $this->minimum;
378
    }
379
380
    /**
381
     * Get the maximum acceptable value for an integer
382
     *
383
     * @return int|null
384
     */
385 1
    public function getMaximum()
386
    {
387 1
        return $this->maximum;
388
    }
389
390
    /**
391
     * Get the minimum allowed length of a string value
392
     *
393
     * @return int
394
     */
395 1
    public function getMinLength()
396
    {
397 1
        return $this->minLength;
398
    }
399
400
    /**
401
     * Get the maximum allowed length of a string value
402
     *
403
     * @return int|null
404
     */
405 1
    public function getMaxLength()
406
    {
407 1
        return $this->maxLength;
408
    }
409
410
    /**
411
     * Get the maximum allowed number of items in an array value
412
     *
413
     * @return int|null
414
     */
415 1
    public function getMaxItems()
416
    {
417 1
        return $this->maxItems;
418
    }
419
420
    /**
421
     * Get the minimum allowed number of items in an array value
422
     *
423
     * @return int
424
     */
425 1
    public function getMinItems()
426
    {
427 1
        return $this->minItems;
428
    }
429
430
    /**
431
     * Get the location of the parameter
432
     *
433
     * @return string|null
434
     */
435 2
    public function getLocation()
436
    {
437 2
        return $this->location;
438
    }
439
440
    /**
441
     * Get the sentAs attribute of the parameter that used with locations to
442
     * sentAs an attribute when it is being applied to a location.
443
     *
444
     * @return string|null
445
     */
446 1
    public function getSentAs()
447
    {
448 1
        return $this->sentAs;
449
    }
450
451
    /**
452
     * Retrieve a known property from the parameter by name or a data property
453
     * by name. When no specific name value is passed, all data properties
454
     * will be returned.
455
     *
456
     * @param string|null $name Specify a particular property name to retrieve
457
     *
458
     * @return array|mixed|null
459
     */
460 1
    public function getData($name = null)
461
    {
462 1
        if (!$name) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $name of type string|null is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
463 1
            return $this->data;
464 1
        } elseif (isset($this->data[$name])) {
465 1
            return $this->data[$name];
466 1
        } elseif (isset($this->{$name})) {
467 1
            return $this->{$name};
468
        }
469
470 1
        return null;
471
    }
472
473
    /**
474
     * Get whether or not the default value can be changed
475
     *
476
     * @return bool
477
     */
478 1
    public function isStatic()
479
    {
480 1
        return $this->static;
481
    }
482
483
    /**
484
     * Get an array of filters used by the parameter
485
     *
486
     * @return array
487
     */
488 2
    public function getFilters()
489
    {
490 2
        return $this->filters ?: [];
491
    }
492
493
    /**
494
     * Get the properties of the parameter
495
     *
496
     * @return Parameter[]
497
     */
498 1
    public function getProperties()
499
    {
500 1
        if (!$this->propertiesCache) {
501 1
            $this->propertiesCache = [];
502 1
            foreach (array_keys($this->properties) as $name) {
503 1
                $this->propertiesCache[$name] = $this->getProperty($name);
504 1
            }
505 1
        }
506
507 1
        return $this->propertiesCache;
508
    }
509
510
    /**
511
     * Get a specific property from the parameter
512
     *
513
     * @param string $name Name of the property to retrieve
514
     *
515
     * @return null|Parameter
516
     */
517 1
    public function getProperty($name)
518
    {
519 1
        if (!isset($this->properties[$name])) {
520 1
            return null;
521
        }
522
523 1
        if (!($this->properties[$name] instanceof self)) {
524 1
            $this->properties[$name]['name'] = $name;
525 1
            $this->properties[$name] = new static(
526 1
                $this->properties[$name],
527 1
                ['description' => $this->serviceDescription]
528 1
            );
529 1
        }
530
531 1
        return $this->properties[$name];
532
    }
533
534
    /**
535
     * Get the additionalProperties value of the parameter
536
     *
537
     * @return bool|Parameter|null
538
     */
539 1
    public function getAdditionalProperties()
540
    {
541 1
        if (is_array($this->additionalProperties)) {
542 1
            $this->additionalProperties = new static(
543 1
                $this->additionalProperties,
544 1
                ['description' => $this->serviceDescription]
545 1
            );
546 1
        }
547
548 1
        return $this->additionalProperties;
549
    }
550
551
    /**
552
     * Get the item data of the parameter
553
     *
554
     * @return Parameter
555
     */
556 1
    public function getItems()
557
    {
558 1
        if (is_array($this->items)) {
559 1
            $this->items = new static(
560 1
                $this->items,
561 1
                ['description' => $this->serviceDescription]
562 1
            );
563 1
        }
564
565 1
        return $this->items;
566
    }
567
568
    /**
569
     * Get the enum of strings that are valid for the parameter
570
     *
571
     * @return array|null
572
     */
573 1
    public function getEnum()
574
    {
575 1
        return $this->enum;
576
    }
577
578
    /**
579
     * Get the regex pattern that must match a value when the value is a string
580
     *
581
     * @return string
582
     */
583 1
    public function getPattern()
584
    {
585 1
        return $this->pattern;
586
    }
587
588
    /**
589
     * Get the format attribute of the schema
590
     *
591
     * @return string
592
     */
593 4
    public function getFormat()
594
    {
595 4
        return $this->format;
596
    }
597
598
    /**
599
     * Set the array of filters used by the parameter
600
     *
601
     * @param array $filters Array of functions to use as filters
602
     *
603
     * @return self
604
     */
605 10
    private function setFilters(array $filters)
606
    {
607 10
        $this->filters = [];
608 10
        foreach ($filters as $filter) {
609 10
            $this->addFilter($filter);
610 9
        }
611
612 9
        return $this;
613
    }
614
615
    /**
616
     * Add a filter to the parameter
617
     *
618
     * @param string|array $filter Method to filter the value through
619
     *
620
     * @return self
621
     * @throws \InvalidArgumentException
622
     */
623 10
    private function addFilter($filter)
624
    {
625 10
        if (is_array($filter)) {
626 2
            if (!isset($filter['method'])) {
627 1
                throw new \InvalidArgumentException(
628
                    'A [method] value must be specified for each complex filter'
629 1
                );
630
            }
631 1
        }
632
633 9
        if (!$this->filters) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->filters of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
634 9
            $this->filters = [$filter];
635 9
        } else {
636 7
            $this->filters[] = $filter;
637
        }
638
639 9
        return $this;
640
    }
641
642
    /**
643
     * Check if a parameter has a specific variable and if it set.
644
     *
645
     * @param string $var
646
     * @return bool
647
     */
648 3
    public function has($var)
649
    {
650 3
        if (!is_string($var)) {
651 1
            throw new \InvalidArgumentException('Expected a string. Got: ' . (is_object($var) ? get_class($var) : gettype($var)));
652
        }
653 2
        return isset($this->{$var}) && !empty($this->{$var});
654
    }
655
}
656