Completed
Pull Request — release-2.1 (#4069)
by Jeremy
08:58
created

xmlArray   D

Complexity

Total Complexity 129

Size/Duplication

Total Lines 700
Duplicated Lines 7.43 %

Coupling/Cohesion

Components 1
Dependencies 0

Importance

Changes 0
Metric Value
dl 52
loc 700
rs 4.4444
c 0
b 0
f 0
wmc 129
lcom 1
cbo 0

16 Methods

Rating   Name   Duplication   Size   Complexity  
B __construct() 0 26 4
A name() 0 4 2
C fetch() 0 28 7
C path() 2 54 13
B exists() 0 29 4
A count() 0 15 3
A set() 0 21 4
A create_xml() 13 20 3
A to_array() 13 19 3
D _parse() 22 142 30
C _xml() 0 46 12
B _array() 0 20 6
C _to_cdata() 0 31 12
A _from_cdata() 0 13 2
B _fetch() 0 24 5
C _path() 2 53 19

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like xmlArray often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use xmlArray, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/**
4
 * The xmlArray class is an xml parser.
5
 *
6
 * Simple Machines Forum (SMF)
7
 *
8
 * @package SMF
9
 * @author Simple Machines http://www.simplemachines.org
10
 * @copyright 2017 Simple Machines and individual contributors
11
 * @license http://www.simplemachines.org/about/smf/license.php BSD
12
 *
13
 * @version 2.1 Beta 3
14
 */
15
16
if (!defined('SMF'))
17
	die('No direct access...');
18
19
/**
20
 * Class xmlArray
21
 * Represents an XML array
22
 */
23
class xmlArray
24
{
25
	/**
26
	 * @var array Holds parsed XML results
27
	 */
28
	public $array;
29
30
	/**
31
	 * @var int The debugging level
32
	 */
33
	public $debug_level;
34
35
	/**
36
	 * holds trim level textual data
37
	 * @var bool Holds trim level textual data
38
	 */
39
	public $trim;
40
41
	/**
42
	 * Constructor for the xml parser.
43
	 * Example use:
44
	 *  $xml = new xmlArray(file('data.xml'));
45
	 *
46
	 * @param string $data The xml data or an array of, unless is_clone is true.
47
	 * @param bool $auto_trim Used to automatically trim textual data.
48
	 * @param int $level The debug level. Specifies whether notices should be generated for missing elements and attributes.
49
	 * @param bool $is_clone default false. If is_clone is true, the  xmlArray is cloned from another - used internally only.
50
	 */
51
	public function __construct($data, $auto_trim = false, $level = null, $is_clone = false)
52
	{
53
		// If we're using this try to get some more memory.
54
		setMemoryLimit('32M');
55
56
		// Set the debug level.
57
		$this->debug_level = $level !== null ? $level : error_reporting();
58
		$this->trim = $auto_trim;
59
60
		// Is the data already parsed?
61
		if ($is_clone)
62
		{
63
			$this->array = $data;
0 ignored issues
show
Documentation Bug introduced by
It seems like $data of type string is incompatible with the declared type array of property $array.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
64
			return;
65
		}
66
67
		// Is the input an array? (ie. passed from file()?)
68
		if (is_array($data))
69
			$data = implode('', $data);
70
71
		// Remove any xml declaration or doctype, and parse out comments and CDATA.
72
		$data = preg_replace('/<!--.*?-->/s', '', $this->_to_cdata(preg_replace(array('/^<\?xml.+?\?' . '>/is', '/<!DOCTYPE[^>]+?' . '>/s'), '', $data)));
73
74
		// Now parse the xml!
75
		$this->array = $this->_parse($data);
76
	}
77
78
	/**
79
	 * Get the root element's name.
80
	 * Example use:
81
	 *  echo $element->name();
82
	 * @return string The root element's name
83
	 */
84
	public function name()
85
	{
86
		return isset($this->array['name']) ? $this->array['name'] : '';
87
	}
88
89
	/**
90
	 * Get a specified element's value or attribute by path.
91
	 * Children are parsed for text, but only textual data is returned
92
	 * unless get_elements is true.
93
	 * Example use:
94
	 *  $data = $xml->fetch('html/head/title');
95
	 * @param string $path The path to the element to fetch
96
	 * @param bool $get_elements Whether to include elements
97
	 * @return string The value or attribute of the specified element
98
	 */
99
	public function fetch($path, $get_elements = false)
100
	{
101
		// Get the element, in array form.
102
		$array = $this->path($path);
103
104
		if ($array === false)
105
			return false;
106
107
		// Getting elements into this is a bit complicated...
108
		if ($get_elements && !is_string($array))
109
		{
110
			$temp = '';
111
112
			// Use the _xml() function to get the xml data.
113
			foreach ($array->array as $val)
114
			{
115
				// Skip the name and any attributes.
116
				if (is_array($val))
117
					$temp .= $this->_xml($val, null);
118
			}
119
120
			// Just get the XML data and then take out the CDATAs.
121
			return $this->_to_cdata($temp);
122
		}
123
124
		// Return the value - taking care to pick out all the text values.
125
		return is_string($array) ? $array : $this->_fetch($array->array);
126
	}
127
128
	/** Get an element, returns a new xmlArray.
129
	 * It finds any elements that match the path specified.
130
	 * It will always return a set if there is more than one of the element
131
	 * or return_set is true.
132
	 * Example use:
133
	 *  $element = $xml->path('html/body');
134
	 * @param $path string The path to the element to get
135
	 * @param $return_full bool Whether to return the full result set
136
	 * @return xmlArray, a new xmlArray.
0 ignored issues
show
Documentation introduced by
The doc-type xmlArray, could not be parsed: Expected "|" or "end of type", but got "," at position 8. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
137
	 */
138
	public function path($path, $return_full = false)
139
	{
140
		// Split up the path.
141
		$path = explode('/', $path);
142
143
		// Start with a base array.
144
		$array = $this->array;
145
146
		// For each element in the path.
147
		foreach ($path as $el)
148
		{
149
			// Deal with sets....
150
			if (strpos($el, '[') !== false)
151
			{
152
				$lvl = (int) substr($el, strpos($el, '[') + 1);
153
				$el = substr($el, 0, strpos($el, '['));
154
			}
155
			// Find an attribute.
156
			elseif (substr($el, 0, 1) == '@')
157
			{
158
				// It simplifies things if the attribute is already there ;).
159
				if (isset($array[$el]))
160
					return $array[$el];
161
				else
162
				{
163
					$trace = debug_backtrace();
164
					$i = 0;
165 View Code Duplication
					while ($i < count($trace) && isset($trace[$i]['class']) && $trace[$i]['class'] == get_class($this))
166
						$i++;
167
					$debug = ' (from ' . $trace[$i - 1]['file'] . ' on line ' . $trace[$i - 1]['line'] . ')';
168
169
					// Cause an error.
170
					if ($this->debug_level & E_NOTICE)
171
						trigger_error('Undefined XML attribute: ' . substr($el, 1) . $debug, E_USER_NOTICE);
172
					return false;
173
				}
174
			}
175
			else
176
				$lvl = null;
177
178
			// Find this element.
179
			$array = $this->_path($array, $el, $lvl);
0 ignored issues
show
Bug introduced by
It seems like $array defined by $this->_path($array, $el, $lvl) on line 179 can also be of type string; however, xmlArray::_path() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
180
		}
181
182
		// Clean up after $lvl, for $return_full.
183
		if ($return_full && (!isset($array['name']) || substr($array['name'], -1) != ']'))
184
			$array = array('name' => $el . '[]', $array);
0 ignored issues
show
Bug introduced by
The variable $el 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

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
185
186
		// Create the right type of class...
187
		$newClass = get_class($this);
188
189
		// Return a new xmlArray for the result.
190
		return $array === false ? false : new $newClass($array, $this->trim, $this->debug_level, true);
191
	}
192
193
	/**
194
	 * Check if an element exists.
195
	 * Example use,
196
	 *  echo $xml->exists('html/body') ? 'y' : 'n';
197
	 *
198
	 * @param string $path The path to the element to get.
199
	 * @return boolean Whether the specified path exists
200
	 */
201
	public function exists($path)
202
	{
203
		// Split up the path.
204
		$path = explode('/', $path);
205
206
		// Start with a base array.
207
		$array = $this->array;
208
209
		// For each element in the path.
210
		foreach ($path as $el)
211
		{
212
			// Deal with sets....
213
			if (strpos($el, '[') !== false)
214
			{
215
				$lvl = (int) substr($el, strpos($el, '[') + 1);
216
				$el = substr($el, 0, strpos($el, '['));
217
			}
218
			// Find an attribute.
219
			elseif (substr($el, 0, 1) == '@')
220
				return isset($array[$el]);
221
			else
222
				$lvl = null;
223
224
			// Find this element.
225
			$array = $this->_path($array, $el, $lvl, true);
0 ignored issues
show
Bug introduced by
It seems like $array defined by $this->_path($array, $el, $lvl, true) on line 225 can also be of type string; however, xmlArray::_path() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
226
		}
227
228
		return $array !== false;
229
	}
230
231
	/**
232
	 * Count the number of occurrences of a path.
233
	 * Example use:
234
	 *  echo $xml->count('html/head/meta');
235
	 * @param string $path The path to search for.
236
	 * @return int The number of elements the path matches.
237
	 */
238
	public function count($path)
239
	{
240
		// Get the element, always returning a full set.
241
		$temp = $this->path($path, true);
242
243
		// Start at zero, then count up all the numeric keys.
244
		$i = 0;
245
		foreach ($temp->array as $item)
246
		{
247
			if (is_array($item))
248
				$i++;
249
		}
250
251
		return $i;
252
	}
253
254
	/**
255
	 * Get an array of xmlArray's matching the specified path.
256
	 * This differs from ->path(path, true) in that instead of an xmlArray
257
	 * of elements, an array of xmlArray's is returned for use with foreach.
258
	 * Example use:
259
	 *  foreach ($xml->set('html/body/p') as $p)
260
	 * @param $path string The path to search for.
261
	 * @return xmlArray[] An array of xmlArray objects
262
	 */
263
	public function set($path)
264
	{
265
		// None as yet, just get the path.
266
		$array = array();
267
		$xml = $this->path($path, true);
268
269
		foreach ($xml->array as $val)
270
		{
271
			// Skip these, they aren't elements.
272
			if (!is_array($val) || $val['name'] == '!')
273
				continue;
274
275
			// Create the right type of class...
276
			$newClass = get_class($this);
277
278
			// Create a new xmlArray and stick it in the array.
279
			$array[] = new $newClass($val, $this->trim, $this->debug_level, true);
280
		}
281
282
		return $array;
283
	}
284
285
	/**
286
	 * Create an xml file from an xmlArray, the specified path if any.
287
	 * Example use:
288
	 *  echo $this->create_xml();
289
	 * @param string $path The path to the element. (optional)
290
	 * @return string Xml-formatted string.
291
	 */
292
	public function create_xml($path = null)
293
	{
294
		// Was a path specified?  If so, use that array.
295 View Code Duplication
		if ($path !== null)
296
		{
297
			$path = $this->path($path);
298
299
			// The path was not found
300
			if ($path === false)
301
				return false;
302
303
			$path = $path->array;
304
		}
305
		// Just use the current array.
306
		else
307
			$path = $this->array;
308
309
		// Add the xml declaration to the front.
310
		return '<?xml version="1.0"?' . '>' . $this->_xml($path, 0);
311
	}
312
313
	/**
314
	 * Output the xml in an array form.
315
	 * Example use:
316
	 *  print_r($xml->to_array());
317
	 *
318
	 * @param string $path The path to output.
319
	 * @return array An array of XML data
320
	 */
321
	public function to_array($path = null)
322
	{
323
		// Are we doing a specific path?
324 View Code Duplication
		if ($path !== null)
325
		{
326
			$path = $this->path($path);
327
328
			// The path was not found
329
			if ($path === false)
330
				return false;
331
332
			$path = $path->array;
333
		}
334
		// No, so just use the current array.
335
		else
336
			$path = $this->array;
337
338
		return $this->_array($path);
339
	}
340
341
	/**
342
	 * Parse data into an array. (privately used...)
343
	 *
344
	 * @param string $data The data to parse
345
	 * @return array The parsed array
346
	 */
347
	protected function _parse($data)
348
	{
349
		// Start with an 'empty' array with no data.
350
		$current = array(
351
		);
352
353
		// Loop until we're out of data.
354
		while ($data != '')
355
		{
356
			// Find and remove the next tag.
357
			preg_match('/\A<([\w\-:]+)((?:\s+.+?)?)([\s]?\/)?' . '>/', $data, $match);
358 View Code Duplication
			if (isset($match[0]))
359
				$data = preg_replace('/' . preg_quote($match[0], '/') . '/s', '', $data, 1);
360
361
			// Didn't find a tag?  Keep looping....
362
			if (!isset($match[1]) || $match[1] == '')
363
			{
364
				// If there's no <, the rest is data.
365
				if (strpos($data, '<') === false)
366
				{
367
					$text_value = $this->_from_cdata($data);
368
					$data = '';
369
370
					if ($text_value != '')
371
						$current[] = array(
372
							'name' => '!',
373
							'value' => $text_value
374
						);
375
				}
376
				// If the < isn't immediately next to the current position... more data.
377
				elseif (strpos($data, '<') > 0)
378
				{
379
					$text_value = $this->_from_cdata(substr($data, 0, strpos($data, '<')));
380
					$data = substr($data, strpos($data, '<'));
381
382
					if ($text_value != '')
383
						$current[] = array(
384
							'name' => '!',
385
							'value' => $text_value
386
						);
387
				}
388
				// If we're looking at a </something> with no start, kill it.
389
				elseif (strpos($data, '<') !== false && strpos($data, '<') == 0)
390
				{
391
					if (strpos($data, '<', 1) !== false)
392
					{
393
						$text_value = $this->_from_cdata(substr($data, 0, strpos($data, '<', 1)));
394
						$data = substr($data, strpos($data, '<', 1));
395
396
						if ($text_value != '')
397
							$current[] = array(
398
								'name' => '!',
399
								'value' => $text_value
400
							);
401
					}
402 View Code Duplication
					else
403
					{
404
						$text_value = $this->_from_cdata($data);
405
						$data = '';
406
407
						if ($text_value != '')
408
							$current[] = array(
409
								'name' => '!',
410
								'value' => $text_value
411
							);
412
					}
413
				}
414
415
				// Wait for an actual occurance of an element.
416
				continue;
417
			}
418
419
			// Create a new element in the array.
420
			$el = &$current[];
421
			$el['name'] = $match[1];
422
423
			// If this ISN'T empty, remove the close tag and parse the inner data.
424
			if ((!isset($match[3]) || trim($match[3]) != '/') && (!isset($match[2]) || trim($match[2]) != '/'))
425
			{
426
				// Because PHP 5.2.0+ seems to croak using regex, we'll have to do this the less fun way.
427
				$last_tag_end = strpos($data, '</' . $match[1] . '>');
428
				if ($last_tag_end === false)
429
					continue;
430
431
				$offset = 0;
432
				while (1 == 1)
433
				{
434
					// Where is the next start tag?
435
					$next_tag_start = strpos($data, '<' . $match[1], $offset);
436
					// If the next start tag is after the last end tag then we've found the right close.
437
					if ($next_tag_start === false || $next_tag_start > $last_tag_end)
438
						break;
439
440
					// If not then find the next ending tag.
441
					$next_tag_end = strpos($data, '</' . $match[1] . '>', $offset);
442
443
					// Didn't find one? Then just use the last and sod it.
444
					if ($next_tag_end === false)
445
						break;
446
					else
447
					{
448
						$last_tag_end = $next_tag_end;
449
						$offset = $next_tag_start + 1;
450
					}
451
				}
452
				// Parse the insides.
453
				$inner_match = substr($data, 0, $last_tag_end);
454
				// Data now starts from where this section ends.
455
				$data = substr($data, $last_tag_end + strlen('</' . $match[1] . '>'));
456
457
				if (!empty($inner_match))
458
				{
459
					// Parse the inner data.
460
					if (strpos($inner_match, '<') !== false)
461
						$el += $this->_parse($inner_match);
462 View Code Duplication
					elseif (trim($inner_match) != '')
463
					{
464
						$text_value = $this->_from_cdata($inner_match);
465
						if ($text_value != '')
466
							$el[] = array(
467
								'name' => '!',
468
								'value' => $text_value
469
							);
470
					}
471
				}
472
			}
473
474
			// If we're dealing with attributes as well, parse them out.
475
			if (isset($match[2]) && $match[2] != '')
476
			{
477
				// Find all the attribute pairs in the string.
478
				preg_match_all('/([\w:]+)="(.+?)"/', $match[2], $attr, PREG_SET_ORDER);
479
480
				// Set them as @attribute-name.
481
				foreach ($attr as $match_attr)
0 ignored issues
show
Bug introduced by
The expression $attr of type null|array<integer,array<integer,string>> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
482
					$el['@' . $match_attr[1]] = $match_attr[2];
483
			}
484
		}
485
486
		// Return the parsed array.
487
		return $current;
488
	}
489
490
	/**
491
	 * Get a specific element's xml. (privately used...)
492
	 *
493
	 * @param array $array An array of element data
494
	 * @param null|int $indent How many levels to indent the elements (null = no indent)
495
	 * @return string The formatted XML
496
	 */
497
	protected function _xml($array, $indent)
498
	{
499
		$indentation = $indent !== null ? '
500
' . str_repeat('	', $indent) : '';
501
502
		// This is a set of elements, with no name...
503
		if (is_array($array) && !isset($array['name']))
504
		{
505
			$temp = '';
506
			foreach ($array as $val)
507
				$temp .= $this->_xml($val, $indent);
0 ignored issues
show
Documentation introduced by
$val is of type null, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
508
			return $temp;
509
		}
510
511
		// This is just text!
512
		if ($array['name'] == '!')
513
			return $indentation . '<![CDATA[' . $array['value'] . ']]>';
514
		elseif (substr($array['name'], -2) == '[]')
515
			$array['name'] = substr($array['name'], 0, -2);
516
517
		// Start the element.
518
		$output = $indentation . '<' . $array['name'];
519
520
		$inside_elements = false;
521
		$output_el = '';
522
523
		// Run through and recursively output all the elements or attrbutes inside this.
524
		foreach ($array as $k => $v)
525
		{
526
			if (substr($k, 0, 1) == '@')
527
				$output .= ' ' . substr($k, 1) . '="' . $v . '"';
528
			elseif (is_array($v))
529
			{
530
				$output_el .= $this->_xml($v, $indent === null ? null : $indent + 1);
531
				$inside_elements = true;
532
			}
533
		}
534
535
		// Indent, if necessary.... then close the tag.
536
		if ($inside_elements)
537
			$output .= '>' . $output_el . $indentation . '</' . $array['name'] . '>';
538
		else
539
			$output .= ' />';
540
541
		return $output;
542
	}
543
544
	/**
545
	 * Return an element as an array
546
	 *
547
	 * @param array $array An array of data
548
	 * @return string|array A string with the element's value or an array of element data
549
	 */
550
	protected function _array($array)
551
	{
552
		$return = array();
553
		$text = '';
554
		foreach ($array as $value)
555
		{
556
			if (!is_array($value) || !isset($value['name']))
557
				continue;
558
559
			if ($value['name'] == '!')
560
				$text .= $value['value'];
561
			else
562
				$return[$value['name']] = $this->_array($value);
563
		}
564
565
		if (empty($return))
566
			return $text;
567
		else
568
			return $return;
569
	}
570
571
	/**
572
	 * Parse out CDATA tags. (htmlspecialchars them...)
573
	 *
574
	 * @param string $data The data with CDATA tags included
575
	 * @return string The data contained within CDATA tags
576
	 */
577
	function _to_cdata($data)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
578
	{
579
		$inCdata = $inComment = false;
580
		$output = '';
581
582
		$parts = preg_split('~(<!\[CDATA\[|\]\]>|<!--|-->)~', $data, -1, PREG_SPLIT_DELIM_CAPTURE);
583
		foreach ($parts as $part)
584
		{
585
			// Handle XML comments.
586
			if (!$inCdata && $part === '<!--')
587
				$inComment = true;
588
			if ($inComment && $part === '-->')
589
				$inComment = false;
590
			elseif ($inComment)
591
				continue;
592
593
			// Handle Cdata blocks.
594
			elseif (!$inComment && $part === '<![CDATA[')
595
				$inCdata = true;
596
			elseif ($inCdata && $part === ']]>')
597
				$inCdata = false;
598
			elseif ($inCdata)
599
				$output .= htmlentities($part, ENT_QUOTES);
600
601
			// Everything else is kept as is.
602
			else
603
				$output .= $part;
604
		}
605
606
		return $output;
607
	}
608
609
	/**
610
	 * Turn the CDATAs back to normal text.
611
	 *
612
	 * @param string $data The data with CDATA tags
613
	 * @return string The transformed data
614
	 */
615
	protected function _from_cdata($data)
616
	{
617
		// Get the HTML translation table and reverse it.
618
		$trans_tbl = array_flip(get_html_translation_table(HTML_ENTITIES, ENT_QUOTES));
619
620
		// Translate all the entities out.
621
		$data = strtr(preg_replace_callback('~&#(\d{1,4});~', function($m)
622
		{
623
			return chr("$m[1]");
624
		}, $data), $trans_tbl);
625
626
		return $this->trim ? trim($data) : $data;
627
	}
628
629
	/**
630
	 * Given an array, return the text from that array. (recursive and privately used.)
631
	 *
632
	 * @param array $array An aray of data
633
	 * @return string The text from the array
634
	 */
635
	protected function _fetch($array)
636
	{
637
		// Don't return anything if this is just a string.
638
		if (is_string($array))
639
			return '';
640
641
		$temp = '';
642
		foreach ($array as $text)
643
		{
644
			// This means it's most likely an attribute or the name itself.
645
			if (!isset($text['name']))
646
				continue;
647
648
			// This is text!
649
			if ($text['name'] == '!')
650
				$temp .= $text['value'];
651
			// Another element - dive in ;).
652
			else
653
				$temp .= $this->_fetch($text);
654
		}
655
656
		// Return all the bits and pieces we've put together.
657
		return $temp;
658
	}
659
660
	/**
661
	 * Get a specific array by path, one level down. (privately used...)
662
	 *
663
	 * @param array $array An array of data
664
	 * @param string $path The path
665
	 * @param int $level How far deep into the array we should go
666
	 * @param bool $no_error Whether or not to ignore errors
667
	 * @return string|array The specified array (or the contents of said array if there's only one result)
668
	 */
669
	protected function _path($array, $path, $level, $no_error = false)
670
	{
671
		// Is $array even an array?  It might be false!
672
		if (!is_array($array))
673
			return false;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return false; (false) is incompatible with the return type documented by xmlArray::_path of type string|array.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
674
675
		// Asking for *no* path?
676
		if ($path == '' || $path == '.')
677
			return $array;
678
		$paths = explode('|', $path);
679
680
		// A * means all elements of any name.
681
		$show_all = in_array('*', $paths);
682
683
		$results = array();
684
685
		// Check each element.
686
		foreach ($array as $value)
687
		{
688
			if (!is_array($value) || $value['name'] === '!')
689
				continue;
690
691
			if ($show_all || in_array($value['name'], $paths))
692
			{
693
				// Skip elements before "the one".
694
				if ($level !== null && $level > 0)
695
					$level--;
696
				else
697
					$results[] = $value;
698
			}
699
		}
700
701
		// No results found...
702
		if (empty($results))
703
		{
704
			$trace = debug_backtrace();
705
			$i = 0;
706 View Code Duplication
			while ($i < count($trace) && isset($trace[$i]['class']) && $trace[$i]['class'] == get_class($this))
707
				$i++;
708
			$debug = ' from ' . $trace[$i - 1]['file'] . ' on line ' . $trace[$i - 1]['line'];
709
710
			// Cause an error.
711
			if ($this->debug_level & E_NOTICE && !$no_error)
712
				trigger_error('Undefined XML element: ' . $path . $debug, E_USER_NOTICE);
713
			return false;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return false; (false) is incompatible with the return type documented by xmlArray::_path of type string|array.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
714
		}
715
		// Only one result.
716
		elseif (count($results) == 1 || $level !== null)
717
			return $results[0];
718
		// Return the result set.
719
		else
720
			return $results + array('name' => $path . '[]');
721
	}
722
}
723
724
/**
725
 * Class ftp_connection
726
 * Simple FTP protocol implementation.
727
 *
728
 * @see https://tools.ietf.org/html/rfc959
729
 */
730
class ftp_connection
731
{
732
	/**
733
	 * @var string Holds the connection response
734
	 */
735
	public $connection;
736
737
	/**
738
	 * @var string Holds any errors
739
	 */
740
	public $error;
741
742
	/**
743
	 * @var string Holds the last message from the server
744
	 */
745
	public $last_message;
746
747
	/**
748
	 * @var boolean Whether or not this is a passive connection
749
	 */
750
	public $pasv;
751
752
	/**
753
	 * Create a new FTP connection...
754
	 *
755
	 * @param string $ftp_server The server to connect to
756
	 * @param int $ftp_port The port to connect to
757
	 * @param string $ftp_user The username
758
	 * @param string $ftp_pass The password
759
	 */
760
	public function __construct($ftp_server, $ftp_port = 21, $ftp_user = 'anonymous', $ftp_pass = '[email protected]')
761
	{
762
		// Initialize variables.
763
		$this->connection = 'no_connection';
764
		$this->error = false;
0 ignored issues
show
Documentation Bug introduced by
The property $error was declared of type string, but false is of type false. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
765
		$this->pasv = array();
0 ignored issues
show
Documentation Bug introduced by
It seems like array() of type array is incompatible with the declared type boolean of property $pasv.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
766
767
		if ($ftp_server !== null)
768
			$this->connect($ftp_server, $ftp_port, $ftp_user, $ftp_pass);
769
	}
770
771
	/**
772
	 * Connects to a server
773
	 *
774
	 * @param string $ftp_server The address of the server
775
	 * @param int $ftp_port The port
776
	 * @param string $ftp_user The username
777
	 * @param string $ftp_pass The password
778
	 */
779
	public function connect($ftp_server, $ftp_port = 21, $ftp_user = 'anonymous', $ftp_pass = '[email protected]')
780
	{
781 View Code Duplication
		if (strpos($ftp_server, 'ftp://') === 0)
782
			$ftp_server = substr($ftp_server, 6);
783
		elseif (strpos($ftp_server, 'ftps://') === 0)
784
			$ftp_server = 'ssl://' . substr($ftp_server, 7);
785 View Code Duplication
		if (strpos($ftp_server, 'http://') === 0)
786
			$ftp_server = substr($ftp_server, 7);
787
		elseif (strpos($ftp_server, 'https://') === 0)
788
			$ftp_server = substr($ftp_server, 8);
789
		$ftp_server = strtr($ftp_server, array('/' => '', ':' => '', '@' => ''));
790
791
		// Connect to the FTP server.
792
		$this->connection = @fsockopen($ftp_server, $ftp_port, $err, $err, 5);
0 ignored issues
show
Security Header Injection introduced by
$ftp_server can contain request data and is used in request header context(s) leading to a potential security vulnerability.

9 paths for user data to reach this point

  1. Path: Read from $_POST, and $_POST['ftp_server'] is passed to ftp_connection::__construct() in other/install.php on line 600
  1. Read from $_POST, and $_POST['ftp_server'] is passed to ftp_connection::__construct()
    in other/install.php on line 600
  2. $ftp_server is passed to ftp_connection::connect()
    in Sources/Class-Package.php on line 768
  3. $ftp_server is passed through strtr(), and $ftp_server is assigned
    in Sources/Class-Package.php on line 789
  2. Path: Read from $_POST, and $upcontext is assigned in other/upgrade-helper.php on line 175
  1. Read from $_POST, and $upcontext is assigned
    in other/upgrade-helper.php on line 175
  2. $upcontext is assigned
    in other/upgrade-helper.php on line 176
  3. $upcontext is assigned
    in other/upgrade-helper.php on line 177
  4. $upcontext is assigned
    in other/upgrade-helper.php on line 178
  5. $upcontext is assigned
    in other/upgrade-helper.php on line 179
  6. $upcontext['chmod']['server'] is passed to ftp_connection::__construct()
    in other/upgrade-helper.php on line 185
  7. $ftp_server is passed to ftp_connection::connect()
    in Sources/Class-Package.php on line 768
  8. $ftp_server is passed through strtr(), and $ftp_server is assigned
    in Sources/Class-Package.php on line 789
  3. Path: Read from $_POST, and $upcontext is assigned in other/upgrade-helper.php on line 176
  1. Read from $_POST, and $upcontext is assigned
    in other/upgrade-helper.php on line 176
  2. $upcontext is assigned
    in other/upgrade-helper.php on line 177
  3. $upcontext is assigned
    in other/upgrade-helper.php on line 178
  4. $upcontext is assigned
    in other/upgrade-helper.php on line 179
  5. $upcontext['chmod']['server'] is passed to ftp_connection::__construct()
    in other/upgrade-helper.php on line 185
  6. $ftp_server is passed to ftp_connection::connect()
    in Sources/Class-Package.php on line 768
  7. $ftp_server is passed through strtr(), and $ftp_server is assigned
    in Sources/Class-Package.php on line 789
  4. Path: Read from $_POST, and $upcontext is assigned in other/upgrade-helper.php on line 177
  1. Read from $_POST, and $upcontext is assigned
    in other/upgrade-helper.php on line 177
  2. $upcontext is assigned
    in other/upgrade-helper.php on line 178
  3. $upcontext is assigned
    in other/upgrade-helper.php on line 179
  4. $upcontext['chmod']['server'] is passed to ftp_connection::__construct()
    in other/upgrade-helper.php on line 185
  5. $ftp_server is passed to ftp_connection::connect()
    in Sources/Class-Package.php on line 768
  6. $ftp_server is passed through strtr(), and $ftp_server is assigned
    in Sources/Class-Package.php on line 789
  5. Path: Read from $_POST, and $upcontext is assigned in other/upgrade-helper.php on line 178
  1. Read from $_POST, and $upcontext is assigned
    in other/upgrade-helper.php on line 178
  2. $upcontext is assigned
    in other/upgrade-helper.php on line 179
  3. $upcontext['chmod']['server'] is passed to ftp_connection::__construct()
    in other/upgrade-helper.php on line 185
  4. $ftp_server is passed to ftp_connection::connect()
    in Sources/Class-Package.php on line 768
  5. $ftp_server is passed through strtr(), and $ftp_server is assigned
    in Sources/Class-Package.php on line 789
  6. Path: Read from $_POST, and $upcontext is assigned in other/upgrade-helper.php on line 179
  1. Read from $_POST, and $upcontext is assigned
    in other/upgrade-helper.php on line 179
  2. $upcontext['chmod']['server'] is passed to ftp_connection::__construct()
    in other/upgrade-helper.php on line 185
  3. $ftp_server is passed to ftp_connection::connect()
    in Sources/Class-Package.php on line 768
  4. $ftp_server is passed through strtr(), and $ftp_server is assigned
    in Sources/Class-Package.php on line 789
  7. Path: Read from $_POST, and $_POST['ftp_server'] is passed to ftp_connection::__construct() in Sources/PackageGet.php on line 125
  1. Read from $_POST, and $_POST['ftp_server'] is passed to ftp_connection::__construct()
    in Sources/PackageGet.php on line 125
  2. $ftp_server is passed to ftp_connection::connect()
    in Sources/Class-Package.php on line 768
  3. $ftp_server is passed through strtr(), and $ftp_server is assigned
    in Sources/Class-Package.php on line 789
  8. Path: Read from $_POST, and $_POST['ftp_server'] is passed to ftp_connection::__construct() in Sources/Subs-Package.php on line 800
  1. Read from $_POST, and $_POST['ftp_server'] is passed to ftp_connection::__construct()
    in Sources/Subs-Package.php on line 800
  2. $ftp_server is passed to ftp_connection::connect()
    in Sources/Class-Package.php on line 768
  3. $ftp_server is passed through strtr(), and $ftp_server is assigned
    in Sources/Class-Package.php on line 789
  9. Path: Read from $_POST, and $_POST['ftp_server'] is passed to ftp_connection::__construct() in Sources/Subs-Package.php on line 1026
  1. Read from $_POST, and $_POST['ftp_server'] is passed to ftp_connection::__construct()
    in Sources/Subs-Package.php on line 1026
  2. $ftp_server is passed to ftp_connection::connect()
    in Sources/Class-Package.php on line 768
  3. $ftp_server is passed through strtr(), and $ftp_server is assigned
    in Sources/Class-Package.php on line 789

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
793
		if (!$this->connection)
794
		{
795
			$this->error = 'bad_server';
796
            		$this->last_message = 'Invalid Server';
797
			return;
798
		}
799
800
		// Get the welcome message...
801
		if (!$this->check_response(220))
802
		{
803
			$this->error = 'bad_response';
804
		        $this->last_message = 'Bad Response';
805
			return;
806
		}
807
808
		// Send the username, it should ask for a password.
809
		fwrite($this->connection, 'USER ' . $ftp_user . "\r\n");
0 ignored issues
show
Security File Manipulation introduced by
'USER ' . $ftp_user . ' ' can contain request data and is used in file manipulation context(s) leading to a potential security vulnerability.

9 paths for user data to reach this point

  1. Path: Read from $_POST, and $_POST['ftp_username'] is passed to ftp_connection::__construct() in other/install.php on line 600
  1. Read from $_POST, and $_POST['ftp_username'] is passed to ftp_connection::__construct()
    in other/install.php on line 600
  2. $ftp_user is passed to ftp_connection::connect()
    in Sources/Class-Package.php on line 768
  2. Path: Read from $_POST, and $upcontext is assigned in other/upgrade-helper.php on line 175
  1. Read from $_POST, and $upcontext is assigned
    in other/upgrade-helper.php on line 175
  2. $upcontext is assigned
    in other/upgrade-helper.php on line 176
  3. $upcontext is assigned
    in other/upgrade-helper.php on line 177
  4. $upcontext is assigned
    in other/upgrade-helper.php on line 178
  5. $upcontext is assigned
    in other/upgrade-helper.php on line 179
  6. $upcontext['chmod']['username'] is passed to ftp_connection::__construct()
    in other/upgrade-helper.php on line 185
  7. $ftp_user is passed to ftp_connection::connect()
    in Sources/Class-Package.php on line 768
  3. Path: Read from $_POST, and $upcontext is assigned in other/upgrade-helper.php on line 176
  1. Read from $_POST, and $upcontext is assigned
    in other/upgrade-helper.php on line 176
  2. $upcontext is assigned
    in other/upgrade-helper.php on line 177
  3. $upcontext is assigned
    in other/upgrade-helper.php on line 178
  4. $upcontext is assigned
    in other/upgrade-helper.php on line 179
  5. $upcontext['chmod']['username'] is passed to ftp_connection::__construct()
    in other/upgrade-helper.php on line 185
  6. $ftp_user is passed to ftp_connection::connect()
    in Sources/Class-Package.php on line 768
  4. Path: Read from $_POST, and $upcontext is assigned in other/upgrade-helper.php on line 177
  1. Read from $_POST, and $upcontext is assigned
    in other/upgrade-helper.php on line 177
  2. $upcontext is assigned
    in other/upgrade-helper.php on line 178
  3. $upcontext is assigned
    in other/upgrade-helper.php on line 179
  4. $upcontext['chmod']['username'] is passed to ftp_connection::__construct()
    in other/upgrade-helper.php on line 185
  5. $ftp_user is passed to ftp_connection::connect()
    in Sources/Class-Package.php on line 768
  5. Path: Read from $_POST, and $upcontext is assigned in other/upgrade-helper.php on line 178
  1. Read from $_POST, and $upcontext is assigned
    in other/upgrade-helper.php on line 178
  2. $upcontext is assigned
    in other/upgrade-helper.php on line 179
  3. $upcontext['chmod']['username'] is passed to ftp_connection::__construct()
    in other/upgrade-helper.php on line 185
  4. $ftp_user is passed to ftp_connection::connect()
    in Sources/Class-Package.php on line 768
  6. Path: Read from $_POST, and $upcontext is assigned in other/upgrade-helper.php on line 179
  1. Read from $_POST, and $upcontext is assigned
    in other/upgrade-helper.php on line 179
  2. $upcontext['chmod']['username'] is passed to ftp_connection::__construct()
    in other/upgrade-helper.php on line 185
  3. $ftp_user is passed to ftp_connection::connect()
    in Sources/Class-Package.php on line 768
  7. Path: Read from $_POST, and $_POST['ftp_username'] is passed to ftp_connection::__construct() in Sources/PackageGet.php on line 125
  1. Read from $_POST, and $_POST['ftp_username'] is passed to ftp_connection::__construct()
    in Sources/PackageGet.php on line 125
  2. $ftp_user is passed to ftp_connection::connect()
    in Sources/Class-Package.php on line 768
  8. Path: Read from $_POST, and $_POST['ftp_username'] is passed to ftp_connection::__construct() in Sources/Subs-Package.php on line 800
  1. Read from $_POST, and $_POST['ftp_username'] is passed to ftp_connection::__construct()
    in Sources/Subs-Package.php on line 800
  2. $ftp_user is passed to ftp_connection::connect()
    in Sources/Class-Package.php on line 768
  9. Path: Read from $_POST, and $_POST['ftp_username'] is passed to ftp_connection::__construct() in Sources/Subs-Package.php on line 1026
  1. Read from $_POST, and $_POST['ftp_username'] is passed to ftp_connection::__construct()
    in Sources/Subs-Package.php on line 1026
  2. $ftp_user is passed to ftp_connection::connect()
    in Sources/Class-Package.php on line 768

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
810
811
		if (!$this->check_response(331))
812
		{
813
			$this->error = 'bad_username';
814
			$this->last_message = 'Invalid Username';
815
			return;
816
		}
817
818
		// Now send the password... and hope it goes okay.
819
820
		fwrite($this->connection, 'PASS ' . $ftp_pass . "\r\n");
0 ignored issues
show
Security File Manipulation introduced by
'PASS ' . $ftp_pass . ' ' can contain request data and is used in file manipulation context(s) leading to a potential security vulnerability.

9 paths for user data to reach this point

  1. Path: Read from $_POST, and $_POST['ftp_password'] is passed to ftp_connection::__construct() in other/install.php on line 600
  1. Read from $_POST, and $_POST['ftp_password'] is passed to ftp_connection::__construct()
    in other/install.php on line 600
  2. $ftp_pass is passed to ftp_connection::connect()
    in Sources/Class-Package.php on line 768
  2. Path: Read from $_POST, and $upcontext is assigned in other/upgrade-helper.php on line 175
  1. Read from $_POST, and $upcontext is assigned
    in other/upgrade-helper.php on line 175
  2. $upcontext is assigned
    in other/upgrade-helper.php on line 176
  3. $upcontext is assigned
    in other/upgrade-helper.php on line 177
  4. $upcontext is assigned
    in other/upgrade-helper.php on line 178
  5. $upcontext is assigned
    in other/upgrade-helper.php on line 179
  6. $upcontext['chmod']['password'] is passed to ftp_connection::__construct()
    in other/upgrade-helper.php on line 185
  7. $ftp_pass is passed to ftp_connection::connect()
    in Sources/Class-Package.php on line 768
  3. Path: Read from $_POST, and $upcontext is assigned in other/upgrade-helper.php on line 176
  1. Read from $_POST, and $upcontext is assigned
    in other/upgrade-helper.php on line 176
  2. $upcontext is assigned
    in other/upgrade-helper.php on line 177
  3. $upcontext is assigned
    in other/upgrade-helper.php on line 178
  4. $upcontext is assigned
    in other/upgrade-helper.php on line 179
  5. $upcontext['chmod']['password'] is passed to ftp_connection::__construct()
    in other/upgrade-helper.php on line 185
  6. $ftp_pass is passed to ftp_connection::connect()
    in Sources/Class-Package.php on line 768
  4. Path: Read from $_POST, and $upcontext is assigned in other/upgrade-helper.php on line 177
  1. Read from $_POST, and $upcontext is assigned
    in other/upgrade-helper.php on line 177
  2. $upcontext is assigned
    in other/upgrade-helper.php on line 178
  3. $upcontext is assigned
    in other/upgrade-helper.php on line 179
  4. $upcontext['chmod']['password'] is passed to ftp_connection::__construct()
    in other/upgrade-helper.php on line 185
  5. $ftp_pass is passed to ftp_connection::connect()
    in Sources/Class-Package.php on line 768
  5. Path: Read from $_POST, and $upcontext is assigned in other/upgrade-helper.php on line 178
  1. Read from $_POST, and $upcontext is assigned
    in other/upgrade-helper.php on line 178
  2. $upcontext is assigned
    in other/upgrade-helper.php on line 179
  3. $upcontext['chmod']['password'] is passed to ftp_connection::__construct()
    in other/upgrade-helper.php on line 185
  4. $ftp_pass is passed to ftp_connection::connect()
    in Sources/Class-Package.php on line 768
  6. Path: Read from $_POST, and $upcontext is assigned in other/upgrade-helper.php on line 179
  1. Read from $_POST, and $upcontext is assigned
    in other/upgrade-helper.php on line 179
  2. $upcontext['chmod']['password'] is passed to ftp_connection::__construct()
    in other/upgrade-helper.php on line 185
  3. $ftp_pass is passed to ftp_connection::connect()
    in Sources/Class-Package.php on line 768
  7. Path: Read from $_POST, and $_POST['ftp_password'] is passed to ftp_connection::__construct() in Sources/PackageGet.php on line 125
  1. Read from $_POST, and $_POST['ftp_password'] is passed to ftp_connection::__construct()
    in Sources/PackageGet.php on line 125
  2. $ftp_pass is passed to ftp_connection::connect()
    in Sources/Class-Package.php on line 768
  8. Path: Read from $_POST, and $_POST['ftp_password'] is passed to ftp_connection::__construct() in Sources/Subs-Package.php on line 800
  1. Read from $_POST, and $_POST['ftp_password'] is passed to ftp_connection::__construct()
    in Sources/Subs-Package.php on line 800
  2. $ftp_pass is passed to ftp_connection::connect()
    in Sources/Class-Package.php on line 768
  9. Path: Read from $_POST, and $_POST['ftp_password'] is passed to ftp_connection::__construct() in Sources/Subs-Package.php on line 1026
  1. Read from $_POST, and $_POST['ftp_password'] is passed to ftp_connection::__construct()
    in Sources/Subs-Package.php on line 1026
  2. $ftp_pass is passed to ftp_connection::connect()
    in Sources/Class-Package.php on line 768

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
821
		if (!$this->check_response(230))
822
		{
823
			$this->error = 'bad_password';
824
			$this->last_message = 'Invalid Password';
825
			return;
826
		}
827
	}
828
829
	/**
830
	 * Changes to a directory (chdir) via the ftp connection
831
	 *
832
	 * @param string $ftp_path The path to the directory we want to change to
833
	 * @return boolean Whether or not the operation was successful
834
	 */
835
	public function chdir($ftp_path)
836
	{
837
		if (!is_resource($this->connection))
838
			return false;
839
840
		// No slash on the end, please...
841
		if ($ftp_path !== '/' && substr($ftp_path, -1) === '/')
842
			$ftp_path = substr($ftp_path, 0, -1);
843
844
		fwrite($this->connection, 'CWD ' . $ftp_path . "\r\n");
0 ignored issues
show
Security File Manipulation introduced by
'CWD ' . $ftp_path . ' ' can contain request data and is used in file manipulation context(s) leading to a potential security vulnerability.

13 paths for user data to reach this point

  1. Path: Read from $_POST, and $_POST['ftp_path'] is passed to ftp_connection::chdir() in other/install.php on line 605
  1. Read from $_POST, and $_POST['ftp_path'] is passed to ftp_connection::chdir()
    in other/install.php on line 605
  2. $ftp_path is passed through substr(), and $ftp_path is assigned
    in Sources/Class-Package.php on line 842
  2. Path: Read from $_POST, and $_POST['ftp_path'] is passed through preg_replace(), and preg_replace('~^/home[2]?/[^/]+?~', '', $_POST['ftp_path']) is passed to ftp_connection::chdir() in other/install.php on line 608
  1. Read from $_POST, and $_POST['ftp_path'] is passed through preg_replace(), and preg_replace('~^/home[2]?/[^/]+?~', '', $_POST['ftp_path']) is passed to ftp_connection::chdir()
    in other/install.php on line 608
  2. $ftp_path is passed through substr(), and $ftp_path is assigned
    in Sources/Class-Package.php on line 842
  3. Path: Read from $_POST, and $upcontext is assigned in other/upgrade-helper.php on line 175
  1. Read from $_POST, and $upcontext is assigned
    in other/upgrade-helper.php on line 175
  2. $upcontext is assigned
    in other/upgrade-helper.php on line 176
  3. $upcontext is assigned
    in other/upgrade-helper.php on line 177
  4. $upcontext is assigned
    in other/upgrade-helper.php on line 178
  5. $upcontext is assigned
    in other/upgrade-helper.php on line 179
  6. $upcontext['chmod']['path'] is passed to ftp_connection::chdir()
    in other/upgrade-helper.php on line 190
  7. $ftp_path is passed through substr(), and $ftp_path is assigned
    in Sources/Class-Package.php on line 842
  4. Path: Read from $_POST, and $upcontext is assigned in other/upgrade-helper.php on line 176
  1. Read from $_POST, and $upcontext is assigned
    in other/upgrade-helper.php on line 176
  2. $upcontext is assigned
    in other/upgrade-helper.php on line 177
  3. $upcontext is assigned
    in other/upgrade-helper.php on line 178
  4. $upcontext is assigned
    in other/upgrade-helper.php on line 179
  5. $upcontext['chmod']['path'] is passed to ftp_connection::chdir()
    in other/upgrade-helper.php on line 190
  6. $ftp_path is passed through substr(), and $ftp_path is assigned
    in Sources/Class-Package.php on line 842
  5. Path: Read from $_POST, and $upcontext is assigned in other/upgrade-helper.php on line 177
  1. Read from $_POST, and $upcontext is assigned
    in other/upgrade-helper.php on line 177
  2. $upcontext is assigned
    in other/upgrade-helper.php on line 178
  3. $upcontext is assigned
    in other/upgrade-helper.php on line 179
  4. $upcontext['chmod']['path'] is passed to ftp_connection::chdir()
    in other/upgrade-helper.php on line 190
  5. $ftp_path is passed through substr(), and $ftp_path is assigned
    in Sources/Class-Package.php on line 842
  6. Path: Read from $_POST, and $upcontext is assigned in other/upgrade-helper.php on line 178
  1. Read from $_POST, and $upcontext is assigned
    in other/upgrade-helper.php on line 178
  2. $upcontext is assigned
    in other/upgrade-helper.php on line 179
  3. $upcontext['chmod']['path'] is passed to ftp_connection::chdir()
    in other/upgrade-helper.php on line 190
  4. $ftp_path is passed through substr(), and $ftp_path is assigned
    in Sources/Class-Package.php on line 842
  7. Path: Read from $_POST, and $upcontext is assigned in other/upgrade-helper.php on line 179
  1. Read from $_POST, and $upcontext is assigned
    in other/upgrade-helper.php on line 179
  2. $upcontext['chmod']['path'] is passed to ftp_connection::chdir()
    in other/upgrade-helper.php on line 190
  3. $ftp_path is passed through substr(), and $ftp_path is assigned
    in Sources/Class-Package.php on line 842
  8. Path: Read from $_POST, and $_POST['ftp_path'] is passed to ftp_connection::chdir() in Sources/PackageGet.php on line 130
  1. Read from $_POST, and $_POST['ftp_path'] is passed to ftp_connection::chdir()
    in Sources/PackageGet.php on line 130
  2. $ftp_path is passed through substr(), and $ftp_path is assigned
    in Sources/Class-Package.php on line 842
  9. Path: Read from $_POST, and $_POST['ftp_path'] is passed through preg_replace(), and preg_replace('~^/home[2]?/[^/]+?~', '', $_POST['ftp_path']) is passed to ftp_connection::chdir() in Sources/PackageGet.php on line 133
  1. Read from $_POST, and $_POST['ftp_path'] is passed through preg_replace(), and preg_replace('~^/home[2]?/[^/]+?~', '', $_POST['ftp_path']) is passed to ftp_connection::chdir()
    in Sources/PackageGet.php on line 133
  2. $ftp_path is passed through substr(), and $ftp_path is assigned
    in Sources/Class-Package.php on line 842
  10. Path: Read from $_POST, and $_POST['ftp_path'] is passed to ftp_connection::chdir() in Sources/Subs-Package.php on line 806
  1. Read from $_POST, and $_POST['ftp_path'] is passed to ftp_connection::chdir()
    in Sources/Subs-Package.php on line 806
  2. $ftp_path is passed through substr(), and $ftp_path is assigned
    in Sources/Class-Package.php on line 842
  11. Path: Read from $_POST, and $_POST['ftp_path'] is passed through preg_replace(), and preg_replace('~^/home[2]?/[^/]+?~', '', $_POST['ftp_path']) is passed to ftp_connection::chdir() in Sources/Subs-Package.php on line 809
  1. Read from $_POST, and $_POST['ftp_path'] is passed through preg_replace(), and preg_replace('~^/home[2]?/[^/]+?~', '', $_POST['ftp_path']) is passed to ftp_connection::chdir()
    in Sources/Subs-Package.php on line 809
  2. $ftp_path is passed through substr(), and $ftp_path is assigned
    in Sources/Class-Package.php on line 842
  12. Path: Read from $_POST, and $_POST['ftp_path'] is passed to ftp_connection::chdir() in Sources/Subs-Package.php on line 1031
  1. Read from $_POST, and $_POST['ftp_path'] is passed to ftp_connection::chdir()
    in Sources/Subs-Package.php on line 1031
  2. $ftp_path is passed through substr(), and $ftp_path is assigned
    in Sources/Class-Package.php on line 842
  13. Path: Read from $_POST, and $_POST['ftp_path'] is passed through preg_replace(), and preg_replace('~^/home[2]?/[^/]+?~', '', $_POST['ftp_path']) is passed to ftp_connection::chdir() in Sources/Subs-Package.php on line 1034
  1. Read from $_POST, and $_POST['ftp_path'] is passed through preg_replace(), and preg_replace('~^/home[2]?/[^/]+?~', '', $_POST['ftp_path']) is passed to ftp_connection::chdir()
    in Sources/Subs-Package.php on line 1034
  2. $ftp_path is passed through substr(), and $ftp_path is assigned
    in Sources/Class-Package.php on line 842

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
845
		if (!$this->check_response(250))
846
		{
847
			$this->error = 'bad_path';
848
			return false;
849
		}
850
851
		return true;
852
	}
853
854
	/**
855
	 * Changes a files atrributes (chmod)
856
	 *
857
	 * @param string $ftp_file The file to CHMOD
858
	 * @param int|string $chmod The value for the CHMOD operation
859
	 * @return boolean Whether or not the operation was successful
860
	 */
861
	public function chmod($ftp_file, $chmod)
0 ignored issues
show
Unused Code introduced by
The parameter $chmod is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
862
	{
863
		if (!is_resource($this->connection))
864
			return false;
865
866
		if ($ftp_file == '')
867
			$ftp_file = '.';
868
869
		// Do we have a file or a dir?
870
		$is_dir = is_dir($ftp_file);
871
		$is_writable = false;
872
873
		// Set different modes.
874
		$chmod_values = $is_dir ? array(0750, 0755, 0775, 0777) : array(0644, 0664, 0666);
875
876
		foreach ($chmod_values as $val)
877
		{
878
			// If it's writable, break out of the loop.
879
			if (is_writable($ftp_file))
880
			{
881
				$is_writable = true;
882
				break;
883
			}
884
885
			else
886
			{
887
				// Convert the chmod value from octal (0777) to text ("777").
888
				fwrite($this->connection, 'SITE CHMOD ' . decoct($val) . ' ' . $ftp_file . "\r\n");
0 ignored issues
show
Security File Manipulation introduced by
'SITE CHMOD ' . decoct($... ' ' . $ftp_file . ' ' can contain request data and is used in file manipulation context(s) leading to a potential security vulnerability.

18 paths for user data to reach this point

  1. Path: Read from $_GET, and $context is assigned in Sources/ManageLanguages.php on line 792
  1. Read from $_GET, and $context is assigned
    in Sources/ManageLanguages.php on line 792
  2. $context is assigned
    in Sources/ManageLanguages.php on line 797
  3. $images_dirs is assigned
    in Sources/ManageLanguages.php on line 839
  4. $curPath is assigned
    in Sources/ManageLanguages.php on line 912
  5. $curPath is passed to deltree()
    in Sources/ManageLanguages.php on line 914
  6. $dir is passed through strtr(), and $ftp_file is assigned
    in Sources/Subs-Package.php on line 1758
  7. $ftp_file is passed to ftp_connection::chmod()
    in Sources/Subs-Package.php on line 1760
  2. Path: Read from $_GET, and $packagesdir . '/' . $_GET['package'] is passed to deltree() in Sources/Packages.php on line 1339
  1. Read from $_GET, and $packagesdir . '/' . $_GET['package'] is passed to deltree()
    in Sources/Packages.php on line 1339
  2. $dir is passed through strtr(), and $ftp_file is assigned
    in Sources/Subs-Package.php on line 1758
  3. $ftp_file is passed to ftp_connection::chmod()
    in Sources/Subs-Package.php on line 1760
  3. Path: Read from $_REQUEST, and $_REQUEST['file'] is passed to read_tgz_file() in Sources/Packages.php on line 1285
  1. Read from $_REQUEST, and $_REQUEST['file'] is passed to read_tgz_file()
    in Sources/Packages.php on line 1285
  2. $destination is passed to read_tgz_data()
    in Sources/Subs-Package.php on line 35
  3. $destination is passed to mktree()
    in Sources/Subs-Package.php on line 90
  4. $strPath is passed through strtr(), and strtr($strPath, array($_SESSION['pack_ftp']['root'] => '')) is passed to ftp_connection::chmod()
    in Sources/Subs-Package.php on line 1832
  4. Path: Read from $_REQUEST, and $_REQUEST['file'] is passed to read_tgz_file() in Sources/Packages.php on line 1309
  1. Read from $_REQUEST, and $_REQUEST['file'] is passed to read_tgz_file()
    in Sources/Packages.php on line 1309
  2. $destination is passed to read_tgz_data()
    in Sources/Subs-Package.php on line 35
  3. $destination is passed to mktree()
    in Sources/Subs-Package.php on line 90
  4. $strPath is passed through strtr(), and strtr($strPath, array($_SESSION['pack_ftp']['root'] => '')) is passed to ftp_connection::chmod()
    in Sources/Subs-Package.php on line 1832
  5. Path: Read from $_POST, and $context is assigned in Sources/Packages.php on line 2444
  1. Read from $_POST, and $context is assigned
    in Sources/Packages.php on line 2444
  2. $context is assigned
    in Sources/Packages.php on line 2455
  3. $path is assigned
    in Sources/Packages.php on line 2509
  4. $path is passed to package_chmod()
    in Sources/Packages.php on line 2512
  5. $filename is passed through strtr(), and $ftp_file is assigned
    in Sources/Subs-Package.php on line 2917
  6. $ftp_file is passed to ftp_connection::chmod()
    in Sources/Subs-Package.php on line 2926
  6. Path: Read from $_POST, and $status is assigned in Sources/Packages.php on line 2465
  1. Read from $_POST, and $status is assigned
    in Sources/Packages.php on line 2465
  2. $context is assigned
    in Sources/Packages.php on line 2486
  3. $context is assigned
    in Sources/Packages.php on line 2488
  4. $path is assigned
    in Sources/Packages.php on line 2509
  5. $path is passed to package_chmod()
    in Sources/Packages.php on line 2512
  6. $filename is passed through strtr(), and $ftp_file is assigned
    in Sources/Subs-Package.php on line 2917
  7. $ftp_file is passed to ftp_connection::chmod()
    in Sources/Subs-Package.php on line 2926
  7. Path: Read from $_POST, and $context is assigned in Sources/Packages.php on line 2536
  1. Read from $_POST, and $context is assigned
    in Sources/Packages.php on line 2536
  2. $context is assigned
    in Sources/Packages.php on line 2538
  3. $context is assigned
    in Sources/Packages.php on line 2539
  4. $context is assigned
    in Sources/Packages.php on line 2541
  5. $context is assigned
    in Sources/Packages.php on line 2586
  6. $path is assigned
    in Sources/Packages.php on line 2617
  7. $path . '/' . $entry is passed to package_chmod()
    in Sources/Packages.php on line 2630
  8. $filename is passed through strtr(), and $ftp_file is assigned
    in Sources/Subs-Package.php on line 2917
  9. $ftp_file is passed to ftp_connection::chmod()
    in Sources/Subs-Package.php on line 2926
  8. Path: Read from $_POST, and $file is assigned in Sources/ManageLanguages.php on line 223
  1. Read from $_POST, and $file is assigned
    in Sources/ManageLanguages.php on line 223
  2. $chmod_files is assigned
    in Sources/ManageLanguages.php on line 229
  3. $chmod_files is passed to create_chmod_control()
    in Sources/ManageLanguages.php on line 234
  4. $file is assigned
    in Sources/Subs-Package.php on line 842
  5. $file is passed to package_chmod()
    in Sources/Subs-Package.php on line 853
  6. $filename is passed through strtr(), and $ftp_file is assigned
    in Sources/Subs-Package.php on line 2917
  7. $ftp_file is passed to ftp_connection::chmod()
    in Sources/Subs-Package.php on line 2926
  9. Path: Read from $_GET, and $context is assigned in Sources/ManageLanguages.php on line 209
  1. Read from $_GET, and $context is assigned
    in Sources/ManageLanguages.php on line 209
  2. $context is assigned
    in Sources/ManageLanguages.php on line 210
  3. $context is assigned
    in Sources/ManageLanguages.php on line 211
  4. $context is assigned
    in Sources/ManageLanguages.php on line 261
  5. $context is assigned
    in Sources/ManageLanguages.php on line 265
  6. $context['make_writable'] is passed to create_chmod_control()
    in Sources/ManageLanguages.php on line 382
  7. $file is assigned
    in Sources/Subs-Package.php on line 842
  8. $file is passed to package_chmod()
    in Sources/Subs-Package.php on line 853
  9. $filename is passed through strtr(), and $ftp_file is assigned
    in Sources/Subs-Package.php on line 2917
  10. $ftp_file is passed to ftp_connection::chmod()
    in Sources/Subs-Package.php on line 2926
  10. Path: Read from $_GET, and $url is assigned in Sources/PackageGet.php on line 230
  1. Read from $_GET, and $url is assigned
    in Sources/PackageGet.php on line 230
  2. $url . '/' . $package['filename'] is passed to getPackageInfo()
    in Sources/PackageGet.php on line 497
  3. $packagesdir . '/' . $gzfilename . '/package-info.xml' is passed through file_get_contents(), and $packageInfo is assigned
    in Sources/Subs-Package.php on line 542
  4. $packageInfo is passed to xmlArray::__construct()
    in Sources/Subs-Package.php on line 560
  5. xmlArray::$array is assigned
    in Sources/Class-Package.php on line 63
  6. Tainted property xmlArray::$array is read, and $array is assigned
    in Sources/Class-Package.php on line 144
  7. xmlArray::path() returns tainted data, and $array is assigned
    in Sources/Class-Package.php on line 102
  8. xmlArray::fetch() returns tainted data
    in Sources/Subs-Package.php on line 1326
  9. Data is passed through strtr()
    in vendor/Sources/Subs-Package.php on line 1735
  10. $this_action is assigned
    in Sources/Subs-Package.php on line 1326
  11. $this_action['destination'] is passed to mktree()
    in Sources/Subs-Package.php on line 1334
  12. $strPath is passed through strtr(), and strtr($strPath, array($_SESSION['pack_ftp']['root'] => '')) is passed to ftp_connection::chmod()
    in Sources/Subs-Package.php on line 1832
  11. Path: Read from $_GET, and $url is assigned in Sources/PackageGet.php on line 239
  1. Read from $_GET, and $url is assigned
    in Sources/PackageGet.php on line 239
  2. $url . '/' . $package['filename'] is passed to getPackageInfo()
    in Sources/PackageGet.php on line 497
  3. $packagesdir . '/' . $gzfilename . '/package-info.xml' is passed through file_get_contents(), and $packageInfo is assigned
    in Sources/Subs-Package.php on line 542
  4. $packageInfo is passed to xmlArray::__construct()
    in Sources/Subs-Package.php on line 560
  5. xmlArray::$array is assigned
    in Sources/Class-Package.php on line 63
  6. Tainted property xmlArray::$array is read, and $array is assigned
    in Sources/Class-Package.php on line 144
  7. xmlArray::path() returns tainted data, and $array is assigned
    in Sources/Class-Package.php on line 102
  8. xmlArray::fetch() returns tainted data
    in Sources/Subs-Package.php on line 1326
  9. Data is passed through strtr()
    in vendor/Sources/Subs-Package.php on line 1735
  10. $this_action is assigned
    in Sources/Subs-Package.php on line 1326
  11. $this_action['destination'] is passed to mktree()
    in Sources/Subs-Package.php on line 1334
  12. $strPath is passed through strtr(), and strtr($strPath, array($_SESSION['pack_ftp']['root'] => '')) is passed to ftp_connection::chmod()
    in Sources/Subs-Package.php on line 1832
  12. Path: Read from $_GET, and $current_url is assigned in Sources/PackageGet.php on line 358
  1. Read from $_GET, and $current_url is assigned
    in Sources/PackageGet.php on line 358
  2. $package is assigned
    in Sources/PackageGet.php on line 366
  3. $package is assigned
    in Sources/PackageGet.php on line 376
  4. $package is assigned
    in Sources/PackageGet.php on line 377
  5. $package is assigned
    in Sources/PackageGet.php on line 466
  6. $package is assigned
    in Sources/PackageGet.php on line 467
  7. $package is assigned
    in Sources/PackageGet.php on line 468
  8. $package is assigned
    in Sources/PackageGet.php on line 469
  9. $package is assigned
    in Sources/PackageGet.php on line 470
  10. $package is assigned
    in Sources/PackageGet.php on line 473
  11. $context is assigned
    in Sources/PackageGet.php on line 476
  12. $packageSection is assigned
    in Sources/PackageGet.php on line 488
  13. $package is assigned
    in Sources/PackageGet.php on line 490
  14. $url . '/' . $package['filename'] is passed to getPackageInfo()
    in Sources/PackageGet.php on line 497
  15. $packagesdir . '/' . $gzfilename . '/package-info.xml' is passed through file_get_contents(), and $packageInfo is assigned
    in Sources/Subs-Package.php on line 542
  16. $packageInfo is passed to xmlArray::__construct()
    in Sources/Subs-Package.php on line 560
  17. xmlArray::$array is assigned
    in Sources/Class-Package.php on line 63
  18. Tainted property xmlArray::$array is read, and $array is assigned
    in Sources/Class-Package.php on line 144
  19. xmlArray::path() returns tainted data, and $array is assigned
    in Sources/Class-Package.php on line 102
  20. xmlArray::fetch() returns tainted data
    in Sources/Subs-Package.php on line 1326
  21. Data is passed through strtr()
    in vendor/Sources/Subs-Package.php on line 1735
  22. $this_action is assigned
    in Sources/Subs-Package.php on line 1326
  23. $this_action['destination'] is passed to mktree()
    in Sources/Subs-Package.php on line 1334
  24. $strPath is passed through strtr(), and strtr($strPath, array($_SESSION['pack_ftp']['root'] => '')) is passed to ftp_connection::chmod()
    in Sources/Subs-Package.php on line 1832
  13. Path: Read from $_GET, and $current_url is assigned in Sources/PackageGet.php on line 360
  1. Read from $_GET, and $current_url is assigned
    in Sources/PackageGet.php on line 360
  2. $package is assigned
    in Sources/PackageGet.php on line 366
  3. $package is assigned
    in Sources/PackageGet.php on line 376
  4. $package is assigned
    in Sources/PackageGet.php on line 377
  5. $package is assigned
    in Sources/PackageGet.php on line 466
  6. $package is assigned
    in Sources/PackageGet.php on line 467
  7. $package is assigned
    in Sources/PackageGet.php on line 468
  8. $package is assigned
    in Sources/PackageGet.php on line 469
  9. $package is assigned
    in Sources/PackageGet.php on line 470
  10. $package is assigned
    in Sources/PackageGet.php on line 473
  11. $context is assigned
    in Sources/PackageGet.php on line 476
  12. $packageSection is assigned
    in Sources/PackageGet.php on line 488
  13. $package is assigned
    in Sources/PackageGet.php on line 490
  14. $url . '/' . $package['filename'] is passed to getPackageInfo()
    in Sources/PackageGet.php on line 497
  15. $packagesdir . '/' . $gzfilename . '/package-info.xml' is passed through file_get_contents(), and $packageInfo is assigned
    in Sources/Subs-Package.php on line 542
  16. $packageInfo is passed to xmlArray::__construct()
    in Sources/Subs-Package.php on line 560
  17. xmlArray::$array is assigned
    in Sources/Class-Package.php on line 63
  18. Tainted property xmlArray::$array is read, and $array is assigned
    in Sources/Class-Package.php on line 144
  19. xmlArray::path() returns tainted data, and $array is assigned
    in Sources/Class-Package.php on line 102
  20. xmlArray::fetch() returns tainted data
    in Sources/Subs-Package.php on line 1326
  21. Data is passed through strtr()
    in vendor/Sources/Subs-Package.php on line 1735
  22. $this_action is assigned
    in Sources/Subs-Package.php on line 1326
  23. $this_action['destination'] is passed to mktree()
    in Sources/Subs-Package.php on line 1334
  24. $strPath is passed through strtr(), and strtr($strPath, array($_SESSION['pack_ftp']['root'] => '')) is passed to ftp_connection::chmod()
    in Sources/Subs-Package.php on line 1832
  14. Path: Read from $_GET, and $current_url is assigned in Sources/PackageGet.php on line 383
  1. Read from $_GET, and $current_url is assigned
    in Sources/PackageGet.php on line 383
  2. $package is assigned
    in Sources/PackageGet.php on line 421
  3. $package is assigned
    in Sources/PackageGet.php on line 422
  4. $package is assigned
    in Sources/PackageGet.php on line 461
  5. $package is assigned
    in Sources/PackageGet.php on line 462
  6. $package is assigned
    in Sources/PackageGet.php on line 466
  7. $package is assigned
    in Sources/PackageGet.php on line 467
  8. $package is assigned
    in Sources/PackageGet.php on line 468
  9. $package is assigned
    in Sources/PackageGet.php on line 469
  10. $package is assigned
    in Sources/PackageGet.php on line 470
  11. $package is assigned
    in Sources/PackageGet.php on line 473
  12. $context is assigned
    in Sources/PackageGet.php on line 476
  13. $packageSection is assigned
    in Sources/PackageGet.php on line 488
  14. $package is assigned
    in Sources/PackageGet.php on line 490
  15. $url . '/' . $package['filename'] is passed to getPackageInfo()
    in Sources/PackageGet.php on line 497
  16. $packagesdir . '/' . $gzfilename . '/package-info.xml' is passed through file_get_contents(), and $packageInfo is assigned
    in Sources/Subs-Package.php on line 542
  17. $packageInfo is passed to xmlArray::__construct()
    in Sources/Subs-Package.php on line 560
  18. xmlArray::$array is assigned
    in Sources/Class-Package.php on line 63
  19. Tainted property xmlArray::$array is read, and $array is assigned
    in Sources/Class-Package.php on line 144
  20. xmlArray::path() returns tainted data, and $array is assigned
    in Sources/Class-Package.php on line 102
  21. xmlArray::fetch() returns tainted data
    in Sources/Subs-Package.php on line 1326
  22. Data is passed through strtr()
    in vendor/Sources/Subs-Package.php on line 1735
  23. $this_action is assigned
    in Sources/Subs-Package.php on line 1326
  24. $this_action['destination'] is passed to mktree()
    in Sources/Subs-Package.php on line 1334
  25. $strPath is passed through strtr(), and strtr($strPath, array($_SESSION['pack_ftp']['root'] => '')) is passed to ftp_connection::chmod()
    in Sources/Subs-Package.php on line 1832
  15. Path: Read from $_GET, and $current_url is assigned in Sources/PackageGet.php on line 385
  1. Read from $_GET, and $current_url is assigned
    in Sources/PackageGet.php on line 385
  2. $package is assigned
    in Sources/PackageGet.php on line 421
  3. $package is assigned
    in Sources/PackageGet.php on line 422
  4. $package is assigned
    in Sources/PackageGet.php on line 461
  5. $package is assigned
    in Sources/PackageGet.php on line 462
  6. $package is assigned
    in Sources/PackageGet.php on line 466
  7. $package is assigned
    in Sources/PackageGet.php on line 467
  8. $package is assigned
    in Sources/PackageGet.php on line 468
  9. $package is assigned
    in Sources/PackageGet.php on line 469
  10. $package is assigned
    in Sources/PackageGet.php on line 470
  11. $package is assigned
    in Sources/PackageGet.php on line 473
  12. $context is assigned
    in Sources/PackageGet.php on line 476
  13. $packageSection is assigned
    in Sources/PackageGet.php on line 488
  14. $package is assigned
    in Sources/PackageGet.php on line 490
  15. $url . '/' . $package['filename'] is passed to getPackageInfo()
    in Sources/PackageGet.php on line 497
  16. $packagesdir . '/' . $gzfilename . '/package-info.xml' is passed through file_get_contents(), and $packageInfo is assigned
    in Sources/Subs-Package.php on line 542
  17. $packageInfo is passed to xmlArray::__construct()
    in Sources/Subs-Package.php on line 560
  18. xmlArray::$array is assigned
    in Sources/Class-Package.php on line 63
  19. Tainted property xmlArray::$array is read, and $array is assigned
    in Sources/Class-Package.php on line 144
  20. xmlArray::path() returns tainted data, and $array is assigned
    in Sources/Class-Package.php on line 102
  21. xmlArray::fetch() returns tainted data
    in Sources/Subs-Package.php on line 1326
  22. Data is passed through strtr()
    in vendor/Sources/Subs-Package.php on line 1735
  23. $this_action is assigned
    in Sources/Subs-Package.php on line 1326
  24. $this_action['destination'] is passed to mktree()
    in Sources/Subs-Package.php on line 1334
  25. $strPath is passed through strtr(), and strtr($strPath, array($_SESSION['pack_ftp']['root'] => '')) is passed to ftp_connection::chmod()
    in Sources/Subs-Package.php on line 1832
  16. Path: Read from $_FILES, and $_FILES['package']['name'] is passed through strtolower(), and strtolower($_FILES['package']['name']) is passed through strrchr(), and strrchr(strtolower($_FILES['package']['name']), '.') is passed through substr(), and $extension is assigned in Sources/PackageGet.php on line 656
  1. Read from $_FILES, and $_FILES['package']['name'] is passed through strtolower(), and strtolower($_FILES['package']['name']) is passed through strrchr(), and strrchr(strtolower($_FILES['package']['name']), '.') is passed through substr(), and $extension is assigned
    in Sources/PackageGet.php on line 656
  2. $extension is assigned
    in Sources/PackageGet.php on line 663
  3. $packageName is assigned
    in Sources/PackageGet.php on line 664
  4. $packageName is passed to getPackageInfo()
    in Sources/PackageGet.php on line 677
  5. $packagesdir . '/' . $gzfilename . '/package-info.xml' is passed through file_get_contents(), and $packageInfo is assigned
    in Sources/Subs-Package.php on line 542
  6. $packageInfo is passed to xmlArray::__construct()
    in Sources/Subs-Package.php on line 560
  7. xmlArray::$array is assigned
    in Sources/Class-Package.php on line 63
  8. Tainted property xmlArray::$array is read, and $array is assigned
    in Sources/Class-Package.php on line 144
  9. xmlArray::path() returns tainted data, and $array is assigned
    in Sources/Class-Package.php on line 102
  10. xmlArray::fetch() returns tainted data
    in Sources/Subs-Package.php on line 1326
  11. Data is passed through strtr()
    in vendor/Sources/Subs-Package.php on line 1735
  12. $this_action is assigned
    in Sources/Subs-Package.php on line 1326
  13. $this_action['destination'] is passed to mktree()
    in Sources/Subs-Package.php on line 1334
  14. $strPath is passed through strtr(), and strtr($strPath, array($_SESSION['pack_ftp']['root'] => '')) is passed to ftp_connection::chmod()
    in Sources/Subs-Package.php on line 1832
  17. Path: Read from $_REQUEST, and $_REQUEST['package'] is passed through preg_replace(), and $context is assigned in Sources/Packages.php on line 104
  1. Read from $_REQUEST, and $_REQUEST['package'] is passed through preg_replace(), and $context is assigned
    in Sources/Packages.php on line 104
  2. $context is assigned
    in Sources/Packages.php on line 107
  3. $context is assigned
    in Sources/Packages.php on line 132
  4. $context is assigned
    in Sources/Packages.php on line 135
  5. $context is assigned
    in Sources/Packages.php on line 141
  6. $context['filename'] is passed to getPackageInfo()
    in Sources/Packages.php on line 193
  7. $packagesdir . '/' . $gzfilename . '/package-info.xml' is passed through file_get_contents(), and $packageInfo is assigned
    in Sources/Subs-Package.php on line 542
  8. $packageInfo is passed to xmlArray::__construct()
    in Sources/Subs-Package.php on line 560
  9. xmlArray::$array is assigned
    in Sources/Class-Package.php on line 63
  10. Tainted property xmlArray::$array is read, and $array is assigned
    in Sources/Class-Package.php on line 144
  11. xmlArray::path() returns tainted data, and $array is assigned
    in Sources/Class-Package.php on line 102
  12. xmlArray::fetch() returns tainted data
    in Sources/Subs-Package.php on line 1326
  13. Data is passed through strtr()
    in vendor/Sources/Subs-Package.php on line 1735
  14. $this_action is assigned
    in Sources/Subs-Package.php on line 1326
  15. $this_action['destination'] is passed to mktree()
    in Sources/Subs-Package.php on line 1334
  16. $strPath is passed through strtr(), and strtr($strPath, array($_SESSION['pack_ftp']['root'] => '')) is passed to ftp_connection::chmod()
    in Sources/Subs-Package.php on line 1832
  18. Path: Read from $_REQUEST, and $context is assigned in Sources/Packages.php on line 780
  1. Read from $_REQUEST, and $context is assigned
    in Sources/Packages.php on line 780
  2. $context is assigned
    in Sources/Packages.php on line 783
  3. $context is assigned
    in Sources/Packages.php on line 789
  4. $context is assigned
    in Sources/Packages.php on line 792
  5. $context is assigned
    in Sources/Packages.php on line 798
  6. $context is assigned
    in Sources/Packages.php on line 866
  7. $context['filename'] is passed to getPackageInfo()
    in Sources/Packages.php on line 886
  8. $packagesdir . '/' . $gzfilename . '/package-info.xml' is passed through file_get_contents(), and $packageInfo is assigned
    in Sources/Subs-Package.php on line 542
  9. $packageInfo is passed to xmlArray::__construct()
    in Sources/Subs-Package.php on line 560
  10. xmlArray::$array is assigned
    in Sources/Class-Package.php on line 63
  11. Tainted property xmlArray::$array is read, and $array is assigned
    in Sources/Class-Package.php on line 144
  12. xmlArray::path() returns tainted data, and $array is assigned
    in Sources/Class-Package.php on line 102
  13. xmlArray::fetch() returns tainted data
    in Sources/Subs-Package.php on line 1326
  14. Data is passed through strtr()
    in vendor/Sources/Subs-Package.php on line 1735
  15. $this_action is assigned
    in Sources/Subs-Package.php on line 1326
  16. $this_action['destination'] is passed to mktree()
    in Sources/Subs-Package.php on line 1334
  17. $strPath is passed through strtr(), and strtr($strPath, array($_SESSION['pack_ftp']['root'] => '')) is passed to ftp_connection::chmod()
    in Sources/Subs-Package.php on line 1832

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
889
				if (!$this->check_response(200))
890
				{
891
					$this->error = 'bad_file';
892
					break;
893
				}
894
			}
895
		}
896
		return $is_writable;
897
	}
898
899
	/**
900
	 * Deletes a file
901
	 *
902
	 * @param string $ftp_file The file to delete
903
	 * @return boolean Whether or not the operation was successful
904
	 */
905
	public function unlink($ftp_file)
906
	{
907
		// We are actually connected, right?
908
		if (!is_resource($this->connection))
909
			return false;
910
911
		// Delete file X.
912
		fwrite($this->connection, 'DELE ' . $ftp_file . "\r\n");
0 ignored issues
show
Security File Manipulation introduced by
'DELE ' . $ftp_file . ' ' can contain request data and is used in file manipulation context(s) leading to a potential security vulnerability.

2 paths for user data to reach this point

  1. Path: Read from $_GET, and $context is assigned in Sources/ManageLanguages.php on line 792
  1. Read from $_GET, and $context is assigned
    in Sources/ManageLanguages.php on line 792
  2. $context is assigned
    in Sources/ManageLanguages.php on line 797
  3. $images_dirs is assigned
    in Sources/ManageLanguages.php on line 839
  4. $curPath is assigned
    in Sources/ManageLanguages.php on line 912
  5. $curPath is passed to deltree()
    in Sources/ManageLanguages.php on line 914
  6. $dir is passed through strtr(), and $ftp_file is assigned
    in Sources/Subs-Package.php on line 1758
  7. $ftp_file is passed to ftp_connection::unlink()
    in Sources/Subs-Package.php on line 1761
  2. Path: Read from $_GET, and $packagesdir . '/' . $_GET['package'] is passed to deltree() in Sources/Packages.php on line 1339
  1. Read from $_GET, and $packagesdir . '/' . $_GET['package'] is passed to deltree()
    in Sources/Packages.php on line 1339
  2. $dir is passed through strtr(), and $ftp_file is assigned
    in Sources/Subs-Package.php on line 1758
  3. $ftp_file is passed to ftp_connection::unlink()
    in Sources/Subs-Package.php on line 1761

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
913
		if (!$this->check_response(250))
914
		{
915
			fwrite($this->connection, 'RMD ' . $ftp_file . "\r\n");
0 ignored issues
show
Security File Manipulation introduced by
'RMD ' . $ftp_file . ' ' can contain request data and is used in file manipulation context(s) leading to a potential security vulnerability.

2 paths for user data to reach this point

  1. Path: Read from $_GET, and $context is assigned in Sources/ManageLanguages.php on line 792
  1. Read from $_GET, and $context is assigned
    in Sources/ManageLanguages.php on line 792
  2. $context is assigned
    in Sources/ManageLanguages.php on line 797
  3. $images_dirs is assigned
    in Sources/ManageLanguages.php on line 839
  4. $curPath is assigned
    in Sources/ManageLanguages.php on line 912
  5. $curPath is passed to deltree()
    in Sources/ManageLanguages.php on line 914
  6. $dir is passed through strtr(), and $ftp_file is assigned
    in Sources/Subs-Package.php on line 1758
  7. $ftp_file is passed to ftp_connection::unlink()
    in Sources/Subs-Package.php on line 1761
  2. Path: Read from $_GET, and $packagesdir . '/' . $_GET['package'] is passed to deltree() in Sources/Packages.php on line 1339
  1. Read from $_GET, and $packagesdir . '/' . $_GET['package'] is passed to deltree()
    in Sources/Packages.php on line 1339
  2. $dir is passed through strtr(), and $ftp_file is assigned
    in Sources/Subs-Package.php on line 1758
  3. $ftp_file is passed to ftp_connection::unlink()
    in Sources/Subs-Package.php on line 1761

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
916
917
			// Still no love?
918
			if (!$this->check_response(250))
919
			{
920
				$this->error = 'bad_file';
921
				return false;
922
			}
923
		}
924
925
		return true;
926
	}
927
928
	/**
929
	 * Reads the response to the command from the server
930
	 *
931
	 * @param string $desired The desired response
932
	 * @return boolean Whether or not we got the desired response
933
	 */
934
	public function check_response($desired)
935
	{
936
		// Wait for a response that isn't continued with -, but don't wait too long.
937
		$time = time();
938
		do
939
			$this->last_message = fgets($this->connection, 1024);
940
		while ((strlen($this->last_message) < 4 || strpos($this->last_message, ' ') === 0 || strpos($this->last_message, ' ', 3) !== 3) && time() - $time < 5);
941
942
		// Was the desired response returned?
943
		return is_array($desired) ? in_array(substr($this->last_message, 0, 3), $desired) : substr($this->last_message, 0, 3) == $desired;
944
	}
945
946
	/**
947
	 * Used to create a passive connection
948
	 *
949
	 * @return boolean Whether the passive connection was created successfully
950
	 */
951
	public function passive()
952
	{
953
		// We can't create a passive data connection without a primary one first being there.
954
		if (!is_resource($this->connection))
955
			return false;
956
957
		// Request a passive connection - this means, we'll talk to you, you don't talk to us.
958
		@fwrite($this->connection, 'PASV' . "\r\n");
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
959
		$time = time();
960 View Code Duplication
		do
961
			$response = fgets($this->connection, 1024);
962
		while (strpos($response, ' ', 3) !== 3 && time() - $time < 5);
963
964
		// If it's not 227, we weren't given an IP and port, which means it failed.
965
		if (strpos($response, '227 ') !== 0)
966
		{
967
			$this->error = 'bad_response';
968
			return false;
969
		}
970
971
		// Snatch the IP and port information, or die horribly trying...
972
		if (preg_match('~\((\d+),\s*(\d+),\s*(\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+))\)~', $response, $match) == 0)
973
		{
974
			$this->error = 'bad_response';
975
			return false;
976
		}
977
978
		// This is pretty simple - store it for later use ;).
979
		$this->pasv = array('ip' => $match[1] . '.' . $match[2] . '.' . $match[3] . '.' . $match[4], 'port' => $match[5] * 256 + $match[6]);
0 ignored issues
show
Documentation Bug introduced by
It seems like array('ip' => $match[1] ...h[5] * 256 + $match[6]) of type array<string,string|doub...ring","port":"double"}> is incompatible with the declared type boolean of property $pasv.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
980
981
		return true;
982
	}
983
984
	/**
985
	 * Creates a new file on the server
986
	 *
987
	 * @param string $ftp_file The file to create
988
	 * @return boolean Whether or not the file was created successfully
989
	 */
990
	public function create_file($ftp_file)
991
	{
992
		// First, we have to be connected... very important.
993
		if (!is_resource($this->connection))
994
			return false;
995
996
		// I'd like one passive mode, please!
997
		if (!$this->passive())
998
			return false;
999
1000
		// Seems logical enough, so far...
1001
		fwrite($this->connection, 'STOR ' . $ftp_file . "\r\n");
0 ignored issues
show
Security File Manipulation introduced by
'STOR ' . $ftp_file . ' ' can contain request data and is used in file manipulation context(s) leading to a potential security vulnerability.

7 paths for user data to reach this point

  1. Path: Read from $_REQUEST, and $_REQUEST['file'] is passed to read_tgz_file() in Sources/Packages.php on line 1285
  1. Read from $_REQUEST, and $_REQUEST['file'] is passed to read_tgz_file()
    in Sources/Packages.php on line 1285
  2. $destination is passed to read_tgz_data()
    in Sources/Subs-Package.php on line 35
  3. $destination . '/' . $current['filename'] is passed to package_put_contents()
    in Sources/Subs-Package.php on line 208
  4. $filename is passed through strtr(), and $ftp_file is assigned
    in Sources/Subs-Package.php on line 2722
  5. $ftp_file is passed to ftp_connection::create_file()
    in Sources/Subs-Package.php on line 2725
  2. Path: Read from $_REQUEST, and $_REQUEST['file'] is passed to read_tgz_file() in Sources/Packages.php on line 1309
  1. Read from $_REQUEST, and $_REQUEST['file'] is passed to read_tgz_file()
    in Sources/Packages.php on line 1309
  2. $destination is passed to read_tgz_data()
    in Sources/Subs-Package.php on line 35
  3. $destination . '/' . $current['filename'] is passed to package_put_contents()
    in Sources/Subs-Package.php on line 208
  4. $filename is passed through strtr(), and $ftp_file is assigned
    in Sources/Subs-Package.php on line 2722
  5. $ftp_file is passed to ftp_connection::create_file()
    in Sources/Subs-Package.php on line 2725
  3. Path: Read from $_POST, and $context is assigned in Sources/Packages.php on line 2444
  1. Read from $_POST, and $context is assigned
    in Sources/Packages.php on line 2444
  2. $context is assigned
    in Sources/Packages.php on line 2455
  3. $path is assigned
    in Sources/Packages.php on line 2509
  4. $path is passed to package_chmod()
    in Sources/Packages.php on line 2512
  5. $filename is passed through strtr(), and $ftp_file is assigned
    in Sources/Subs-Package.php on line 2917
  6. $ftp_file is passed to ftp_connection::create_file()
    in Sources/Subs-Package.php on line 2925
  4. Path: Read from $_POST, and $status is assigned in Sources/Packages.php on line 2465
  1. Read from $_POST, and $status is assigned
    in Sources/Packages.php on line 2465
  2. $context is assigned
    in Sources/Packages.php on line 2486
  3. $context is assigned
    in Sources/Packages.php on line 2488
  4. $path is assigned
    in Sources/Packages.php on line 2509
  5. $path is passed to package_chmod()
    in Sources/Packages.php on line 2512
  6. $filename is passed through strtr(), and $ftp_file is assigned
    in Sources/Subs-Package.php on line 2917
  7. $ftp_file is passed to ftp_connection::create_file()
    in Sources/Subs-Package.php on line 2925
  5. Path: Read from $_POST, and $context is assigned in Sources/Packages.php on line 2536
  1. Read from $_POST, and $context is assigned
    in Sources/Packages.php on line 2536
  2. $context is assigned
    in Sources/Packages.php on line 2538
  3. $context is assigned
    in Sources/Packages.php on line 2539
  4. $context is assigned
    in Sources/Packages.php on line 2541
  5. $context is assigned
    in Sources/Packages.php on line 2586
  6. $path is assigned
    in Sources/Packages.php on line 2617
  7. $path . '/' . $entry is passed to package_chmod()
    in Sources/Packages.php on line 2630
  8. $filename is passed through strtr(), and $ftp_file is assigned
    in Sources/Subs-Package.php on line 2917
  9. $ftp_file is passed to ftp_connection::create_file()
    in Sources/Subs-Package.php on line 2925
  6. Path: Read from $_POST, and $file is assigned in Sources/ManageLanguages.php on line 223
  1. Read from $_POST, and $file is assigned
    in Sources/ManageLanguages.php on line 223
  2. $chmod_files is assigned
    in Sources/ManageLanguages.php on line 229
  3. $chmod_files is passed to create_chmod_control()
    in Sources/ManageLanguages.php on line 234
  4. $file is assigned
    in Sources/Subs-Package.php on line 842
  5. $file is passed to package_chmod()
    in Sources/Subs-Package.php on line 853
  6. $filename is passed through strtr(), and $ftp_file is assigned
    in Sources/Subs-Package.php on line 2917
  7. $ftp_file is passed to ftp_connection::create_file()
    in Sources/Subs-Package.php on line 2925
  7. Path: Read from $_GET, and $context is assigned in Sources/ManageLanguages.php on line 209
  1. Read from $_GET, and $context is assigned
    in Sources/ManageLanguages.php on line 209
  2. $context is assigned
    in Sources/ManageLanguages.php on line 210
  3. $context is assigned
    in Sources/ManageLanguages.php on line 211
  4. $context is assigned
    in Sources/ManageLanguages.php on line 261
  5. $context is assigned
    in Sources/ManageLanguages.php on line 265
  6. $context['make_writable'] is passed to create_chmod_control()
    in Sources/ManageLanguages.php on line 382
  7. $file is assigned
    in Sources/Subs-Package.php on line 842
  8. $file is passed to package_chmod()
    in Sources/Subs-Package.php on line 853
  9. $filename is passed through strtr(), and $ftp_file is assigned
    in Sources/Subs-Package.php on line 2917
  10. $ftp_file is passed to ftp_connection::create_file()
    in Sources/Subs-Package.php on line 2925

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
1002
1003
		// Okay, now we connect to the data port.  If it doesn't work out, it's probably "file already exists", etc.
1004
		$fp = @fsockopen($this->pasv['ip'], $this->pasv['port'], $err, $err, 5);
1005
		if (!$fp || !$this->check_response(150))
1006
		{
1007
			$this->error = 'bad_file';
1008
			@fclose($fp);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
1009
			return false;
1010
		}
1011
1012
		// This may look strange, but we're just closing it to indicate a zero-byte upload.
1013
		fclose($fp);
1014
		if (!$this->check_response(226))
1015
		{
1016
			$this->error = 'bad_response';
1017
			return false;
1018
		}
1019
1020
		return true;
1021
	}
1022
1023
	/**
1024
	 * Generates a directory listing for the current directory
1025
	 *
1026
	 * @param string $ftp_path The path to the directory
1027
	 * @param bool $search Whether or not to get a recursive directory listing
1028
	 * @return string|boolean The results of the command or false if unsuccessful
1029
	 */
1030
	public function list_dir($ftp_path = '', $search = false)
1031
	{
1032
		// Are we even connected...?
1033
		if (!is_resource($this->connection))
1034
			return false;
1035
1036
		// Passive... non-agressive...
1037
		if (!$this->passive())
1038
			return false;
1039
1040
		// Get the listing!
1041
		fwrite($this->connection, 'LIST -1' . ($search ? 'R' : '') . ($ftp_path == '' ? '' : ' ' . $ftp_path) . "\r\n");
0 ignored issues
show
Security File Manipulation introduced by
'LIST -1' . ($search ? '...' ' . $ftp_path) . ' ' can contain request data and is used in file manipulation context(s) leading to a potential security vulnerability.

1 path for user data to reach this point

  1. Fetching key PHP_SELF from $_SERVER, and $_SERVER['PHP_SELF'] is passed through dirname(), and $path is assigned
    in Sources/Class-Package.php on line 1161
  2. $path is passed to ftp_connection::list_dir()
    in Sources/Class-Package.php on line 1171

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
1042
1043
		// Connect, assuming we've got a connection.
1044
		$fp = @fsockopen($this->pasv['ip'], $this->pasv['port'], $err, $err, 5);
1045
		if (!$fp || !$this->check_response(array(150, 125)))
0 ignored issues
show
Documentation introduced by
array(150, 125) is of type array<integer,integer,{"...nteger","1":"integer"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1046
		{
1047
			$this->error = 'bad_response';
1048
			@fclose($fp);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
1049
			return false;
1050
		}
1051
1052
		// Read in the file listing.
1053
		$data = '';
1054
		while (!feof($fp))
1055
			$data .= fread($fp, 4096);
1056
		fclose($fp);
1057
1058
		// Everything go okay?
1059
		if (!$this->check_response(226))
1060
		{
1061
			$this->error = 'bad_response';
1062
			return false;
1063
		}
1064
1065
		return $data;
1066
	}
1067
1068
	/**
1069
	 * Determines the current directory we are in
1070
	 *
1071
	 * @param string $file The name of a file
1072
	 * @param string $listing A directory listing or null to generate one
1073
	 * @return string|boolean The name of the file or false if it wasn't found
1074
	 */
1075
	public function locate($file, $listing = null)
1076
	{
1077
		if ($listing === null)
1078
			$listing = $this->list_dir('', true);
1079
		$listing = explode("\n", $listing);
1080
1081
		@fwrite($this->connection, 'PWD' . "\r\n");
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
1082
		$time = time();
1083 View Code Duplication
		do
1084
			$response = fgets($this->connection, 1024);
1085
		while ($response[3] != ' ' && time() - $time < 5);
1086
1087
		// Check for 257!
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% 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...
1088
		if (preg_match('~^257 "(.+?)" ~', $response, $match) != 0)
1089
			$current_dir = strtr($match[1], array('""' => '"'));
1090
		else
1091
			$current_dir = '';
1092
1093
		for ($i = 0, $n = count($listing); $i < $n; $i++)
1094
		{
1095
			if (trim($listing[$i]) == '' && isset($listing[$i + 1]))
1096
			{
1097
				$current_dir = substr(trim($listing[++$i]), 0, -1);
1098
				$i++;
1099
			}
1100
1101
			// Okay, this file's name is:
1102
			$listing[$i] = $current_dir . '/' . trim(strlen($listing[$i]) > 30 ? strrchr($listing[$i], ' ') : $listing[$i]);
1103
1104 View Code Duplication
			if ($file[0] == '*' && substr($listing[$i], -(strlen($file) - 1)) == substr($file, 1))
1105
				return $listing[$i];
1106 View Code Duplication
			if (substr($file, -1) == '*' && substr($listing[$i], 0, strlen($file) - 1) == substr($file, 0, -1))
1107
				return $listing[$i];
1108
			if (basename($listing[$i]) == $file || $listing[$i] == $file)
1109
				return $listing[$i];
1110
		}
1111
1112
		return false;
1113
	}
1114
1115
	/**
1116
	 * Creates a new directory on the server
1117
	 *
1118
	 * @param string $ftp_dir The name of the directory to create
1119
	 * @return boolean Whether or not the operation was successful
1120
	 */
1121
	public function create_dir($ftp_dir)
1122
	{
1123
		// We must be connected to the server to do something.
1124
		if (!is_resource($this->connection))
1125
			return false;
1126
1127
		// Make this new beautiful directory!
1128
		fwrite($this->connection, 'MKD ' . $ftp_dir . "\r\n");
0 ignored issues
show
Security File Manipulation introduced by
'MKD ' . $ftp_dir . ' ' can contain request data and is used in file manipulation context(s) leading to a potential security vulnerability.

16 paths for user data to reach this point

  1. Path: Read from $_REQUEST, and $_REQUEST['file'] is passed to read_tgz_file() in Sources/Packages.php on line 1285
  1. Read from $_REQUEST, and $_REQUEST['file'] is passed to read_tgz_file()
    in Sources/Packages.php on line 1285
  2. $destination is passed to read_tgz_data()
    in Sources/Subs-Package.php on line 35
  3. $destination is passed to mktree()
    in Sources/Subs-Package.php on line 90
  4. $strPath is passed through strtr(), and strtr($strPath, array($_SESSION['pack_ftp']['root'] => '')) is passed to ftp_connection::create_dir()
    in Sources/Subs-Package.php on line 1859
  2. Path: Read from $_REQUEST, and $_REQUEST['file'] is passed to read_tgz_file() in Sources/Packages.php on line 1309
  1. Read from $_REQUEST, and $_REQUEST['file'] is passed to read_tgz_file()
    in Sources/Packages.php on line 1309
  2. $destination is passed to read_tgz_data()
    in Sources/Subs-Package.php on line 35
  3. $destination is passed to mktree()
    in Sources/Subs-Package.php on line 90
  4. $strPath is passed through strtr(), and strtr($strPath, array($_SESSION['pack_ftp']['root'] => '')) is passed to ftp_connection::create_dir()
    in Sources/Subs-Package.php on line 1859
  3. Path: Read from $_POST, and $context is assigned in Sources/Packages.php on line 2444
  1. Read from $_POST, and $context is assigned
    in Sources/Packages.php on line 2444
  2. $context is assigned
    in Sources/Packages.php on line 2455
  3. $path is assigned
    in Sources/Packages.php on line 2509
  4. $path is passed to package_chmod()
    in Sources/Packages.php on line 2512
  5. $chmod_file is assigned
    in Sources/Subs-Package.php on line 2843
  6. $chmod_file is passed through dirname(), and dirname($chmod_file) is passed to mktree()
    in Sources/Subs-Package.php on line 2866
  7. $strPath is passed through strtr(), and strtr($strPath, array($_SESSION['pack_ftp']['root'] => '')) is passed to ftp_connection::create_dir()
    in Sources/Subs-Package.php on line 1859
  4. Path: Read from $_POST, and $status is assigned in Sources/Packages.php on line 2465
  1. Read from $_POST, and $status is assigned
    in Sources/Packages.php on line 2465
  2. $context is assigned
    in Sources/Packages.php on line 2486
  3. $context is assigned
    in Sources/Packages.php on line 2488
  4. $path is assigned
    in Sources/Packages.php on line 2509
  5. $path is passed to package_chmod()
    in Sources/Packages.php on line 2512
  6. $chmod_file is assigned
    in Sources/Subs-Package.php on line 2843
  7. $chmod_file is passed through dirname(), and dirname($chmod_file) is passed to mktree()
    in Sources/Subs-Package.php on line 2866
  8. $strPath is passed through strtr(), and strtr($strPath, array($_SESSION['pack_ftp']['root'] => '')) is passed to ftp_connection::create_dir()
    in Sources/Subs-Package.php on line 1859
  5. Path: Read from $_POST, and $context is assigned in Sources/Packages.php on line 2536
  1. Read from $_POST, and $context is assigned
    in Sources/Packages.php on line 2536
  2. $context is assigned
    in Sources/Packages.php on line 2538
  3. $context is assigned
    in Sources/Packages.php on line 2539
  4. $context is assigned
    in Sources/Packages.php on line 2541
  5. $context is assigned
    in Sources/Packages.php on line 2586
  6. $path is assigned
    in Sources/Packages.php on line 2617
  7. $path . '/' . $entry is passed to package_chmod()
    in Sources/Packages.php on line 2630
  8. $chmod_file is assigned
    in Sources/Subs-Package.php on line 2843
  9. $chmod_file is passed through dirname(), and dirname($chmod_file) is passed to mktree()
    in Sources/Subs-Package.php on line 2866
  10. $strPath is passed through strtr(), and strtr($strPath, array($_SESSION['pack_ftp']['root'] => '')) is passed to ftp_connection::create_dir()
    in Sources/Subs-Package.php on line 1859
  6. Path: Read from $_POST, and $file is assigned in Sources/ManageLanguages.php on line 223
  1. Read from $_POST, and $file is assigned
    in Sources/ManageLanguages.php on line 223
  2. $chmod_files is assigned
    in Sources/ManageLanguages.php on line 229
  3. $chmod_files is passed to create_chmod_control()
    in Sources/ManageLanguages.php on line 234
  4. $file is assigned
    in Sources/Subs-Package.php on line 842
  5. $file is passed to package_chmod()
    in Sources/Subs-Package.php on line 853
  6. $chmod_file is assigned
    in Sources/Subs-Package.php on line 2843
  7. $chmod_file is passed through dirname(), and dirname($chmod_file) is passed to mktree()
    in Sources/Subs-Package.php on line 2866
  8. $strPath is passed through strtr(), and strtr($strPath, array($_SESSION['pack_ftp']['root'] => '')) is passed to ftp_connection::create_dir()
    in Sources/Subs-Package.php on line 1859
  7. Path: Read from $_GET, and $context is assigned in Sources/ManageLanguages.php on line 209
  1. Read from $_GET, and $context is assigned
    in Sources/ManageLanguages.php on line 209
  2. $context is assigned
    in Sources/ManageLanguages.php on line 210
  3. $context is assigned
    in Sources/ManageLanguages.php on line 211
  4. $context is assigned
    in Sources/ManageLanguages.php on line 261
  5. $context is assigned
    in Sources/ManageLanguages.php on line 265
  6. $context['make_writable'] is passed to create_chmod_control()
    in Sources/ManageLanguages.php on line 382
  7. $file is assigned
    in Sources/Subs-Package.php on line 842
  8. $file is passed to package_chmod()
    in Sources/Subs-Package.php on line 853
  9. $chmod_file is assigned
    in Sources/Subs-Package.php on line 2843
  10. $chmod_file is passed through dirname(), and dirname($chmod_file) is passed to mktree()
    in Sources/Subs-Package.php on line 2866
  11. $strPath is passed through strtr(), and strtr($strPath, array($_SESSION['pack_ftp']['root'] => '')) is passed to ftp_connection::create_dir()
    in Sources/Subs-Package.php on line 1859
  8. Path: Read from $_GET, and $url is assigned in Sources/PackageGet.php on line 230
  1. Read from $_GET, and $url is assigned
    in Sources/PackageGet.php on line 230
  2. $url . '/' . $package['filename'] is passed to getPackageInfo()
    in Sources/PackageGet.php on line 497
  3. $packagesdir . '/' . $gzfilename . '/package-info.xml' is passed through file_get_contents(), and $packageInfo is assigned
    in Sources/Subs-Package.php on line 542
  4. $packageInfo is passed to xmlArray::__construct()
    in Sources/Subs-Package.php on line 560
  5. xmlArray::$array is assigned
    in Sources/Class-Package.php on line 63
  6. Tainted property xmlArray::$array is read, and $array is assigned
    in Sources/Class-Package.php on line 144
  7. xmlArray::path() returns tainted data, and $array is assigned
    in Sources/Class-Package.php on line 102
  8. xmlArray::fetch() returns tainted data
    in Sources/Subs-Package.php on line 1326
  9. Data is passed through strtr()
    in vendor/Sources/Subs-Package.php on line 1735
  10. $this_action is assigned
    in Sources/Subs-Package.php on line 1326
  11. $this_action['destination'] is passed to mktree()
    in Sources/Subs-Package.php on line 1334
  12. $strPath is passed through strtr(), and strtr($strPath, array($_SESSION['pack_ftp']['root'] => '')) is passed to ftp_connection::create_dir()
    in Sources/Subs-Package.php on line 1859
  9. Path: Read from $_GET, and $url is assigned in Sources/PackageGet.php on line 239
  1. Read from $_GET, and $url is assigned
    in Sources/PackageGet.php on line 239
  2. $url . '/' . $package['filename'] is passed to getPackageInfo()
    in Sources/PackageGet.php on line 497
  3. $packagesdir . '/' . $gzfilename . '/package-info.xml' is passed through file_get_contents(), and $packageInfo is assigned
    in Sources/Subs-Package.php on line 542
  4. $packageInfo is passed to xmlArray::__construct()
    in Sources/Subs-Package.php on line 560
  5. xmlArray::$array is assigned
    in Sources/Class-Package.php on line 63
  6. Tainted property xmlArray::$array is read, and $array is assigned
    in Sources/Class-Package.php on line 144
  7. xmlArray::path() returns tainted data, and $array is assigned
    in Sources/Class-Package.php on line 102
  8. xmlArray::fetch() returns tainted data
    in Sources/Subs-Package.php on line 1326
  9. Data is passed through strtr()
    in vendor/Sources/Subs-Package.php on line 1735
  10. $this_action is assigned
    in Sources/Subs-Package.php on line 1326
  11. $this_action['destination'] is passed to mktree()
    in Sources/Subs-Package.php on line 1334
  12. $strPath is passed through strtr(), and strtr($strPath, array($_SESSION['pack_ftp']['root'] => '')) is passed to ftp_connection::create_dir()
    in Sources/Subs-Package.php on line 1859
  10. Path: Read from $_GET, and $current_url is assigned in Sources/PackageGet.php on line 358
  1. Read from $_GET, and $current_url is assigned
    in Sources/PackageGet.php on line 358
  2. $package is assigned
    in Sources/PackageGet.php on line 366
  3. $package is assigned
    in Sources/PackageGet.php on line 376
  4. $package is assigned
    in Sources/PackageGet.php on line 377
  5. $package is assigned
    in Sources/PackageGet.php on line 466
  6. $package is assigned
    in Sources/PackageGet.php on line 467
  7. $package is assigned
    in Sources/PackageGet.php on line 468
  8. $package is assigned
    in Sources/PackageGet.php on line 469
  9. $package is assigned
    in Sources/PackageGet.php on line 470
  10. $package is assigned
    in Sources/PackageGet.php on line 473
  11. $context is assigned
    in Sources/PackageGet.php on line 476
  12. $packageSection is assigned
    in Sources/PackageGet.php on line 488
  13. $package is assigned
    in Sources/PackageGet.php on line 490
  14. $url . '/' . $package['filename'] is passed to getPackageInfo()
    in Sources/PackageGet.php on line 497
  15. $packagesdir . '/' . $gzfilename . '/package-info.xml' is passed through file_get_contents(), and $packageInfo is assigned
    in Sources/Subs-Package.php on line 542
  16. $packageInfo is passed to xmlArray::__construct()
    in Sources/Subs-Package.php on line 560
  17. xmlArray::$array is assigned
    in Sources/Class-Package.php on line 63
  18. Tainted property xmlArray::$array is read, and $array is assigned
    in Sources/Class-Package.php on line 144
  19. xmlArray::path() returns tainted data, and $array is assigned
    in Sources/Class-Package.php on line 102
  20. xmlArray::fetch() returns tainted data
    in Sources/Subs-Package.php on line 1326
  21. Data is passed through strtr()
    in vendor/Sources/Subs-Package.php on line 1735
  22. $this_action is assigned
    in Sources/Subs-Package.php on line 1326
  23. $this_action['destination'] is passed to mktree()
    in Sources/Subs-Package.php on line 1334
  24. $strPath is passed through strtr(), and strtr($strPath, array($_SESSION['pack_ftp']['root'] => '')) is passed to ftp_connection::create_dir()
    in Sources/Subs-Package.php on line 1859
  11. Path: Read from $_GET, and $current_url is assigned in Sources/PackageGet.php on line 360
  1. Read from $_GET, and $current_url is assigned
    in Sources/PackageGet.php on line 360
  2. $package is assigned
    in Sources/PackageGet.php on line 366
  3. $package is assigned
    in Sources/PackageGet.php on line 376
  4. $package is assigned
    in Sources/PackageGet.php on line 377
  5. $package is assigned
    in Sources/PackageGet.php on line 466
  6. $package is assigned
    in Sources/PackageGet.php on line 467
  7. $package is assigned
    in Sources/PackageGet.php on line 468
  8. $package is assigned
    in Sources/PackageGet.php on line 469
  9. $package is assigned
    in Sources/PackageGet.php on line 470
  10. $package is assigned
    in Sources/PackageGet.php on line 473
  11. $context is assigned
    in Sources/PackageGet.php on line 476
  12. $packageSection is assigned
    in Sources/PackageGet.php on line 488
  13. $package is assigned
    in Sources/PackageGet.php on line 490
  14. $url . '/' . $package['filename'] is passed to getPackageInfo()
    in Sources/PackageGet.php on line 497
  15. $packagesdir . '/' . $gzfilename . '/package-info.xml' is passed through file_get_contents(), and $packageInfo is assigned
    in Sources/Subs-Package.php on line 542
  16. $packageInfo is passed to xmlArray::__construct()
    in Sources/Subs-Package.php on line 560
  17. xmlArray::$array is assigned
    in Sources/Class-Package.php on line 63
  18. Tainted property xmlArray::$array is read, and $array is assigned
    in Sources/Class-Package.php on line 144
  19. xmlArray::path() returns tainted data, and $array is assigned
    in Sources/Class-Package.php on line 102
  20. xmlArray::fetch() returns tainted data
    in Sources/Subs-Package.php on line 1326
  21. Data is passed through strtr()
    in vendor/Sources/Subs-Package.php on line 1735
  22. $this_action is assigned
    in Sources/Subs-Package.php on line 1326
  23. $this_action['destination'] is passed to mktree()
    in Sources/Subs-Package.php on line 1334
  24. $strPath is passed through strtr(), and strtr($strPath, array($_SESSION['pack_ftp']['root'] => '')) is passed to ftp_connection::create_dir()
    in Sources/Subs-Package.php on line 1859
  12. Path: Read from $_GET, and $current_url is assigned in Sources/PackageGet.php on line 383
  1. Read from $_GET, and $current_url is assigned
    in Sources/PackageGet.php on line 383
  2. $package is assigned
    in Sources/PackageGet.php on line 421
  3. $package is assigned
    in Sources/PackageGet.php on line 422
  4. $package is assigned
    in Sources/PackageGet.php on line 461
  5. $package is assigned
    in Sources/PackageGet.php on line 462
  6. $package is assigned
    in Sources/PackageGet.php on line 466
  7. $package is assigned
    in Sources/PackageGet.php on line 467
  8. $package is assigned
    in Sources/PackageGet.php on line 468
  9. $package is assigned
    in Sources/PackageGet.php on line 469
  10. $package is assigned
    in Sources/PackageGet.php on line 470
  11. $package is assigned
    in Sources/PackageGet.php on line 473
  12. $context is assigned
    in Sources/PackageGet.php on line 476
  13. $packageSection is assigned
    in Sources/PackageGet.php on line 488
  14. $package is assigned
    in Sources/PackageGet.php on line 490
  15. $url . '/' . $package['filename'] is passed to getPackageInfo()
    in Sources/PackageGet.php on line 497
  16. $packagesdir . '/' . $gzfilename . '/package-info.xml' is passed through file_get_contents(), and $packageInfo is assigned
    in Sources/Subs-Package.php on line 542
  17. $packageInfo is passed to xmlArray::__construct()
    in Sources/Subs-Package.php on line 560
  18. xmlArray::$array is assigned
    in Sources/Class-Package.php on line 63
  19. Tainted property xmlArray::$array is read, and $array is assigned
    in Sources/Class-Package.php on line 144
  20. xmlArray::path() returns tainted data, and $array is assigned
    in Sources/Class-Package.php on line 102
  21. xmlArray::fetch() returns tainted data
    in Sources/Subs-Package.php on line 1326
  22. Data is passed through strtr()
    in vendor/Sources/Subs-Package.php on line 1735
  23. $this_action is assigned
    in Sources/Subs-Package.php on line 1326
  24. $this_action['destination'] is passed to mktree()
    in Sources/Subs-Package.php on line 1334
  25. $strPath is passed through strtr(), and strtr($strPath, array($_SESSION['pack_ftp']['root'] => '')) is passed to ftp_connection::create_dir()
    in Sources/Subs-Package.php on line 1859
  13. Path: Read from $_GET, and $current_url is assigned in Sources/PackageGet.php on line 385
  1. Read from $_GET, and $current_url is assigned
    in Sources/PackageGet.php on line 385
  2. $package is assigned
    in Sources/PackageGet.php on line 421
  3. $package is assigned
    in Sources/PackageGet.php on line 422
  4. $package is assigned
    in Sources/PackageGet.php on line 461
  5. $package is assigned
    in Sources/PackageGet.php on line 462
  6. $package is assigned
    in Sources/PackageGet.php on line 466
  7. $package is assigned
    in Sources/PackageGet.php on line 467
  8. $package is assigned
    in Sources/PackageGet.php on line 468
  9. $package is assigned
    in Sources/PackageGet.php on line 469
  10. $package is assigned
    in Sources/PackageGet.php on line 470
  11. $package is assigned
    in Sources/PackageGet.php on line 473
  12. $context is assigned
    in Sources/PackageGet.php on line 476
  13. $packageSection is assigned
    in Sources/PackageGet.php on line 488
  14. $package is assigned
    in Sources/PackageGet.php on line 490
  15. $url . '/' . $package['filename'] is passed to getPackageInfo()
    in Sources/PackageGet.php on line 497
  16. $packagesdir . '/' . $gzfilename . '/package-info.xml' is passed through file_get_contents(), and $packageInfo is assigned
    in Sources/Subs-Package.php on line 542
  17. $packageInfo is passed to xmlArray::__construct()
    in Sources/Subs-Package.php on line 560
  18. xmlArray::$array is assigned
    in Sources/Class-Package.php on line 63
  19. Tainted property xmlArray::$array is read, and $array is assigned
    in Sources/Class-Package.php on line 144
  20. xmlArray::path() returns tainted data, and $array is assigned
    in Sources/Class-Package.php on line 102
  21. xmlArray::fetch() returns tainted data
    in Sources/Subs-Package.php on line 1326
  22. Data is passed through strtr()
    in vendor/Sources/Subs-Package.php on line 1735
  23. $this_action is assigned
    in Sources/Subs-Package.php on line 1326
  24. $this_action['destination'] is passed to mktree()
    in Sources/Subs-Package.php on line 1334
  25. $strPath is passed through strtr(), and strtr($strPath, array($_SESSION['pack_ftp']['root'] => '')) is passed to ftp_connection::create_dir()
    in Sources/Subs-Package.php on line 1859
  14. Path: Read from $_FILES, and $_FILES['package']['name'] is passed through strtolower(), and strtolower($_FILES['package']['name']) is passed through strrchr(), and strrchr(strtolower($_FILES['package']['name']), '.') is passed through substr(), and $extension is assigned in Sources/PackageGet.php on line 656
  1. Read from $_FILES, and $_FILES['package']['name'] is passed through strtolower(), and strtolower($_FILES['package']['name']) is passed through strrchr(), and strrchr(strtolower($_FILES['package']['name']), '.') is passed through substr(), and $extension is assigned
    in Sources/PackageGet.php on line 656
  2. $extension is assigned
    in Sources/PackageGet.php on line 663
  3. $packageName is assigned
    in Sources/PackageGet.php on line 664
  4. $packageName is passed to getPackageInfo()
    in Sources/PackageGet.php on line 677
  5. $packagesdir . '/' . $gzfilename . '/package-info.xml' is passed through file_get_contents(), and $packageInfo is assigned
    in Sources/Subs-Package.php on line 542
  6. $packageInfo is passed to xmlArray::__construct()
    in Sources/Subs-Package.php on line 560
  7. xmlArray::$array is assigned
    in Sources/Class-Package.php on line 63
  8. Tainted property xmlArray::$array is read, and $array is assigned
    in Sources/Class-Package.php on line 144
  9. xmlArray::path() returns tainted data, and $array is assigned
    in Sources/Class-Package.php on line 102
  10. xmlArray::fetch() returns tainted data
    in Sources/Subs-Package.php on line 1326
  11. Data is passed through strtr()
    in vendor/Sources/Subs-Package.php on line 1735
  12. $this_action is assigned
    in Sources/Subs-Package.php on line 1326
  13. $this_action['destination'] is passed to mktree()
    in Sources/Subs-Package.php on line 1334
  14. $strPath is passed through strtr(), and strtr($strPath, array($_SESSION['pack_ftp']['root'] => '')) is passed to ftp_connection::create_dir()
    in Sources/Subs-Package.php on line 1859
  15. Path: Read from $_REQUEST, and $_REQUEST['package'] is passed through preg_replace(), and $context is assigned in Sources/Packages.php on line 104
  1. Read from $_REQUEST, and $_REQUEST['package'] is passed through preg_replace(), and $context is assigned
    in Sources/Packages.php on line 104
  2. $context is assigned
    in Sources/Packages.php on line 107
  3. $context is assigned
    in Sources/Packages.php on line 132
  4. $context is assigned
    in Sources/Packages.php on line 135
  5. $context is assigned
    in Sources/Packages.php on line 141
  6. $context['filename'] is passed to getPackageInfo()
    in Sources/Packages.php on line 193
  7. $packagesdir . '/' . $gzfilename . '/package-info.xml' is passed through file_get_contents(), and $packageInfo is assigned
    in Sources/Subs-Package.php on line 542
  8. $packageInfo is passed to xmlArray::__construct()
    in Sources/Subs-Package.php on line 560
  9. xmlArray::$array is assigned
    in Sources/Class-Package.php on line 63
  10. Tainted property xmlArray::$array is read, and $array is assigned
    in Sources/Class-Package.php on line 144
  11. xmlArray::path() returns tainted data, and $array is assigned
    in Sources/Class-Package.php on line 102
  12. xmlArray::fetch() returns tainted data
    in Sources/Subs-Package.php on line 1326
  13. Data is passed through strtr()
    in vendor/Sources/Subs-Package.php on line 1735
  14. $this_action is assigned
    in Sources/Subs-Package.php on line 1326
  15. $this_action['destination'] is passed to mktree()
    in Sources/Subs-Package.php on line 1334
  16. $strPath is passed through strtr(), and strtr($strPath, array($_SESSION['pack_ftp']['root'] => '')) is passed to ftp_connection::create_dir()
    in Sources/Subs-Package.php on line 1859
  16. Path: Read from $_REQUEST, and $context is assigned in Sources/Packages.php on line 780
  1. Read from $_REQUEST, and $context is assigned
    in Sources/Packages.php on line 780
  2. $context is assigned
    in Sources/Packages.php on line 783
  3. $context is assigned
    in Sources/Packages.php on line 789
  4. $context is assigned
    in Sources/Packages.php on line 792
  5. $context is assigned
    in Sources/Packages.php on line 798
  6. $context is assigned
    in Sources/Packages.php on line 866
  7. $context['filename'] is passed to getPackageInfo()
    in Sources/Packages.php on line 886
  8. $packagesdir . '/' . $gzfilename . '/package-info.xml' is passed through file_get_contents(), and $packageInfo is assigned
    in Sources/Subs-Package.php on line 542
  9. $packageInfo is passed to xmlArray::__construct()
    in Sources/Subs-Package.php on line 560
  10. xmlArray::$array is assigned
    in Sources/Class-Package.php on line 63
  11. Tainted property xmlArray::$array is read, and $array is assigned
    in Sources/Class-Package.php on line 144
  12. xmlArray::path() returns tainted data, and $array is assigned
    in Sources/Class-Package.php on line 102
  13. xmlArray::fetch() returns tainted data
    in Sources/Subs-Package.php on line 1326
  14. Data is passed through strtr()
    in vendor/Sources/Subs-Package.php on line 1735
  15. $this_action is assigned
    in Sources/Subs-Package.php on line 1326
  16. $this_action['destination'] is passed to mktree()
    in Sources/Subs-Package.php on line 1334
  17. $strPath is passed through strtr(), and strtr($strPath, array($_SESSION['pack_ftp']['root'] => '')) is passed to ftp_connection::create_dir()
    in Sources/Subs-Package.php on line 1859

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
1129
		if (!$this->check_response(257))
1130
		{
1131
			$this->error = 'bad_file';
1132
			return false;
1133
		}
1134
1135
		return true;
1136
	}
1137
1138
	/**
1139
	 * Detects the current path
1140
	 *
1141
	 * @param string $filesystem_path The full path from the filesystem
1142
	 * @param string $lookup_file The name of a file in the specified path
1143
	 * @return array An array of detected info - username, path from FTP root and whether or not the current path was found
1144
	 */
1145
	public function detect_path($filesystem_path, $lookup_file = null)
1146
	{
1147
		$username = '';
1148
1149
		if (isset($_SERVER['DOCUMENT_ROOT']))
1150
		{
1151
			if (preg_match('~^/home[2]?/([^/]+?)/public_html~', $_SERVER['DOCUMENT_ROOT'], $match))
1152
			{
1153
				$username = $match[1];
1154
1155
				$path = strtr($_SERVER['DOCUMENT_ROOT'], array('/home/' . $match[1] . '/' => '', '/home2/' . $match[1] . '/' => ''));
1156
1157 View Code Duplication
				if (substr($path, -1) == '/')
1158
					$path = substr($path, 0, -1);
1159
1160
				if (strlen(dirname($_SERVER['PHP_SELF'])) > 1)
1161
					$path .= dirname($_SERVER['PHP_SELF']);
1162
			}
1163
			elseif (strpos($filesystem_path, '/var/www/') === 0)
1164
				$path = substr($filesystem_path, 8);
1165
			else
1166
				$path = strtr(strtr($filesystem_path, array('\\' => '/')), array($_SERVER['DOCUMENT_ROOT'] => ''));
1167
		}
1168
		else
1169
			$path = '';
1170
1171
		if (is_resource($this->connection) && $this->list_dir($path) == '')
1172
		{
1173
			$data = $this->list_dir('', true);
1174
1175
			if ($lookup_file === null)
1176
				$lookup_file = $_SERVER['PHP_SELF'];
1177
1178
			$found_path = dirname($this->locate('*' . basename(dirname($lookup_file)) . '/' . basename($lookup_file), $data));
0 ignored issues
show
Security Bug introduced by
It seems like $data defined by $this->list_dir('', true) on line 1173 can also be of type false; however, ftp_connection::locate() does only seem to accept string|null, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
1179
			if ($found_path == false)
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing $found_path of type string to the boolean false. If you are specifically checking for an empty string, consider using the more explicit === '' instead.
Loading history...
1180
				$found_path = dirname($this->locate(basename($lookup_file)));
1181
			if ($found_path != false)
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing $found_path of type string to the boolean false. If you are specifically checking for a non-empty string, consider using the more explicit !== '' instead.
Loading history...
1182
				$path = $found_path;
1183
		}
1184
		elseif (is_resource($this->connection))
1185
			$found_path = true;
1186
1187
		return array($username, $path, isset($found_path));
1188
	}
1189
1190
	/**
1191
	 * Close the ftp connection
1192
	 *
1193
	 * @return boolean Always returns true
1194
	 */
1195
	public function close()
1196
	{
1197
		// Goodbye!
1198
		fwrite($this->connection, 'QUIT' . "\r\n");
1199
		fclose($this->connection);
1200
1201
		return true;
1202
	}
1203
}
1204
1205
?>
0 ignored issues
show
Best Practice introduced by
It is not recommended to use PHP's closing tag ?> in files other than templates.

Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore.

A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever.

Loading history...