These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
|||||||||||
0 ignored issues
–
show
|
||||||||||||
2 | /** |
|||||||||||
3 | * CodeIgniter |
|||||||||||
4 | * |
|||||||||||
5 | * An open source application development framework for PHP |
|||||||||||
6 | * |
|||||||||||
7 | * This content is released under the MIT License (MIT) |
|||||||||||
8 | * |
|||||||||||
9 | * Copyright (c) 2014 - 2018, British Columbia Institute of Technology |
|||||||||||
10 | * |
|||||||||||
11 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
|||||||||||
12 | * of this software and associated documentation files (the "Software"), to deal |
|||||||||||
13 | * in the Software without restriction, including without limitation the rights |
|||||||||||
14 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|||||||||||
15 | * copies of the Software, and to permit persons to whom the Software is |
|||||||||||
16 | * furnished to do so, subject to the following conditions: |
|||||||||||
17 | * |
|||||||||||
18 | * The above copyright notice and this permission notice shall be included in |
|||||||||||
19 | * all copies or substantial portions of the Software. |
|||||||||||
20 | * |
|||||||||||
21 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||||||||||
22 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||||||||||
23 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|||||||||||
24 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||||||||||
25 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|||||||||||
26 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|||||||||||
27 | * THE SOFTWARE. |
|||||||||||
28 | * |
|||||||||||
29 | * @package CodeIgniter |
|||||||||||
30 | * @author EllisLab Dev Team |
|||||||||||
31 | * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) |
|||||||||||
32 | * @copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/) |
|||||||||||
33 | * @license http://opensource.org/licenses/MIT MIT License |
|||||||||||
34 | * @link https://codeigniter.com |
|||||||||||
35 | * @since Version 1.0.0 |
|||||||||||
36 | * @filesource |
|||||||||||
37 | */ |
|||||||||||
38 | defined('BASEPATH') OR exit('No direct script access allowed'); |
|||||||||||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
Using logical operators such as
or instead of || is generally not recommended.
PHP has two types of connecting operators (logical operators, and boolean operators):
The difference between these is the order in which they are executed. In most cases,
you would want to use a boolean operator like Let’s take a look at a few examples: // Logical operators have lower precedence:
$f = false or true;
// is executed like this:
($f = false) or true;
// Boolean operators have higher precedence:
$f = false || true;
// is executed like this:
$f = (false || true);
Logical Operators are used for Control-FlowOne case where you explicitly want to use logical operators is for control-flow such as this: $x === 5
or die('$x must be 5.');
// Instead of
if ($x !== 5) {
die('$x must be 5.');
}
Since // The following is currently a parse error.
$x === 5
or throw new RuntimeException('$x must be 5.');
These limitations lead to logical operators rarely being of use in current PHP code.
Loading history...
|
||||||||||||
39 | ||||||||||||
40 | /** |
|||||||||||
41 | * File Uploading Class (Modified by ci-phpunit-test) |
|||||||||||
42 | * |
|||||||||||
43 | * @package CodeIgniter |
|||||||||||
44 | * @subpackage Libraries |
|||||||||||
45 | * @category Uploads |
|||||||||||
46 | * @author EllisLab Dev Team |
|||||||||||
47 | * @link https://codeigniter.com/user_guide/libraries/file_uploading.html |
|||||||||||
48 | */ |
|||||||||||
49 | View Code Duplication | class CI_Upload { |
||||||||||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
The type
CI_Upload has been defined more than once; this definition is ignored, only the first definition in application/tests/_ci_ph...es/old/3.1.2-Upload.php (L49-1360) is considered.
This check looks for classes that have been defined more than once. If you can, we would recommend to use standard object-oriented programming techniques. For example, to avoid multiple types, it might make sense to create a common interface, and then multiple, different implementations for that interface. This also has the side-effect of providing you with better IDE auto-completion, static analysis and also better OPCode caching from PHP.
Loading history...
This class seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.
You can fix this by adding a namespace to your class: namespace YourVendor;
class YourClass { }
When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.
Loading history...
|
||||||||||||
50 | ||||||||||||
51 | /** |
|||||||||||
52 | * Maximum file size |
|||||||||||
53 | * |
|||||||||||
54 | * @var int |
|||||||||||
55 | */ |
|||||||||||
56 | public $max_size = 0; |
|||||||||||
57 | ||||||||||||
58 | /** |
|||||||||||
59 | * Maximum image width |
|||||||||||
60 | * |
|||||||||||
61 | * @var int |
|||||||||||
62 | */ |
|||||||||||
63 | public $max_width = 0; |
|||||||||||
64 | ||||||||||||
65 | /** |
|||||||||||
66 | * Maximum image height |
|||||||||||
67 | * |
|||||||||||
68 | * @var int |
|||||||||||
69 | */ |
|||||||||||
70 | public $max_height = 0; |
|||||||||||
71 | ||||||||||||
72 | /** |
|||||||||||
73 | * Minimum image width |
|||||||||||
74 | * |
|||||||||||
75 | * @var int |
|||||||||||
76 | */ |
|||||||||||
77 | public $min_width = 0; |
|||||||||||
78 | ||||||||||||
79 | /** |
|||||||||||
80 | * Minimum image height |
|||||||||||
81 | * |
|||||||||||
82 | * @var int |
|||||||||||
83 | */ |
|||||||||||
84 | public $min_height = 0; |
|||||||||||
85 | ||||||||||||
86 | /** |
|||||||||||
87 | * Maximum filename length |
|||||||||||
88 | * |
|||||||||||
89 | * @var int |
|||||||||||
90 | */ |
|||||||||||
91 | public $max_filename = 0; |
|||||||||||
92 | ||||||||||||
93 | /** |
|||||||||||
94 | * Maximum duplicate filename increment ID |
|||||||||||
95 | * |
|||||||||||
96 | * @var int |
|||||||||||
97 | */ |
|||||||||||
98 | public $max_filename_increment = 100; |
|||||||||||
99 | ||||||||||||
100 | /** |
|||||||||||
101 | * Allowed file types |
|||||||||||
102 | * |
|||||||||||
103 | * @var string |
|||||||||||
104 | */ |
|||||||||||
105 | public $allowed_types = ''; |
|||||||||||
106 | ||||||||||||
107 | /** |
|||||||||||
108 | * Temporary filename |
|||||||||||
109 | * |
|||||||||||
110 | * @var string |
|||||||||||
111 | */ |
|||||||||||
112 | public $file_temp = ''; |
|||||||||||
113 | ||||||||||||
114 | /** |
|||||||||||
115 | * Filename |
|||||||||||
116 | * |
|||||||||||
117 | * @var string |
|||||||||||
118 | */ |
|||||||||||
119 | public $file_name = ''; |
|||||||||||
120 | ||||||||||||
121 | /** |
|||||||||||
122 | * Original filename |
|||||||||||
123 | * |
|||||||||||
124 | * @var string |
|||||||||||
125 | */ |
|||||||||||
126 | public $orig_name = ''; |
|||||||||||
127 | ||||||||||||
128 | /** |
|||||||||||
129 | * File type |
|||||||||||
130 | * |
|||||||||||
131 | * @var string |
|||||||||||
132 | */ |
|||||||||||
133 | public $file_type = ''; |
|||||||||||
134 | ||||||||||||
135 | /** |
|||||||||||
136 | * File size |
|||||||||||
137 | * |
|||||||||||
138 | * @var int |
|||||||||||
139 | */ |
|||||||||||
140 | public $file_size = NULL; |
|||||||||||
141 | ||||||||||||
142 | /** |
|||||||||||
143 | * Filename extension |
|||||||||||
144 | * |
|||||||||||
145 | * @var string |
|||||||||||
146 | */ |
|||||||||||
147 | public $file_ext = ''; |
|||||||||||
148 | ||||||||||||
149 | /** |
|||||||||||
150 | * Force filename extension to lowercase |
|||||||||||
151 | * |
|||||||||||
152 | * @var string |
|||||||||||
153 | */ |
|||||||||||
154 | public $file_ext_tolower = FALSE; |
|||||||||||
155 | ||||||||||||
156 | /** |
|||||||||||
157 | * Upload path |
|||||||||||
158 | * |
|||||||||||
159 | * @var string |
|||||||||||
160 | */ |
|||||||||||
161 | public $upload_path = ''; |
|||||||||||
162 | ||||||||||||
163 | /** |
|||||||||||
164 | * Overwrite flag |
|||||||||||
165 | * |
|||||||||||
166 | * @var bool |
|||||||||||
167 | */ |
|||||||||||
168 | public $overwrite = FALSE; |
|||||||||||
169 | ||||||||||||
170 | /** |
|||||||||||
171 | * Obfuscate filename flag |
|||||||||||
172 | * |
|||||||||||
173 | * @var bool |
|||||||||||
174 | */ |
|||||||||||
175 | public $encrypt_name = FALSE; |
|||||||||||
176 | ||||||||||||
177 | /** |
|||||||||||
178 | * Is image flag |
|||||||||||
179 | * |
|||||||||||
180 | * @var bool |
|||||||||||
181 | */ |
|||||||||||
182 | public $is_image = FALSE; |
|||||||||||
183 | ||||||||||||
184 | /** |
|||||||||||
185 | * Image width |
|||||||||||
186 | * |
|||||||||||
187 | * @var int |
|||||||||||
188 | */ |
|||||||||||
189 | public $image_width = NULL; |
|||||||||||
190 | ||||||||||||
191 | /** |
|||||||||||
192 | * Image height |
|||||||||||
193 | * |
|||||||||||
194 | * @var int |
|||||||||||
195 | */ |
|||||||||||
196 | public $image_height = NULL; |
|||||||||||
197 | ||||||||||||
198 | /** |
|||||||||||
199 | * Image type |
|||||||||||
200 | * |
|||||||||||
201 | * @var string |
|||||||||||
202 | */ |
|||||||||||
203 | public $image_type = ''; |
|||||||||||
204 | ||||||||||||
205 | /** |
|||||||||||
206 | * Image size string |
|||||||||||
207 | * |
|||||||||||
208 | * @var string |
|||||||||||
209 | */ |
|||||||||||
210 | public $image_size_str = ''; |
|||||||||||
211 | ||||||||||||
212 | /** |
|||||||||||
213 | * Error messages list |
|||||||||||
214 | * |
|||||||||||
215 | * @var array |
|||||||||||
216 | */ |
|||||||||||
217 | public $error_msg = array(); |
|||||||||||
218 | ||||||||||||
219 | /** |
|||||||||||
220 | * Remove spaces flag |
|||||||||||
221 | * |
|||||||||||
222 | * @var bool |
|||||||||||
223 | */ |
|||||||||||
224 | public $remove_spaces = TRUE; |
|||||||||||
225 | ||||||||||||
226 | /** |
|||||||||||
227 | * MIME detection flag |
|||||||||||
228 | * |
|||||||||||
229 | * @var bool |
|||||||||||
230 | */ |
|||||||||||
231 | public $detect_mime = TRUE; |
|||||||||||
232 | ||||||||||||
233 | /** |
|||||||||||
234 | * XSS filter flag |
|||||||||||
235 | * |
|||||||||||
236 | * @var bool |
|||||||||||
237 | */ |
|||||||||||
238 | public $xss_clean = FALSE; |
|||||||||||
239 | ||||||||||||
240 | /** |
|||||||||||
241 | * Apache mod_mime fix flag |
|||||||||||
242 | * |
|||||||||||
243 | * @var bool |
|||||||||||
244 | */ |
|||||||||||
245 | public $mod_mime_fix = TRUE; |
|||||||||||
246 | ||||||||||||
247 | /** |
|||||||||||
248 | * Temporary filename prefix |
|||||||||||
249 | * |
|||||||||||
250 | * @var string |
|||||||||||
251 | */ |
|||||||||||
252 | public $temp_prefix = 'temp_file_'; |
|||||||||||
253 | ||||||||||||
254 | /** |
|||||||||||
255 | * Filename sent by the client |
|||||||||||
256 | * |
|||||||||||
257 | * @var bool |
|||||||||||
258 | */ |
|||||||||||
259 | public $client_name = ''; |
|||||||||||
260 | ||||||||||||
261 | // -------------------------------------------------------------------- |
|||||||||||
262 | ||||||||||||
263 | /** |
|||||||||||
264 | * Filename override |
|||||||||||
265 | * |
|||||||||||
266 | * @var string |
|||||||||||
267 | */ |
|||||||||||
268 | protected $_file_name_override = ''; |
|||||||||||
269 | ||||||||||||
270 | /** |
|||||||||||
271 | * MIME types list |
|||||||||||
272 | * |
|||||||||||
273 | * @var array |
|||||||||||
274 | */ |
|||||||||||
275 | protected $_mimes = array(); |
|||||||||||
276 | ||||||||||||
277 | /** |
|||||||||||
278 | * CI Singleton |
|||||||||||
279 | * |
|||||||||||
280 | * @var object |
|||||||||||
281 | */ |
|||||||||||
282 | protected $_CI; |
|||||||||||
283 | ||||||||||||
284 | // -------------------------------------------------------------------- |
|||||||||||
285 | ||||||||||||
286 | /** |
|||||||||||
287 | * Constructor |
|||||||||||
288 | * |
|||||||||||
289 | * @param array $config |
|||||||||||
290 | * @return void |
|||||||||||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
Adding a
@return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.
Adding a Please refer to the PHP core documentation on constructors.
Loading history...
|
||||||||||||
291 | * |
|||||||||||
292 | * @codeCoverageIgnore |
|||||||||||
293 | */ |
|||||||||||
294 | public function __construct($config = array()) |
|||||||||||
295 | { |
|||||||||||
296 | empty($config) OR $this->initialize($config, FALSE); |
|||||||||||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
Using logical operators such as
or instead of || is generally not recommended.
PHP has two types of connecting operators (logical operators, and boolean operators):
The difference between these is the order in which they are executed. In most cases,
you would want to use a boolean operator like Let’s take a look at a few examples: // Logical operators have lower precedence:
$f = false or true;
// is executed like this:
($f = false) or true;
// Boolean operators have higher precedence:
$f = false || true;
// is executed like this:
$f = (false || true);
Logical Operators are used for Control-FlowOne case where you explicitly want to use logical operators is for control-flow such as this: $x === 5
or die('$x must be 5.');
// Instead of
if ($x !== 5) {
die('$x must be 5.');
}
Since // The following is currently a parse error.
$x === 5
or throw new RuntimeException('$x must be 5.');
These limitations lead to logical operators rarely being of use in current PHP code.
Loading history...
|
||||||||||||
297 | ||||||||||||
298 | $this->_mimes =& get_mimes(); |
|||||||||||
299 | $this->_CI =& get_instance(); |
|||||||||||
300 | ||||||||||||
301 | log_message('info', 'Upload Class Initialized'); |
|||||||||||
302 | } |
|||||||||||
303 | ||||||||||||
304 | // -------------------------------------------------------------------- |
|||||||||||
305 | ||||||||||||
306 | /** |
|||||||||||
307 | * Initialize preferences |
|||||||||||
308 | * |
|||||||||||
309 | * @param array $config |
|||||||||||
310 | * @param bool $reset |
|||||||||||
311 | * @return CI_Upload |
|||||||||||
312 | * |
|||||||||||
313 | * @codeCoverageIgnore |
|||||||||||
314 | */ |
|||||||||||
315 | public function initialize(array $config = array(), $reset = TRUE) |
|||||||||||
316 | { |
|||||||||||
317 | $reflection = new ReflectionClass($this); |
|||||||||||
318 | ||||||||||||
319 | if ($reset === TRUE) |
|||||||||||
320 | { |
|||||||||||
321 | $defaults = $reflection->getDefaultProperties(); |
|||||||||||
322 | foreach (array_keys($defaults) as $key) |
|||||||||||
323 | { |
|||||||||||
324 | if ($key[0] === '_') |
|||||||||||
325 | { |
|||||||||||
326 | continue; |
|||||||||||
327 | } |
|||||||||||
328 | ||||||||||||
329 | if (isset($config[$key])) |
|||||||||||
330 | { |
|||||||||||
331 | if ($reflection->hasMethod('set_'.$key)) |
|||||||||||
332 | { |
|||||||||||
333 | $this->{'set_'.$key}($config[$key]); |
|||||||||||
334 | } |
|||||||||||
335 | else |
|||||||||||
336 | { |
|||||||||||
337 | $this->$key = $config[$key]; |
|||||||||||
338 | } |
|||||||||||
339 | } |
|||||||||||
340 | else |
|||||||||||
341 | { |
|||||||||||
342 | $this->$key = $defaults[$key]; |
|||||||||||
343 | } |
|||||||||||
344 | } |
|||||||||||
345 | } |
|||||||||||
346 | else |
|||||||||||
347 | { |
|||||||||||
348 | foreach ($config as $key => &$value) |
|||||||||||
349 | { |
|||||||||||
350 | if ($key[0] !== '_' && $reflection->hasProperty($key)) |
|||||||||||
351 | { |
|||||||||||
352 | if ($reflection->hasMethod('set_'.$key)) |
|||||||||||
353 | { |
|||||||||||
354 | $this->{'set_'.$key}($value); |
|||||||||||
355 | } |
|||||||||||
356 | else |
|||||||||||
357 | { |
|||||||||||
358 | $this->$key = $value; |
|||||||||||
359 | } |
|||||||||||
360 | } |
|||||||||||
361 | } |
|||||||||||
362 | } |
|||||||||||
363 | ||||||||||||
364 | // if a file_name was provided in the config, use it instead of the user input |
|||||||||||
365 | // supplied file name for all uploads until initialized again |
|||||||||||
366 | $this->_file_name_override = $this->file_name; |
|||||||||||
367 | return $this; |
|||||||||||
368 | } |
|||||||||||
369 | ||||||||||||
370 | // -------------------------------------------------------------------- |
|||||||||||
371 | ||||||||||||
372 | /** |
|||||||||||
373 | * Perform the file upload |
|||||||||||
374 | * |
|||||||||||
375 | * @param string $field |
|||||||||||
376 | * @return bool |
|||||||||||
377 | * |
|||||||||||
378 | * modified by ci-phpunit-test |
|||||||||||
379 | */ |
|||||||||||
380 | public function do_upload($field = 'userfile') |
|||||||||||
0 ignored issues
–
show
do_upload uses the super-global variable $_FILES which is generally not recommended.
Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable: // Bad
class Router
{
public function generate($path)
{
return $_SERVER['HOST'].$path;
}
}
// Better
class Router
{
private $host;
public function __construct($host)
{
$this->host = $host;
}
public function generate($path)
{
return $this->host.$path;
}
}
class Controller
{
public function myAction(Request $request)
{
// Instead of
$page = isset($_GET['page']) ? intval($_GET['page']) : 1;
// Better (assuming you use the Symfony2 request)
$page = $request->query->get('page', 1);
}
}
Loading history...
|
||||||||||||
381 | { |
|||||||||||
382 | // Is $_FILES[$field] set? If not, no reason to continue. |
|||||||||||
383 | if (isset($_FILES[$field])) |
|||||||||||
384 | { |
|||||||||||
385 | $_file = $_FILES[$field]; |
|||||||||||
386 | } |
|||||||||||
387 | // Does the field name contain array notation? |
|||||||||||
388 | elseif (($c = preg_match_all('/(?:^[^\[]+)|\[[^]]*\]/', $field, $matches)) > 1) |
|||||||||||
389 | { |
|||||||||||
390 | $_file = $_FILES; |
|||||||||||
391 | for ($i = 0; $i < $c; $i++) |
|||||||||||
392 | { |
|||||||||||
393 | // We can't track numeric iterations, only full field names are accepted |
|||||||||||
394 | if (($field = trim($matches[0][$i], '[]')) === '' OR ! isset($_file[$field])) |
|||||||||||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
Using logical operators such as
or instead of || is generally not recommended.
PHP has two types of connecting operators (logical operators, and boolean operators):
The difference between these is the order in which they are executed. In most cases,
you would want to use a boolean operator like Let’s take a look at a few examples: // Logical operators have lower precedence:
$f = false or true;
// is executed like this:
($f = false) or true;
// Boolean operators have higher precedence:
$f = false || true;
// is executed like this:
$f = (false || true);
Logical Operators are used for Control-FlowOne case where you explicitly want to use logical operators is for control-flow such as this: $x === 5
or die('$x must be 5.');
// Instead of
if ($x !== 5) {
die('$x must be 5.');
}
Since // The following is currently a parse error.
$x === 5
or throw new RuntimeException('$x must be 5.');
These limitations lead to logical operators rarely being of use in current PHP code.
Loading history...
|
||||||||||||
395 | { |
|||||||||||
396 | $_file = NULL; |
|||||||||||
397 | break; |
|||||||||||
398 | } |
|||||||||||
399 | ||||||||||||
400 | $_file = $_file[$field]; |
|||||||||||
401 | } |
|||||||||||
402 | } |
|||||||||||
403 | ||||||||||||
404 | if ( ! isset($_file)) |
|||||||||||
405 | { |
|||||||||||
406 | $this->set_error('upload_no_file_selected', 'debug'); |
|||||||||||
407 | return FALSE; |
|||||||||||
408 | } |
|||||||||||
409 | ||||||||||||
410 | // Is the upload path valid? |
|||||||||||
411 | if ( ! $this->validate_upload_path()) |
|||||||||||
412 | { |
|||||||||||
413 | // errors will already be set by validate_upload_path() so just return FALSE |
|||||||||||
414 | return FALSE; |
|||||||||||
415 | } |
|||||||||||
416 | ||||||||||||
417 | // Was the file able to be uploaded? If not, determine the reason why. |
|||||||||||
418 | if ( ! file_exists($_file['tmp_name'])) // modified by ci-phpunit-test |
|||||||||||
419 | { |
|||||||||||
420 | $error = isset($_file['error']) ? $_file['error'] : 4; |
|||||||||||
421 | ||||||||||||
422 | switch ($error) |
|||||||||||
423 | { |
|||||||||||
424 | case UPLOAD_ERR_INI_SIZE: |
|||||||||||
425 | $this->set_error('upload_file_exceeds_limit', 'info'); |
|||||||||||
426 | break; |
|||||||||||
427 | case UPLOAD_ERR_FORM_SIZE: |
|||||||||||
428 | $this->set_error('upload_file_exceeds_form_limit', 'info'); |
|||||||||||
429 | break; |
|||||||||||
430 | case UPLOAD_ERR_PARTIAL: |
|||||||||||
431 | $this->set_error('upload_file_partial', 'debug'); |
|||||||||||
432 | break; |
|||||||||||
433 | case UPLOAD_ERR_NO_FILE: |
|||||||||||
434 | $this->set_error('upload_no_file_selected', 'debug'); |
|||||||||||
435 | break; |
|||||||||||
436 | case UPLOAD_ERR_NO_TMP_DIR: |
|||||||||||
437 | $this->set_error('upload_no_temp_directory', 'error'); |
|||||||||||
438 | break; |
|||||||||||
439 | case UPLOAD_ERR_CANT_WRITE: |
|||||||||||
440 | $this->set_error('upload_unable_to_write_file', 'error'); |
|||||||||||
441 | break; |
|||||||||||
442 | case UPLOAD_ERR_EXTENSION: |
|||||||||||
443 | $this->set_error('upload_stopped_by_extension', 'debug'); |
|||||||||||
444 | break; |
|||||||||||
445 | default: |
|||||||||||
446 | $this->set_error('upload_no_file_selected', 'debug'); |
|||||||||||
447 | break; |
|||||||||||
448 | } |
|||||||||||
449 | ||||||||||||
450 | return FALSE; |
|||||||||||
451 | } |
|||||||||||
452 | ||||||||||||
453 | // Set the uploaded data as class variables |
|||||||||||
454 | $this->file_temp = $_file['tmp_name']; |
|||||||||||
455 | $this->file_size = $_file['size']; |
|||||||||||
456 | ||||||||||||
457 | // Skip MIME type detection? |
|||||||||||
458 | if ($this->detect_mime !== FALSE) |
|||||||||||
459 | { |
|||||||||||
460 | $this->_file_mime_type($_file); |
|||||||||||
461 | } |
|||||||||||
462 | ||||||||||||
463 | $this->file_type = preg_replace('/^(.+?);.*$/', '\\1', $this->file_type); |
|||||||||||
464 | $this->file_type = strtolower(trim(stripslashes($this->file_type), '"')); |
|||||||||||
465 | $this->file_name = $this->_prep_filename($_file['name']); |
|||||||||||
466 | $this->file_ext = $this->get_extension($this->file_name); |
|||||||||||
467 | $this->client_name = $this->file_name; |
|||||||||||
0 ignored issues
–
show
The property
$client_name was declared of type boolean , but $this->file_name is of type string . 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...
|
||||||||||||
468 | ||||||||||||
469 | // Is the file type allowed to be uploaded? |
|||||||||||
470 | if ( ! $this->is_allowed_filetype()) |
|||||||||||
471 | { |
|||||||||||
472 | $this->set_error('upload_invalid_filetype', 'debug'); |
|||||||||||
473 | return FALSE; |
|||||||||||
474 | } |
|||||||||||
475 | ||||||||||||
476 | // if we're overriding, let's now make sure the new name and type is allowed |
|||||||||||
477 | if ($this->_file_name_override !== '') |
|||||||||||
478 | { |
|||||||||||
479 | $this->file_name = $this->_prep_filename($this->_file_name_override); |
|||||||||||
480 | ||||||||||||
481 | // If no extension was provided in the file_name config item, use the uploaded one |
|||||||||||
482 | if (strpos($this->_file_name_override, '.') === FALSE) |
|||||||||||
483 | { |
|||||||||||
484 | $this->file_name .= $this->file_ext; |
|||||||||||
485 | } |
|||||||||||
486 | else |
|||||||||||
487 | { |
|||||||||||
488 | // An extension was provided, let's have it! |
|||||||||||
489 | $this->file_ext = $this->get_extension($this->_file_name_override); |
|||||||||||
490 | } |
|||||||||||
491 | ||||||||||||
492 | if ( ! $this->is_allowed_filetype(TRUE)) |
|||||||||||
493 | { |
|||||||||||
494 | $this->set_error('upload_invalid_filetype', 'debug'); |
|||||||||||
495 | return FALSE; |
|||||||||||
496 | } |
|||||||||||
497 | } |
|||||||||||
498 | ||||||||||||
499 | // Convert the file size to kilobytes |
|||||||||||
500 | if ($this->file_size > 0) |
|||||||||||
501 | { |
|||||||||||
502 | $this->file_size = round($this->file_size/1024, 2); |
|||||||||||
0 ignored issues
–
show
The property
$file_size was declared of type integer , but round($this->file_size / 1024, 2) is of type double . 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...
|
||||||||||||
503 | } |
|||||||||||
504 | ||||||||||||
505 | // Is the file size within the allowed maximum? |
|||||||||||
506 | if ( ! $this->is_allowed_filesize()) |
|||||||||||
507 | { |
|||||||||||
508 | $this->set_error('upload_invalid_filesize', 'info'); |
|||||||||||
509 | return FALSE; |
|||||||||||
510 | } |
|||||||||||
511 | ||||||||||||
512 | // Are the image dimensions within the allowed size? |
|||||||||||
513 | // Note: This can fail if the server has an open_basedir restriction. |
|||||||||||
514 | if ( ! $this->is_allowed_dimensions()) |
|||||||||||
515 | { |
|||||||||||
516 | $this->set_error('upload_invalid_dimensions', 'info'); |
|||||||||||
517 | return FALSE; |
|||||||||||
518 | } |
|||||||||||
519 | ||||||||||||
520 | // Sanitize the file name for security |
|||||||||||
521 | $this->file_name = $this->_CI->security->sanitize_filename($this->file_name); |
|||||||||||
522 | ||||||||||||
523 | // Truncate the file name if it's too long |
|||||||||||
524 | if ($this->max_filename > 0) |
|||||||||||
525 | { |
|||||||||||
526 | $this->file_name = $this->limit_filename_length($this->file_name, $this->max_filename); |
|||||||||||
527 | } |
|||||||||||
528 | ||||||||||||
529 | // Remove white spaces in the name |
|||||||||||
530 | if ($this->remove_spaces === TRUE) |
|||||||||||
531 | { |
|||||||||||
532 | $this->file_name = preg_replace('/\s+/', '_', $this->file_name); |
|||||||||||
533 | } |
|||||||||||
534 | ||||||||||||
535 | if ($this->file_ext_tolower && ($ext_length = strlen($this->file_ext))) |
|||||||||||
536 | { |
|||||||||||
537 | // file_ext was previously lower-cased by a get_extension() call |
|||||||||||
538 | $this->file_name = substr($this->file_name, 0, -$ext_length).$this->file_ext; |
|||||||||||
539 | } |
|||||||||||
540 | ||||||||||||
541 | /* |
|||||||||||
542 | * Validate the file name |
|||||||||||
543 | * This function appends an number onto the end of |
|||||||||||
544 | * the file if one with the same name already exists. |
|||||||||||
545 | * If it returns false there was a problem. |
|||||||||||
546 | */ |
|||||||||||
547 | $this->orig_name = $this->file_name; |
|||||||||||
548 | if (FALSE === ($this->file_name = $this->set_filename($this->upload_path, $this->file_name))) |
|||||||||||
0 ignored issues
–
show
It seems like
$this->set_filename($thi...path, $this->file_name) can also be of type false . However, the property $file_name is declared as type string . Maybe add an additional type check?
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly. For example, imagine you have a variable Either this assignment is in error or a type check should be added for that assignment. class Id
{
public $id;
public function __construct($id)
{
$this->id = $id;
}
}
class Account
{
/** @var Id $id */
public $id;
}
$account_id = false;
if (starsAreRight()) {
$account_id = new Id(42);
}
$account = new Account();
if ($account instanceof Id)
{
$account->id = $account_id;
}
Loading history...
|
||||||||||||
549 | { |
|||||||||||
550 | return FALSE; |
|||||||||||
551 | } |
|||||||||||
552 | ||||||||||||
553 | /* |
|||||||||||
554 | * Run the file through the XSS hacking filter |
|||||||||||
555 | * This helps prevent malicious code from being |
|||||||||||
556 | * embedded within a file. Scripts can easily |
|||||||||||
557 | * be disguised as images or other file types. |
|||||||||||
558 | */ |
|||||||||||
559 | if ($this->xss_clean && $this->do_xss_clean() === FALSE) |
|||||||||||
560 | { |
|||||||||||
561 | $this->set_error('upload_unable_to_write_file', 'error'); |
|||||||||||
562 | return FALSE; |
|||||||||||
563 | } |
|||||||||||
564 | ||||||||||||
565 | /* |
|||||||||||
566 | * Move the file to the final destination |
|||||||||||
567 | * To deal with different server configurations |
|||||||||||
568 | * we'll attempt to use copy() first. If that fails |
|||||||||||
569 | * we'll use move_uploaded_file(). One of the two should |
|||||||||||
570 | * reliably work in most environments |
|||||||||||
571 | */ |
|||||||||||
572 | if ( ! @copy($this->file_temp, $this->upload_path.$this->file_name)) |
|||||||||||
573 | { |
|||||||||||
574 | if ( ! @move_uploaded_file($this->file_temp, $this->upload_path.$this->file_name)) |
|||||||||||
575 | { |
|||||||||||
576 | $this->set_error('upload_destination_error', 'error'); |
|||||||||||
577 | return FALSE; |
|||||||||||
578 | } |
|||||||||||
579 | } |
|||||||||||
580 | ||||||||||||
581 | /* |
|||||||||||
582 | * Set the finalized image dimensions |
|||||||||||
583 | * This sets the image width/height (assuming the |
|||||||||||
584 | * file was an image). We use this information |
|||||||||||
585 | * in the "data" function. |
|||||||||||
586 | */ |
|||||||||||
587 | $this->set_image_properties($this->upload_path.$this->file_name); |
|||||||||||
588 | ||||||||||||
589 | return TRUE; |
|||||||||||
590 | } |
|||||||||||
591 | ||||||||||||
592 | // -------------------------------------------------------------------- |
|||||||||||
593 | ||||||||||||
594 | /** |
|||||||||||
595 | * Finalized Data Array |
|||||||||||
596 | * |
|||||||||||
597 | * Returns an associative array containing all of the information |
|||||||||||
598 | * related to the upload, allowing the developer easy access in one array. |
|||||||||||
599 | * |
|||||||||||
600 | * @param string $index |
|||||||||||
601 | * @return mixed |
|||||||||||
602 | * |
|||||||||||
603 | * @codeCoverageIgnore |
|||||||||||
604 | */ |
|||||||||||
605 | public function data($index = NULL) |
|||||||||||
606 | { |
|||||||||||
607 | $data = array( |
|||||||||||
608 | 'file_name' => $this->file_name, |
|||||||||||
609 | 'file_type' => $this->file_type, |
|||||||||||
610 | 'file_path' => $this->upload_path, |
|||||||||||
611 | 'full_path' => $this->upload_path.$this->file_name, |
|||||||||||
612 | 'raw_name' => substr($this->file_name, 0, -strlen($this->file_ext)), |
|||||||||||
613 | 'orig_name' => $this->orig_name, |
|||||||||||
614 | 'client_name' => $this->client_name, |
|||||||||||
615 | 'file_ext' => $this->file_ext, |
|||||||||||
616 | 'file_size' => $this->file_size, |
|||||||||||
617 | 'is_image' => $this->is_image(), |
|||||||||||
618 | 'image_width' => $this->image_width, |
|||||||||||
619 | 'image_height' => $this->image_height, |
|||||||||||
620 | 'image_type' => $this->image_type, |
|||||||||||
621 | 'image_size_str' => $this->image_size_str, |
|||||||||||
622 | ); |
|||||||||||
623 | ||||||||||||
624 | if ( ! empty($index)) |
|||||||||||
625 | { |
|||||||||||
626 | return isset($data[$index]) ? $data[$index] : NULL; |
|||||||||||
627 | } |
|||||||||||
628 | ||||||||||||
629 | return $data; |
|||||||||||
630 | } |
|||||||||||
631 | ||||||||||||
632 | // -------------------------------------------------------------------- |
|||||||||||
633 | ||||||||||||
634 | /** |
|||||||||||
635 | * Set Upload Path |
|||||||||||
636 | * |
|||||||||||
637 | * @param string $path |
|||||||||||
638 | * @return CI_Upload |
|||||||||||
639 | */ |
|||||||||||
640 | public function set_upload_path($path) |
|||||||||||
641 | { |
|||||||||||
642 | // Make sure it has a trailing slash |
|||||||||||
643 | $this->upload_path = rtrim($path, '/').'/'; |
|||||||||||
644 | return $this; |
|||||||||||
645 | } |
|||||||||||
646 | ||||||||||||
647 | // -------------------------------------------------------------------- |
|||||||||||
648 | ||||||||||||
649 | /** |
|||||||||||
650 | * Set the file name |
|||||||||||
651 | * |
|||||||||||
652 | * This function takes a filename/path as input and looks for the |
|||||||||||
653 | * existence of a file with the same name. If found, it will append a |
|||||||||||
654 | * number to the end of the filename to avoid overwriting a pre-existing file. |
|||||||||||
655 | * |
|||||||||||
656 | * @param string $path |
|||||||||||
657 | * @param string $filename |
|||||||||||
658 | * @return string |
|||||||||||
659 | * |
|||||||||||
660 | * @codeCoverageIgnore |
|||||||||||
661 | */ |
|||||||||||
662 | public function set_filename($path, $filename) |
|||||||||||
663 | { |
|||||||||||
664 | if ($this->encrypt_name === TRUE) |
|||||||||||
665 | { |
|||||||||||
666 | $filename = md5(uniqid(mt_rand())).$this->file_ext; |
|||||||||||
667 | } |
|||||||||||
668 | ||||||||||||
669 | if ($this->overwrite === TRUE OR ! file_exists($path.$filename)) |
|||||||||||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
Using logical operators such as
or instead of || is generally not recommended.
PHP has two types of connecting operators (logical operators, and boolean operators):
The difference between these is the order in which they are executed. In most cases,
you would want to use a boolean operator like Let’s take a look at a few examples: // Logical operators have lower precedence:
$f = false or true;
// is executed like this:
($f = false) or true;
// Boolean operators have higher precedence:
$f = false || true;
// is executed like this:
$f = (false || true);
Logical Operators are used for Control-FlowOne case where you explicitly want to use logical operators is for control-flow such as this: $x === 5
or die('$x must be 5.');
// Instead of
if ($x !== 5) {
die('$x must be 5.');
}
Since // The following is currently a parse error.
$x === 5
or throw new RuntimeException('$x must be 5.');
These limitations lead to logical operators rarely being of use in current PHP code.
Loading history...
|
||||||||||||
670 | { |
|||||||||||
671 | return $filename; |
|||||||||||
672 | } |
|||||||||||
673 | ||||||||||||
674 | $filename = str_replace($this->file_ext, '', $filename); |
|||||||||||
675 | ||||||||||||
676 | $new_filename = ''; |
|||||||||||
677 | for ($i = 1; $i < $this->max_filename_increment; $i++) |
|||||||||||
678 | { |
|||||||||||
679 | if ( ! file_exists($path.$filename.$i.$this->file_ext)) |
|||||||||||
680 | { |
|||||||||||
681 | $new_filename = $filename.$i.$this->file_ext; |
|||||||||||
682 | break; |
|||||||||||
683 | } |
|||||||||||
684 | } |
|||||||||||
685 | ||||||||||||
686 | if ($new_filename === '') |
|||||||||||
687 | { |
|||||||||||
688 | $this->set_error('upload_bad_filename', 'debug'); |
|||||||||||
689 | return FALSE; |
|||||||||||
690 | } |
|||||||||||
691 | ||||||||||||
692 | return $new_filename; |
|||||||||||
693 | } |
|||||||||||
694 | ||||||||||||
695 | // -------------------------------------------------------------------- |
|||||||||||
696 | ||||||||||||
697 | /** |
|||||||||||
698 | * Set Maximum File Size |
|||||||||||
699 | * |
|||||||||||
700 | * @param int $n |
|||||||||||
701 | * @return CI_Upload |
|||||||||||
702 | */ |
|||||||||||
703 | public function set_max_filesize($n) |
|||||||||||
704 | { |
|||||||||||
705 | $this->max_size = ($n < 0) ? 0 : (int) $n; |
|||||||||||
706 | return $this; |
|||||||||||
707 | } |
|||||||||||
708 | ||||||||||||
709 | // -------------------------------------------------------------------- |
|||||||||||
710 | ||||||||||||
711 | /** |
|||||||||||
712 | * Set Maximum File Size |
|||||||||||
713 | * |
|||||||||||
714 | * An internal alias to set_max_filesize() to help with configuration |
|||||||||||
715 | * as initialize() will look for a set_<property_name>() method ... |
|||||||||||
716 | * |
|||||||||||
717 | * @param int $n |
|||||||||||
718 | * @return CI_Upload |
|||||||||||
719 | */ |
|||||||||||
720 | protected function set_max_size($n) |
|||||||||||
721 | { |
|||||||||||
722 | return $this->set_max_filesize($n); |
|||||||||||
723 | } |
|||||||||||
724 | ||||||||||||
725 | // -------------------------------------------------------------------- |
|||||||||||
726 | ||||||||||||
727 | /** |
|||||||||||
728 | * Set Maximum File Name Length |
|||||||||||
729 | * |
|||||||||||
730 | * @param int $n |
|||||||||||
731 | * @return CI_Upload |
|||||||||||
732 | * |
|||||||||||
733 | * @codeCoverageIgnore |
|||||||||||
734 | */ |
|||||||||||
735 | public function set_max_filename($n) |
|||||||||||
736 | { |
|||||||||||
737 | $this->max_filename = ($n < 0) ? 0 : (int) $n; |
|||||||||||
738 | return $this; |
|||||||||||
739 | } |
|||||||||||
740 | ||||||||||||
741 | // -------------------------------------------------------------------- |
|||||||||||
742 | ||||||||||||
743 | /** |
|||||||||||
744 | * Set Maximum Image Width |
|||||||||||
745 | * |
|||||||||||
746 | * @param int $n |
|||||||||||
747 | * @return CI_Upload |
|||||||||||
748 | */ |
|||||||||||
749 | public function set_max_width($n) |
|||||||||||
750 | { |
|||||||||||
751 | $this->max_width = ($n < 0) ? 0 : (int) $n; |
|||||||||||
752 | return $this; |
|||||||||||
753 | } |
|||||||||||
754 | ||||||||||||
755 | // -------------------------------------------------------------------- |
|||||||||||
756 | ||||||||||||
757 | /** |
|||||||||||
758 | * Set Maximum Image Height |
|||||||||||
759 | * |
|||||||||||
760 | * @param int $n |
|||||||||||
761 | * @return CI_Upload |
|||||||||||
762 | */ |
|||||||||||
763 | public function set_max_height($n) |
|||||||||||
764 | { |
|||||||||||
765 | $this->max_height = ($n < 0) ? 0 : (int) $n; |
|||||||||||
766 | return $this; |
|||||||||||
767 | } |
|||||||||||
768 | ||||||||||||
769 | // -------------------------------------------------------------------- |
|||||||||||
770 | ||||||||||||
771 | /** |
|||||||||||
772 | * Set minimum image width |
|||||||||||
773 | * |
|||||||||||
774 | * @param int $n |
|||||||||||
775 | * @return CI_Upload |
|||||||||||
776 | * |
|||||||||||
777 | * @codeCoverageIgnore |
|||||||||||
778 | */ |
|||||||||||
779 | public function set_min_width($n) |
|||||||||||
780 | { |
|||||||||||
781 | $this->min_width = ($n < 0) ? 0 : (int) $n; |
|||||||||||
782 | return $this; |
|||||||||||
783 | } |
|||||||||||
784 | ||||||||||||
785 | // -------------------------------------------------------------------- |
|||||||||||
786 | ||||||||||||
787 | /** |
|||||||||||
788 | * Set minimum image height |
|||||||||||
789 | * |
|||||||||||
790 | * @param int $n |
|||||||||||
791 | * @return CI_Upload |
|||||||||||
792 | * |
|||||||||||
793 | * @codeCoverageIgnore |
|||||||||||
794 | */ |
|||||||||||
795 | public function set_min_height($n) |
|||||||||||
796 | { |
|||||||||||
797 | $this->min_height = ($n < 0) ? 0 : (int) $n; |
|||||||||||
798 | return $this; |
|||||||||||
799 | } |
|||||||||||
800 | ||||||||||||
801 | // -------------------------------------------------------------------- |
|||||||||||
802 | ||||||||||||
803 | /** |
|||||||||||
804 | * Set Allowed File Types |
|||||||||||
805 | * |
|||||||||||
806 | * @param mixed $types |
|||||||||||
807 | * @return CI_Upload |
|||||||||||
808 | */ |
|||||||||||
809 | public function set_allowed_types($types) |
|||||||||||
810 | { |
|||||||||||
811 | $this->allowed_types = (is_array($types) OR $types === '*') |
|||||||||||
0 ignored issues
–
show
It seems like
(is_array($types) or $ty... : explode('|', $types) can also be of type array . However, the property $allowed_types is declared as type string . Maybe add an additional type check?
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly. For example, imagine you have a variable Either this assignment is in error or a type check should be added for that assignment. class Id
{
public $id;
public function __construct($id)
{
$this->id = $id;
}
}
class Account
{
/** @var Id $id */
public $id;
}
$account_id = false;
if (starsAreRight()) {
$account_id = new Id(42);
}
$account = new Account();
if ($account instanceof Id)
{
$account->id = $account_id;
}
Loading history...
Comprehensibility
Best Practice
introduced
by
Using logical operators such as
or instead of || is generally not recommended.
PHP has two types of connecting operators (logical operators, and boolean operators):
The difference between these is the order in which they are executed. In most cases,
you would want to use a boolean operator like Let’s take a look at a few examples: // Logical operators have lower precedence:
$f = false or true;
// is executed like this:
($f = false) or true;
// Boolean operators have higher precedence:
$f = false || true;
// is executed like this:
$f = (false || true);
Logical Operators are used for Control-FlowOne case where you explicitly want to use logical operators is for control-flow such as this: $x === 5
or die('$x must be 5.');
// Instead of
if ($x !== 5) {
die('$x must be 5.');
}
Since // The following is currently a parse error.
$x === 5
or throw new RuntimeException('$x must be 5.');
These limitations lead to logical operators rarely being of use in current PHP code.
Loading history...
|
||||||||||||
812 | ? $types |
|||||||||||
813 | : explode('|', $types); |
|||||||||||
814 | return $this; |
|||||||||||
815 | } |
|||||||||||
816 | ||||||||||||
817 | // -------------------------------------------------------------------- |
|||||||||||
818 | ||||||||||||
819 | /** |
|||||||||||
820 | * Set Image Properties |
|||||||||||
821 | * |
|||||||||||
822 | * Uses GD to determine the width/height/type of image |
|||||||||||
823 | * |
|||||||||||
824 | * @param string $path |
|||||||||||
825 | * @return CI_Upload |
|||||||||||
826 | */ |
|||||||||||
827 | public function set_image_properties($path = '') |
|||||||||||
828 | { |
|||||||||||
829 | if ($this->is_image() && function_exists('getimagesize')) |
|||||||||||
830 | { |
|||||||||||
831 | if (FALSE !== ($D = @getimagesize($path))) |
|||||||||||
832 | { |
|||||||||||
833 | $types = array(1 => 'gif', 2 => 'jpeg', 3 => 'png'); |
|||||||||||
834 | ||||||||||||
835 | $this->image_width = $D[0]; |
|||||||||||
836 | $this->image_height = $D[1]; |
|||||||||||
837 | $this->image_type = isset($types[$D[2]]) ? $types[$D[2]] : 'unknown'; |
|||||||||||
838 | $this->image_size_str = $D[3]; // string containing height and width |
|||||||||||
839 | } |
|||||||||||
840 | } |
|||||||||||
841 | ||||||||||||
842 | return $this; |
|||||||||||
843 | } |
|||||||||||
844 | ||||||||||||
845 | // -------------------------------------------------------------------- |
|||||||||||
846 | ||||||||||||
847 | /** |
|||||||||||
848 | * Set XSS Clean |
|||||||||||
849 | * |
|||||||||||
850 | * Enables the XSS flag so that the file that was uploaded |
|||||||||||
851 | * will be run through the XSS filter. |
|||||||||||
852 | * |
|||||||||||
853 | * @param bool $flag |
|||||||||||
854 | * @return CI_Upload |
|||||||||||
855 | * |
|||||||||||
856 | * @codeCoverageIgnore |
|||||||||||
857 | */ |
|||||||||||
858 | public function set_xss_clean($flag = FALSE) |
|||||||||||
859 | { |
|||||||||||
860 | $this->xss_clean = ($flag === TRUE); |
|||||||||||
861 | return $this; |
|||||||||||
862 | } |
|||||||||||
863 | ||||||||||||
864 | // -------------------------------------------------------------------- |
|||||||||||
865 | ||||||||||||
866 | /** |
|||||||||||
867 | * Validate the image |
|||||||||||
868 | * |
|||||||||||
869 | * @return bool |
|||||||||||
870 | * |
|||||||||||
871 | * @codeCoverageIgnore |
|||||||||||
872 | */ |
|||||||||||
873 | public function is_image() |
|||||||||||
874 | { |
|||||||||||
875 | // IE will sometimes return odd mime-types during upload, so here we just standardize all |
|||||||||||
876 | // jpegs or pngs to the same file type. |
|||||||||||
877 | ||||||||||||
878 | $png_mimes = array('image/x-png'); |
|||||||||||
879 | $jpeg_mimes = array('image/jpg', 'image/jpe', 'image/jpeg', 'image/pjpeg'); |
|||||||||||
880 | ||||||||||||
881 | if (in_array($this->file_type, $png_mimes)) |
|||||||||||
882 | { |
|||||||||||
883 | $this->file_type = 'image/png'; |
|||||||||||
884 | } |
|||||||||||
885 | elseif (in_array($this->file_type, $jpeg_mimes)) |
|||||||||||
886 | { |
|||||||||||
887 | $this->file_type = 'image/jpeg'; |
|||||||||||
888 | } |
|||||||||||
889 | ||||||||||||
890 | $img_mimes = array('image/gif', 'image/jpeg', 'image/png'); |
|||||||||||
891 | ||||||||||||
892 | return in_array($this->file_type, $img_mimes, TRUE); |
|||||||||||
893 | } |
|||||||||||
894 | ||||||||||||
895 | // -------------------------------------------------------------------- |
|||||||||||
896 | ||||||||||||
897 | /** |
|||||||||||
898 | * Verify that the filetype is allowed |
|||||||||||
899 | * |
|||||||||||
900 | * @param bool $ignore_mime |
|||||||||||
901 | * @return bool |
|||||||||||
902 | * |
|||||||||||
903 | * @codeCoverageIgnore |
|||||||||||
904 | */ |
|||||||||||
905 | public function is_allowed_filetype($ignore_mime = FALSE) |
|||||||||||
906 | { |
|||||||||||
907 | if ($this->allowed_types === '*') |
|||||||||||
908 | { |
|||||||||||
909 | return TRUE; |
|||||||||||
910 | } |
|||||||||||
911 | ||||||||||||
912 | if (empty($this->allowed_types) OR ! is_array($this->allowed_types)) |
|||||||||||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
Using logical operators such as
or instead of || is generally not recommended.
PHP has two types of connecting operators (logical operators, and boolean operators):
The difference between these is the order in which they are executed. In most cases,
you would want to use a boolean operator like Let’s take a look at a few examples: // Logical operators have lower precedence:
$f = false or true;
// is executed like this:
($f = false) or true;
// Boolean operators have higher precedence:
$f = false || true;
// is executed like this:
$f = (false || true);
Logical Operators are used for Control-FlowOne case where you explicitly want to use logical operators is for control-flow such as this: $x === 5
or die('$x must be 5.');
// Instead of
if ($x !== 5) {
die('$x must be 5.');
}
Since // The following is currently a parse error.
$x === 5
or throw new RuntimeException('$x must be 5.');
These limitations lead to logical operators rarely being of use in current PHP code.
Loading history...
|
||||||||||||
913 | { |
|||||||||||
914 | $this->set_error('upload_no_file_types', 'debug'); |
|||||||||||
915 | return FALSE; |
|||||||||||
916 | } |
|||||||||||
917 | ||||||||||||
918 | $ext = strtolower(ltrim($this->file_ext, '.')); |
|||||||||||
919 | ||||||||||||
920 | if ( ! in_array($ext, $this->allowed_types, TRUE)) |
|||||||||||
921 | { |
|||||||||||
922 | return FALSE; |
|||||||||||
923 | } |
|||||||||||
924 | ||||||||||||
925 | // Images get some additional checks |
|||||||||||
926 | if (in_array($ext, array('gif', 'jpg', 'jpeg', 'jpe', 'png'), TRUE) && @getimagesize($this->file_temp) === FALSE) |
|||||||||||
927 | { |
|||||||||||
928 | return FALSE; |
|||||||||||
929 | } |
|||||||||||
930 | ||||||||||||
931 | if ($ignore_mime === TRUE) |
|||||||||||
932 | { |
|||||||||||
933 | return TRUE; |
|||||||||||
934 | } |
|||||||||||
935 | ||||||||||||
936 | if (isset($this->_mimes[$ext])) |
|||||||||||
937 | { |
|||||||||||
938 | return is_array($this->_mimes[$ext]) |
|||||||||||
939 | ? in_array($this->file_type, $this->_mimes[$ext], TRUE) |
|||||||||||
940 | : ($this->_mimes[$ext] === $this->file_type); |
|||||||||||
941 | } |
|||||||||||
942 | ||||||||||||
943 | return FALSE; |
|||||||||||
944 | } |
|||||||||||
945 | ||||||||||||
946 | // -------------------------------------------------------------------- |
|||||||||||
947 | ||||||||||||
948 | /** |
|||||||||||
949 | * Verify that the file is within the allowed size |
|||||||||||
950 | * |
|||||||||||
951 | * @return bool |
|||||||||||
952 | * |
|||||||||||
953 | * @codeCoverageIgnore |
|||||||||||
954 | */ |
|||||||||||
955 | public function is_allowed_filesize() |
|||||||||||
956 | { |
|||||||||||
957 | return ($this->max_size === 0 OR $this->max_size > $this->file_size); |
|||||||||||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
Using logical operators such as
or instead of || is generally not recommended.
PHP has two types of connecting operators (logical operators, and boolean operators):
The difference between these is the order in which they are executed. In most cases,
you would want to use a boolean operator like Let’s take a look at a few examples: // Logical operators have lower precedence:
$f = false or true;
// is executed like this:
($f = false) or true;
// Boolean operators have higher precedence:
$f = false || true;
// is executed like this:
$f = (false || true);
Logical Operators are used for Control-FlowOne case where you explicitly want to use logical operators is for control-flow such as this: $x === 5
or die('$x must be 5.');
// Instead of
if ($x !== 5) {
die('$x must be 5.');
}
Since // The following is currently a parse error.
$x === 5
or throw new RuntimeException('$x must be 5.');
These limitations lead to logical operators rarely being of use in current PHP code.
Loading history...
|
||||||||||||
958 | } |
|||||||||||
959 | ||||||||||||
960 | // -------------------------------------------------------------------- |
|||||||||||
961 | ||||||||||||
962 | /** |
|||||||||||
963 | * Verify that the image is within the allowed width/height |
|||||||||||
964 | * |
|||||||||||
965 | * @return bool |
|||||||||||
966 | * |
|||||||||||
967 | * @codeCoverageIgnore |
|||||||||||
968 | */ |
|||||||||||
969 | public function is_allowed_dimensions() |
|||||||||||
970 | { |
|||||||||||
971 | if ( ! $this->is_image()) |
|||||||||||
972 | { |
|||||||||||
973 | return TRUE; |
|||||||||||
974 | } |
|||||||||||
975 | ||||||||||||
976 | if (function_exists('getimagesize')) |
|||||||||||
977 | { |
|||||||||||
978 | $D = @getimagesize($this->file_temp); |
|||||||||||
979 | ||||||||||||
980 | if ($this->max_width > 0 && $D[0] > $this->max_width) |
|||||||||||
981 | { |
|||||||||||
982 | return FALSE; |
|||||||||||
983 | } |
|||||||||||
984 | ||||||||||||
985 | if ($this->max_height > 0 && $D[1] > $this->max_height) |
|||||||||||
986 | { |
|||||||||||
987 | return FALSE; |
|||||||||||
988 | } |
|||||||||||
989 | ||||||||||||
990 | if ($this->min_width > 0 && $D[0] < $this->min_width) |
|||||||||||
991 | { |
|||||||||||
992 | return FALSE; |
|||||||||||
993 | } |
|||||||||||
994 | ||||||||||||
995 | if ($this->min_height > 0 && $D[1] < $this->min_height) |
|||||||||||
996 | { |
|||||||||||
997 | return FALSE; |
|||||||||||
998 | } |
|||||||||||
999 | } |
|||||||||||
1000 | ||||||||||||
1001 | return TRUE; |
|||||||||||
1002 | } |
|||||||||||
1003 | ||||||||||||
1004 | // -------------------------------------------------------------------- |
|||||||||||
1005 | ||||||||||||
1006 | /** |
|||||||||||
1007 | * Validate Upload Path |
|||||||||||
1008 | * |
|||||||||||
1009 | * Verifies that it is a valid upload path with proper permissions. |
|||||||||||
1010 | * |
|||||||||||
1011 | * @return bool |
|||||||||||
1012 | * |
|||||||||||
1013 | * @codeCoverageIgnore |
|||||||||||
1014 | */ |
|||||||||||
1015 | public function validate_upload_path() |
|||||||||||
1016 | { |
|||||||||||
1017 | if ($this->upload_path === '') |
|||||||||||
1018 | { |
|||||||||||
1019 | $this->set_error('upload_no_filepath', 'error'); |
|||||||||||
1020 | return FALSE; |
|||||||||||
1021 | } |
|||||||||||
1022 | ||||||||||||
1023 | if (realpath($this->upload_path) !== FALSE) |
|||||||||||
1024 | { |
|||||||||||
1025 | $this->upload_path = str_replace('\\', '/', realpath($this->upload_path)); |
|||||||||||
1026 | } |
|||||||||||
1027 | ||||||||||||
1028 | if ( ! is_dir($this->upload_path)) |
|||||||||||
1029 | { |
|||||||||||
1030 | $this->set_error('upload_no_filepath', 'error'); |
|||||||||||
1031 | return FALSE; |
|||||||||||
1032 | } |
|||||||||||
1033 | ||||||||||||
1034 | if ( ! is_really_writable($this->upload_path)) |
|||||||||||
1035 | { |
|||||||||||
1036 | $this->set_error('upload_not_writable', 'error'); |
|||||||||||
1037 | return FALSE; |
|||||||||||
1038 | } |
|||||||||||
1039 | ||||||||||||
1040 | $this->upload_path = preg_replace('/(.+?)\/*$/', '\\1/', $this->upload_path); |
|||||||||||
1041 | return TRUE; |
|||||||||||
1042 | } |
|||||||||||
1043 | ||||||||||||
1044 | // -------------------------------------------------------------------- |
|||||||||||
1045 | ||||||||||||
1046 | /** |
|||||||||||
1047 | * Extract the file extension |
|||||||||||
1048 | * |
|||||||||||
1049 | * @param string $filename |
|||||||||||
1050 | * @return string |
|||||||||||
1051 | * |
|||||||||||
1052 | * @codeCoverageIgnore |
|||||||||||
1053 | */ |
|||||||||||
1054 | public function get_extension($filename) |
|||||||||||
1055 | { |
|||||||||||
1056 | $x = explode('.', $filename); |
|||||||||||
1057 | ||||||||||||
1058 | if (count($x) === 1) |
|||||||||||
1059 | { |
|||||||||||
1060 | return ''; |
|||||||||||
1061 | } |
|||||||||||
1062 | ||||||||||||
1063 | $ext = ($this->file_ext_tolower) ? strtolower(end($x)) : end($x); |
|||||||||||
1064 | return '.'.$ext; |
|||||||||||
1065 | } |
|||||||||||
1066 | ||||||||||||
1067 | // -------------------------------------------------------------------- |
|||||||||||
1068 | ||||||||||||
1069 | /** |
|||||||||||
1070 | * Limit the File Name Length |
|||||||||||
1071 | * |
|||||||||||
1072 | * @param string $filename |
|||||||||||
1073 | * @param int $length |
|||||||||||
1074 | * @return string |
|||||||||||
1075 | * |
|||||||||||
1076 | * @codeCoverageIgnore |
|||||||||||
1077 | */ |
|||||||||||
1078 | public function limit_filename_length($filename, $length) |
|||||||||||
1079 | { |
|||||||||||
1080 | if (strlen($filename) < $length) |
|||||||||||
1081 | { |
|||||||||||
1082 | return $filename; |
|||||||||||
1083 | } |
|||||||||||
1084 | ||||||||||||
1085 | $ext = ''; |
|||||||||||
1086 | if (strpos($filename, '.') !== FALSE) |
|||||||||||
1087 | { |
|||||||||||
1088 | $parts = explode('.', $filename); |
|||||||||||
1089 | $ext = '.'.array_pop($parts); |
|||||||||||
1090 | $filename = implode('.', $parts); |
|||||||||||
1091 | } |
|||||||||||
1092 | ||||||||||||
1093 | return substr($filename, 0, ($length - strlen($ext))).$ext; |
|||||||||||
1094 | } |
|||||||||||
1095 | ||||||||||||
1096 | // -------------------------------------------------------------------- |
|||||||||||
1097 | ||||||||||||
1098 | /** |
|||||||||||
1099 | * Runs the file through the XSS clean function |
|||||||||||
1100 | * |
|||||||||||
1101 | * This prevents people from embedding malicious code in their files. |
|||||||||||
1102 | * I'm not sure that it won't negatively affect certain files in unexpected ways, |
|||||||||||
1103 | * but so far I haven't found that it causes trouble. |
|||||||||||
1104 | * |
|||||||||||
1105 | * @return string |
|||||||||||
1106 | * |
|||||||||||
1107 | * @codeCoverageIgnore |
|||||||||||
1108 | */ |
|||||||||||
1109 | public function do_xss_clean() |
|||||||||||
1110 | { |
|||||||||||
1111 | $file = $this->file_temp; |
|||||||||||
1112 | ||||||||||||
1113 | if (filesize($file) == 0) |
|||||||||||
1114 | { |
|||||||||||
1115 | return FALSE; |
|||||||||||
0 ignored issues
–
show
The return type of
return FALSE; (false ) is incompatible with the return type documented by CI_Upload::do_xss_clean of type string .
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
Loading history...
|
||||||||||||
1116 | } |
|||||||||||
1117 | ||||||||||||
1118 | if (memory_get_usage() && ($memory_limit = ini_get('memory_limit')) > 0) |
|||||||||||
1119 | { |
|||||||||||
1120 | $memory_limit = str_split($memory_limit, strspn($memory_limit, '1234567890')); |
|||||||||||
1121 | if ( ! empty($memory_limit[1])) |
|||||||||||
1122 | { |
|||||||||||
1123 | switch ($memory_limit[1][0]) |
|||||||||||
1124 | { |
|||||||||||
1125 | case 'g': |
|||||||||||
1126 | case 'G': |
|||||||||||
1127 | $memory_limit[0] *= 1024 * 1024 * 1024; |
|||||||||||
1128 | break; |
|||||||||||
1129 | case 'm': |
|||||||||||
1130 | case 'M': |
|||||||||||
1131 | $memory_limit[0] *= 1024 * 1024; |
|||||||||||
1132 | break; |
|||||||||||
1133 | default: |
|||||||||||
1134 | break; |
|||||||||||
1135 | } |
|||||||||||
1136 | } |
|||||||||||
1137 | ||||||||||||
1138 | $memory_limit = (int) ceil(filesize($file) + $memory_limit[0]); |
|||||||||||
1139 | ini_set('memory_limit', $memory_limit); // When an integer is used, the value is measured in bytes. - PHP.net |
|||||||||||
1140 | } |
|||||||||||
1141 | ||||||||||||
1142 | // If the file being uploaded is an image, then we should have no problem with XSS attacks (in theory), but |
|||||||||||
1143 | // IE can be fooled into mime-type detecting a malformed image as an html file, thus executing an XSS attack on anyone |
|||||||||||
1144 | // using IE who looks at the image. It does this by inspecting the first 255 bytes of an image. To get around this |
|||||||||||
1145 | // CI will itself look at the first 255 bytes of an image to determine its relative safety. This can save a lot of |
|||||||||||
1146 | // processor power and time if it is actually a clean image, as it will be in nearly all instances _except_ an |
|||||||||||
1147 | // attempted XSS attack. |
|||||||||||
1148 | ||||||||||||
1149 | if (function_exists('getimagesize') && @getimagesize($file) !== FALSE) |
|||||||||||
1150 | { |
|||||||||||
1151 | if (($file = @fopen($file, 'rb')) === FALSE) // "b" to force binary |
|||||||||||
1152 | { |
|||||||||||
1153 | return FALSE; // Couldn't open the file, return FALSE |
|||||||||||
0 ignored issues
–
show
The return type of
return FALSE; (false ) is incompatible with the return type documented by CI_Upload::do_xss_clean of type string .
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
Loading history...
|
||||||||||||
1154 | } |
|||||||||||
1155 | ||||||||||||
1156 | $opening_bytes = fread($file, 256); |
|||||||||||
1157 | fclose($file); |
|||||||||||
1158 | ||||||||||||
1159 | // These are known to throw IE into mime-type detection chaos |
|||||||||||
1160 | // <a, <body, <head, <html, <img, <plaintext, <pre, <script, <table, <title |
|||||||||||
1161 | // title is basically just in SVG, but we filter it anyhow |
|||||||||||
1162 | ||||||||||||
1163 | // if it's an image or no "triggers" detected in the first 256 bytes - we're good |
|||||||||||
1164 | return ! preg_match('/<(a|body|head|html|img|plaintext|pre|script|table|title)[\s>]/i', $opening_bytes); |
|||||||||||
0 ignored issues
–
show
The return type of
return !preg_match('/<(a...>]/i', $opening_bytes); (boolean ) is incompatible with the return type documented by CI_Upload::do_xss_clean of type string .
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
Loading history...
|
||||||||||||
1165 | } |
|||||||||||
1166 | ||||||||||||
1167 | if (($data = @file_get_contents($file)) === FALSE) |
|||||||||||
1168 | { |
|||||||||||
1169 | return FALSE; |
|||||||||||
0 ignored issues
–
show
The return type of
return FALSE; (false ) is incompatible with the return type documented by CI_Upload::do_xss_clean of type string .
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
Loading history...
|
||||||||||||
1170 | } |
|||||||||||
1171 | ||||||||||||
1172 | return $this->_CI->security->xss_clean($data, TRUE); |
|||||||||||
1173 | } |
|||||||||||
1174 | ||||||||||||
1175 | // -------------------------------------------------------------------- |
|||||||||||
1176 | ||||||||||||
1177 | /** |
|||||||||||
1178 | * Set an error message |
|||||||||||
1179 | * |
|||||||||||
1180 | * @param string $msg |
|||||||||||
1181 | * @return CI_Upload |
|||||||||||
1182 | * |
|||||||||||
1183 | * @codeCoverageIgnore |
|||||||||||
1184 | */ |
|||||||||||
1185 | public function set_error($msg, $log_level = 'error') |
|||||||||||
1186 | { |
|||||||||||
1187 | $this->_CI->lang->load('upload'); |
|||||||||||
1188 | ||||||||||||
1189 | is_array($msg) OR $msg = array($msg); |
|||||||||||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
Using logical operators such as
or instead of || is generally not recommended.
PHP has two types of connecting operators (logical operators, and boolean operators):
The difference between these is the order in which they are executed. In most cases,
you would want to use a boolean operator like Let’s take a look at a few examples: // Logical operators have lower precedence:
$f = false or true;
// is executed like this:
($f = false) or true;
// Boolean operators have higher precedence:
$f = false || true;
// is executed like this:
$f = (false || true);
Logical Operators are used for Control-FlowOne case where you explicitly want to use logical operators is for control-flow such as this: $x === 5
or die('$x must be 5.');
// Instead of
if ($x !== 5) {
die('$x must be 5.');
}
Since // The following is currently a parse error.
$x === 5
or throw new RuntimeException('$x must be 5.');
These limitations lead to logical operators rarely being of use in current PHP code.
Loading history...
|
||||||||||||
1190 | foreach ($msg as $val) |
|||||||||||
1191 | { |
|||||||||||
1192 | $msg = ($this->_CI->lang->line($val) === FALSE) ? $val : $this->_CI->lang->line($val); |
|||||||||||
1193 | $this->error_msg[] = $msg; |
|||||||||||
1194 | log_message($log_level, $msg); |
|||||||||||
1195 | } |
|||||||||||
1196 | ||||||||||||
1197 | return $this; |
|||||||||||
1198 | } |
|||||||||||
1199 | ||||||||||||
1200 | // -------------------------------------------------------------------- |
|||||||||||
1201 | ||||||||||||
1202 | /** |
|||||||||||
1203 | * Display the error message |
|||||||||||
1204 | * |
|||||||||||
1205 | * @param string $open |
|||||||||||
1206 | * @param string $close |
|||||||||||
1207 | * @return string |
|||||||||||
1208 | * |
|||||||||||
1209 | * @codeCoverageIgnore |
|||||||||||
1210 | */ |
|||||||||||
1211 | public function display_errors($open = '<p>', $close = '</p>') |
|||||||||||
1212 | { |
|||||||||||
1213 | return (count($this->error_msg) > 0) ? $open.implode($close.$open, $this->error_msg).$close : ''; |
|||||||||||
1214 | } |
|||||||||||
1215 | ||||||||||||
1216 | // -------------------------------------------------------------------- |
|||||||||||
1217 | ||||||||||||
1218 | /** |
|||||||||||
1219 | * Prep Filename |
|||||||||||
1220 | * |
|||||||||||
1221 | * Prevents possible script execution from Apache's handling |
|||||||||||
1222 | * of files' multiple extensions. |
|||||||||||
1223 | * |
|||||||||||
1224 | * @link http://httpd.apache.org/docs/1.3/mod/mod_mime.html#multipleext |
|||||||||||
1225 | * |
|||||||||||
1226 | * @param string $filename |
|||||||||||
1227 | * @return string |
|||||||||||
1228 | * |
|||||||||||
1229 | * @codeCoverageIgnore |
|||||||||||
1230 | */ |
|||||||||||
1231 | protected function _prep_filename($filename) |
|||||||||||
1232 | { |
|||||||||||
1233 | if ($this->mod_mime_fix === FALSE OR $this->allowed_types === '*' OR ($ext_pos = strrpos($filename, '.')) === FALSE) |
|||||||||||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
Using logical operators such as
or instead of || is generally not recommended.
PHP has two types of connecting operators (logical operators, and boolean operators):
The difference between these is the order in which they are executed. In most cases,
you would want to use a boolean operator like Let’s take a look at a few examples: // Logical operators have lower precedence:
$f = false or true;
// is executed like this:
($f = false) or true;
// Boolean operators have higher precedence:
$f = false || true;
// is executed like this:
$f = (false || true);
Logical Operators are used for Control-FlowOne case where you explicitly want to use logical operators is for control-flow such as this: $x === 5
or die('$x must be 5.');
// Instead of
if ($x !== 5) {
die('$x must be 5.');
}
Since // The following is currently a parse error.
$x === 5
or throw new RuntimeException('$x must be 5.');
These limitations lead to logical operators rarely being of use in current PHP code.
Loading history...
|
||||||||||||
1234 | { |
|||||||||||
1235 | return $filename; |
|||||||||||
1236 | } |
|||||||||||
1237 | ||||||||||||
1238 | $ext = substr($filename, $ext_pos); |
|||||||||||
1239 | $filename = substr($filename, 0, $ext_pos); |
|||||||||||
1240 | return str_replace('.', '_', $filename).$ext; |
|||||||||||
1241 | } |
|||||||||||
1242 | ||||||||||||
1243 | // -------------------------------------------------------------------- |
|||||||||||
1244 | ||||||||||||
1245 | /** |
|||||||||||
1246 | * File MIME type |
|||||||||||
1247 | * |
|||||||||||
1248 | * Detects the (actual) MIME type of the uploaded file, if possible. |
|||||||||||
1249 | * The input array is expected to be $_FILES[$field] |
|||||||||||
1250 | * |
|||||||||||
1251 | * @param array $file |
|||||||||||
1252 | * @return void |
|||||||||||
1253 | * |
|||||||||||
1254 | * @codeCoverageIgnore |
|||||||||||
1255 | */ |
|||||||||||
1256 | protected function _file_mime_type($file) |
|||||||||||
1257 | { |
|||||||||||
1258 | // We'll need this to validate the MIME info string (e.g. text/plain; charset=us-ascii) |
|||||||||||
1259 | $regexp = '/^([a-z\-]+\/[a-z0-9\-\.\+]+)(;\s.+)?$/'; |
|||||||||||
1260 | ||||||||||||
1261 | /** |
|||||||||||
1262 | * Fileinfo extension - most reliable method |
|||||||||||
1263 | * |
|||||||||||
1264 | * Apparently XAMPP, CentOS, cPanel and who knows what |
|||||||||||
1265 | * other PHP distribution channels EXPLICITLY DISABLE |
|||||||||||
1266 | * ext/fileinfo, which is otherwise enabled by default |
|||||||||||
1267 | * since PHP 5.3 ... |
|||||||||||
1268 | */ |
|||||||||||
1269 | if (function_exists('finfo_file')) |
|||||||||||
1270 | { |
|||||||||||
1271 | $finfo = @finfo_open(FILEINFO_MIME); |
|||||||||||
1272 | if (is_resource($finfo)) // It is possible that a FALSE value is returned, if there is no magic MIME database file found on the system |
|||||||||||
1273 | { |
|||||||||||
1274 | $mime = @finfo_file($finfo, $file['tmp_name']); |
|||||||||||
1275 | finfo_close($finfo); |
|||||||||||
1276 | ||||||||||||
1277 | /* According to the comments section of the PHP manual page, |
|||||||||||
1278 | * it is possible that this function returns an empty string |
|||||||||||
1279 | * for some files (e.g. if they don't exist in the magic MIME database) |
|||||||||||
1280 | */ |
|||||||||||
1281 | if (is_string($mime) && preg_match($regexp, $mime, $matches)) |
|||||||||||
1282 | { |
|||||||||||
1283 | $this->file_type = $matches[1]; |
|||||||||||
1284 | return; |
|||||||||||
1285 | } |
|||||||||||
1286 | } |
|||||||||||
1287 | } |
|||||||||||
1288 | ||||||||||||
1289 | /* This is an ugly hack, but UNIX-type systems provide a "native" way to detect the file type, |
|||||||||||
1290 | * which is still more secure than depending on the value of $_FILES[$field]['type'], and as it |
|||||||||||
1291 | * was reported in issue #750 (https://github.com/EllisLab/CodeIgniter/issues/750) - it's better |
|||||||||||
1292 | * than mime_content_type() as well, hence the attempts to try calling the command line with |
|||||||||||
1293 | * three different functions. |
|||||||||||
1294 | * |
|||||||||||
1295 | * Notes: |
|||||||||||
1296 | * - the DIRECTORY_SEPARATOR comparison ensures that we're not on a Windows system |
|||||||||||
1297 | * - many system admins would disable the exec(), shell_exec(), popen() and similar functions |
|||||||||||
1298 | * due to security concerns, hence the function_usable() checks |
|||||||||||
1299 | */ |
|||||||||||
1300 | if (DIRECTORY_SEPARATOR !== '\\') |
|||||||||||
1301 | { |
|||||||||||
1302 | $cmd = function_exists('escapeshellarg') |
|||||||||||
1303 | ? 'file --brief --mime '.escapeshellarg($file['tmp_name']).' 2>&1' |
|||||||||||
1304 | : 'file --brief --mime '.$file['tmp_name'].' 2>&1'; |
|||||||||||
1305 | ||||||||||||
1306 | if (function_usable('exec')) |
|||||||||||
1307 | { |
|||||||||||
1308 | /* This might look confusing, as $mime is being populated with all of the output when set in the second parameter. |
|||||||||||
1309 | * However, we only need the last line, which is the actual return value of exec(), and as such - it overwrites |
|||||||||||
1310 | * anything that could already be set for $mime previously. This effectively makes the second parameter a dummy |
|||||||||||
1311 | * value, which is only put to allow us to get the return status code. |
|||||||||||
1312 | */ |
|||||||||||
1313 | $mime = @exec($cmd, $mime, $return_status); |
|||||||||||
1314 | if ($return_status === 0 && is_string($mime) && preg_match($regexp, $mime, $matches)) |
|||||||||||
1315 | { |
|||||||||||
1316 | $this->file_type = $matches[1]; |
|||||||||||
1317 | return; |
|||||||||||
1318 | } |
|||||||||||
1319 | } |
|||||||||||
1320 | ||||||||||||
1321 | if ( ! ini_get('safe_mode') && function_usable('shell_exec')) |
|||||||||||
1322 | { |
|||||||||||
1323 | $mime = @shell_exec($cmd); |
|||||||||||
1324 | if (strlen($mime) > 0) |
|||||||||||
1325 | { |
|||||||||||
1326 | $mime = explode("\n", trim($mime)); |
|||||||||||
1327 | if (preg_match($regexp, $mime[(count($mime) - 1)], $matches)) |
|||||||||||
1328 | { |
|||||||||||
1329 | $this->file_type = $matches[1]; |
|||||||||||
1330 | return; |
|||||||||||
1331 | } |
|||||||||||
1332 | } |
|||||||||||
1333 | } |
|||||||||||
1334 | ||||||||||||
1335 | if (function_usable('popen')) |
|||||||||||
1336 | { |
|||||||||||
1337 | $proc = @popen($cmd, 'r'); |
|||||||||||
1338 | if (is_resource($proc)) |
|||||||||||
1339 | { |
|||||||||||
1340 | $mime = @fread($proc, 512); |
|||||||||||
1341 | @pclose($proc); |
|||||||||||
0 ignored issues
–
show
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...
|
||||||||||||
1342 | if ($mime !== FALSE) |
|||||||||||
1343 | { |
|||||||||||
1344 | $mime = explode("\n", trim($mime)); |
|||||||||||
1345 | if (preg_match($regexp, $mime[(count($mime) - 1)], $matches)) |
|||||||||||
1346 | { |
|||||||||||
1347 | $this->file_type = $matches[1]; |
|||||||||||
1348 | return; |
|||||||||||
1349 | } |
|||||||||||
1350 | } |
|||||||||||
1351 | } |
|||||||||||
1352 | } |
|||||||||||
1353 | } |
|||||||||||
1354 | ||||||||||||
1355 | // Fall back to mime_content_type(), if available (still better than $_FILES[$field]['type']) |
|||||||||||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
42% 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...
|
||||||||||||
1356 | if (function_exists('mime_content_type')) |
|||||||||||
1357 | { |
|||||||||||
1358 | $this->file_type = @mime_content_type($file['tmp_name']); |
|||||||||||
1359 | if (strlen($this->file_type) > 0) // It's possible that mime_content_type() returns FALSE or an empty string |
|||||||||||
1360 | { |
|||||||||||
1361 | return; |
|||||||||||
1362 | } |
|||||||||||
1363 | } |
|||||||||||
1364 | ||||||||||||
1365 | $this->file_type = $file['type']; |
|||||||||||
1366 | } |
|||||||||||
1367 | ||||||||||||
1368 | } |
|||||||||||
1369 |
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.