This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace florinp\messenger\libs; |
||
4 | |||
5 | use finfo; |
||
6 | use Exception; |
||
7 | |||
8 | /** |
||
9 | * Simple PHP upload class |
||
10 | * |
||
11 | * @author Aivis Silins |
||
12 | */ |
||
13 | class upload |
||
14 | { |
||
15 | |||
16 | /** |
||
17 | * Default directory persmissions (destination dir) |
||
18 | */ |
||
19 | protected $default_permissions = 750; |
||
20 | |||
21 | |||
22 | /** |
||
23 | * File post array |
||
24 | * |
||
25 | * @var array |
||
26 | */ |
||
27 | protected $files_post = array(); |
||
28 | |||
29 | |||
30 | /** |
||
31 | * Destination directory |
||
32 | * |
||
33 | * @var string |
||
34 | */ |
||
35 | protected $destination; |
||
36 | |||
37 | |||
38 | /** |
||
39 | * Fileinfo |
||
40 | * |
||
41 | * @var object |
||
42 | */ |
||
43 | protected $finfo; |
||
44 | |||
45 | |||
46 | /** |
||
47 | * Data about file |
||
48 | * |
||
49 | * @var array |
||
50 | */ |
||
51 | public $file = array(); |
||
52 | |||
53 | |||
54 | /** |
||
55 | * Max. file size |
||
56 | * |
||
57 | * @var int |
||
58 | */ |
||
59 | protected $max_file_size; |
||
60 | |||
61 | |||
62 | /** |
||
63 | * Allowed mime types |
||
64 | * |
||
65 | * @var array |
||
66 | */ |
||
67 | protected $mimes = array(); |
||
68 | |||
69 | |||
70 | /** |
||
71 | * External callback object |
||
72 | * |
||
73 | * @var obejct |
||
74 | */ |
||
75 | protected $external_callback_object; |
||
76 | |||
77 | |||
78 | /** |
||
79 | * External callback methods |
||
80 | * |
||
81 | * @var array |
||
82 | */ |
||
83 | protected $external_callback_methods = array(); |
||
84 | |||
85 | |||
86 | /** |
||
87 | * Temp path |
||
88 | * |
||
89 | * @var string |
||
90 | */ |
||
91 | protected $tmp_name; |
||
92 | |||
93 | |||
94 | /** |
||
95 | * Validation errors |
||
96 | * |
||
97 | * @var array |
||
98 | */ |
||
99 | protected $validation_errors = array(); |
||
100 | |||
101 | |||
102 | /** |
||
103 | * Filename (new) |
||
104 | * |
||
105 | * @var string |
||
106 | */ |
||
107 | protected $filename; |
||
108 | |||
109 | /** |
||
110 | * File extension |
||
111 | * @var string |
||
112 | */ |
||
113 | protected $extension; |
||
114 | |||
115 | /** |
||
116 | * Internal callbacks (filesize check, mime, etc) |
||
117 | * |
||
118 | * @var array |
||
119 | */ |
||
120 | private $callbacks = array(); |
||
121 | |||
122 | /** |
||
123 | * Root dir |
||
124 | * |
||
125 | * @var string |
||
126 | */ |
||
127 | protected $root; |
||
128 | |||
129 | /** |
||
130 | * Return upload object |
||
131 | * |
||
132 | * $destination = 'path/to/your/file/destination/folder'; |
||
133 | * |
||
134 | * @param string $phpbb_root_path |
||
135 | * @return Upload |
||
136 | */ |
||
137 | public static function factory($phpbb_root_path) |
||
138 | { |
||
139 | return new Upload($phpbb_root_path); |
||
140 | } |
||
141 | |||
142 | /** |
||
143 | * Define ROOT constant and set & create destination path |
||
144 | * |
||
145 | * @param string $phpbb_root_path |
||
146 | * @throws Exception |
||
147 | */ |
||
148 | public function __construct($phpbb_root_path) |
||
149 | { |
||
150 | $phpbb_root_path = $phpbb_root_path.'store/messenger/files'; |
||
151 | // set & create destination path |
||
152 | if (!$this->set_destination($phpbb_root_path)) { |
||
153 | throw new Exception('Upload: Can\'t create destination. '.$this->root.$this->destination); |
||
154 | } |
||
155 | |||
156 | //create finfo object |
||
157 | $this->finfo = new finfo(); |
||
158 | } |
||
159 | |||
160 | /** |
||
161 | * Set target filename |
||
162 | * |
||
163 | * @param string $filename |
||
164 | */ |
||
165 | public function set_filename($filename) |
||
166 | { |
||
167 | $this->filename = $filename; |
||
168 | } |
||
169 | |||
170 | /** |
||
171 | * Check & Save file |
||
172 | * |
||
173 | * Return data about current upload |
||
174 | * |
||
175 | * @return array |
||
176 | */ |
||
177 | public function upload($filename = '') |
||
0 ignored issues
–
show
|
|||
178 | { |
||
179 | if ($this->check()) { |
||
180 | $this->save(); |
||
181 | } |
||
182 | // return state data |
||
183 | return $this->get_state(); |
||
184 | } |
||
185 | |||
186 | |||
187 | /** |
||
188 | * Save file on server |
||
189 | * |
||
190 | * Return state data |
||
191 | * |
||
192 | * @return array |
||
193 | */ |
||
194 | public function save() |
||
195 | { |
||
196 | $this->save_file(); |
||
197 | return $this->get_state(); |
||
198 | } |
||
199 | |||
200 | |||
201 | /** |
||
202 | * Validate file (execute callbacks) |
||
203 | * |
||
204 | * Returns TRUE if validation successful |
||
205 | * |
||
206 | * @return bool |
||
207 | */ |
||
208 | public function check() |
||
209 | { |
||
210 | //execute callbacks (check filesize, mime, also external callbacks |
||
211 | $this->validate(); |
||
212 | |||
213 | //add error messages |
||
214 | $this->file['errors'] = $this->get_errors(); |
||
215 | |||
216 | //change file validation status |
||
217 | $this->file['status'] = empty($this->validation_errors); |
||
218 | |||
219 | return $this->file['status']; |
||
220 | } |
||
221 | |||
222 | /** |
||
223 | * Get current state data |
||
224 | * |
||
225 | * @return array |
||
226 | */ |
||
227 | public function get_state() |
||
228 | { |
||
229 | return $this->file; |
||
230 | } |
||
231 | |||
232 | |||
233 | /** |
||
234 | * Save file on server |
||
235 | */ |
||
236 | protected function save_file() |
||
237 | { |
||
238 | //create & set new filename |
||
239 | if (empty($this->filename)) { |
||
240 | $this->create_new_filename(); |
||
241 | } |
||
242 | |||
243 | //set filename |
||
244 | $this->file['filename'] = $this->filename; |
||
245 | |||
246 | //set full path |
||
247 | $this->file['full_path'] = $this->root.$this->destination.$this->filename; |
||
248 | $this->file['path'] = $this->destination.$this->filename; |
||
249 | |||
250 | $status = move_uploaded_file($this->tmp_name, $this->file['full_path']); |
||
251 | |||
252 | //checks whether upload successful |
||
253 | if (!$status) { |
||
254 | throw new Exception('Upload: Can\'t upload file.'); |
||
255 | } |
||
256 | |||
257 | //done |
||
258 | $this->file['status'] = true; |
||
259 | } |
||
260 | |||
261 | /** |
||
262 | * Set data about file |
||
263 | */ |
||
264 | protected function set_file_data() |
||
265 | { |
||
266 | $file_size = $this->get_file_size(); |
||
267 | |||
268 | $this->file = array( |
||
269 | 'status' => false, |
||
270 | 'destination' => $this->destination, |
||
271 | 'size_in_bytes' => $file_size, |
||
272 | 'size_in_mb' => $this->bytes_to_mb($file_size), |
||
273 | 'mime' => $this->get_file_mime(), |
||
274 | 'original_filename' => $this->file_post['name'], |
||
0 ignored issues
–
show
The property
file_post does not seem to exist. Did you mean files_post ?
An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name. If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading. ![]() |
|||
275 | 'tmp_name' => $this->file_post['tmp_name'], |
||
0 ignored issues
–
show
The property
file_post does not seem to exist. Did you mean files_post ?
An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name. If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading. ![]() |
|||
276 | 'post_data' => $this->file_post, |
||
0 ignored issues
–
show
The property
file_post does not seem to exist. Did you mean files_post ?
An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name. If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading. ![]() |
|||
277 | ); |
||
278 | } |
||
279 | |||
280 | /** |
||
281 | * Set validation error |
||
282 | * |
||
283 | * @param string $message |
||
284 | */ |
||
285 | public function set_error($message) |
||
286 | { |
||
287 | $this->validation_errors[] = $message; |
||
288 | } |
||
289 | |||
290 | /** |
||
291 | * Return validation errors |
||
292 | * |
||
293 | * @return array |
||
294 | */ |
||
295 | public function get_errors() |
||
296 | { |
||
297 | return $this->validation_errors; |
||
298 | } |
||
299 | |||
300 | /** |
||
301 | * Set external callback methods |
||
302 | * |
||
303 | * @param object $instance_of_callback_object |
||
304 | * @param array $callback_methods |
||
305 | * @throws Exception |
||
306 | */ |
||
307 | public function callbacks($instance_of_callback_object, $callback_methods) |
||
308 | { |
||
309 | if (empty($instance_of_callback_object)) { |
||
310 | throw new Exception('Upload: $instance_of_callback_object can\'t be empty.'); |
||
311 | } |
||
312 | |||
313 | if (!is_array($callback_methods)) { |
||
314 | throw new Exception('Upload: $callback_methods data type need to be array.'); |
||
315 | } |
||
316 | |||
317 | $this->external_callback_object = $instance_of_callback_object; |
||
318 | $this->external_callback_methods = $callback_methods; |
||
319 | } |
||
320 | |||
321 | /** |
||
322 | * Execute callbacks |
||
323 | */ |
||
324 | protected function validate() |
||
325 | { |
||
326 | //get curent errors |
||
327 | $errors = $this->get_errors(); |
||
328 | |||
329 | if (empty($errors)) { |
||
330 | //set data about current file |
||
331 | $this->set_file_data(); |
||
332 | |||
333 | //execute internal callbacks |
||
334 | $this->execute_callbacks($this->callbacks, $this); |
||
335 | |||
336 | //execute external callbacks |
||
337 | $this->execute_callbacks($this->external_callback_methods, $this->external_callback_object); |
||
338 | } |
||
339 | } |
||
340 | |||
341 | /** |
||
342 | * Execute callbacks |
||
343 | */ |
||
344 | protected function execute_callbacks($callbacks, $object) |
||
345 | { |
||
346 | foreach ($callbacks as $method) { |
||
347 | $object->$method($this); |
||
348 | } |
||
349 | } |
||
350 | |||
351 | /** |
||
352 | * File mime type validation callback |
||
353 | * |
||
354 | * @param mixed $object |
||
355 | */ |
||
356 | protected function check_mime_type($object) |
||
357 | { |
||
358 | if (!empty($object->mimes)) { |
||
359 | if (!in_array($object->file['mime'], $object->mimes)) { |
||
360 | $object->set_error('Mime type not allowed.'); |
||
361 | } |
||
362 | } |
||
363 | } |
||
364 | |||
365 | /** |
||
366 | * Set allowed mime types |
||
367 | * |
||
368 | * @param string[] $mimes |
||
369 | */ |
||
370 | public function set_allowed_mime_types($mimes) |
||
371 | { |
||
372 | $this->mimes = $mimes; |
||
373 | //if mime types is set -> set callback |
||
374 | $this->callbacks[] = 'check_mime_type'; |
||
375 | } |
||
376 | |||
377 | /** |
||
378 | * File size validation callback |
||
379 | * |
||
380 | * @param object $object |
||
381 | */ |
||
382 | protected function check_file_size($object) |
||
383 | { |
||
384 | if (!empty($object->max_file_size)) { |
||
385 | $file_size_in_mb = $this->bytes_to_mb($object->file['size_in_bytes']); |
||
386 | if ($object->max_file_size <= $file_size_in_mb) { |
||
387 | $object->set_error('File is too big.'); |
||
388 | } |
||
389 | } |
||
390 | } |
||
391 | |||
392 | /** |
||
393 | * Set max. file size |
||
394 | * |
||
395 | * @param int $size |
||
396 | */ |
||
397 | public function set_max_file_size($size) |
||
398 | { |
||
399 | $this->max_file_size = $size; |
||
400 | //if max file size is set -> set callback |
||
401 | $this->callbacks[] = 'check_file_size'; |
||
402 | } |
||
403 | |||
404 | /** |
||
405 | * Set File array to object |
||
406 | * |
||
407 | * @param array $file |
||
408 | */ |
||
409 | public function file($file) |
||
410 | { |
||
411 | $this->set_file_array($file); |
||
412 | } |
||
413 | |||
414 | /** |
||
415 | * Set file array |
||
416 | * |
||
417 | * @param array $file |
||
418 | */ |
||
419 | protected function set_file_array($file) |
||
420 | { |
||
421 | //checks whether file array is valid |
||
422 | if (!$this->check_file_array($file)) { |
||
423 | //file not selected or some bigger problems (broken files array) |
||
424 | $this->set_error('Please select file.'); |
||
425 | } |
||
426 | |||
427 | //set file data |
||
428 | $this->file_post = $file; |
||
0 ignored issues
–
show
The property
file_post does not seem to exist. Did you mean files_post ?
An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name. If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading. ![]() |
|||
429 | |||
430 | //set tmp path |
||
431 | $this->tmp_name = $file['tmp_name']; |
||
432 | |||
433 | // set file extension |
||
434 | $this->extension = pathinfo($file['name'], PATHINFO_EXTENSION); |
||
435 | } |
||
436 | |||
437 | /** |
||
438 | * Checks whether Files post array is valid |
||
439 | * |
||
440 | * @return bool |
||
441 | */ |
||
442 | protected function check_file_array($file) |
||
443 | { |
||
444 | return isset($file['error']) |
||
445 | && !empty($file['name']) |
||
446 | && !empty($file['type']) |
||
447 | && !empty($file['tmp_name']) |
||
448 | && !empty($file['size']); |
||
449 | } |
||
450 | |||
451 | /** |
||
452 | * Get file mime type |
||
453 | * |
||
454 | * @return string |
||
455 | */ |
||
456 | protected function get_file_mime() |
||
457 | { |
||
458 | return $this->finfo->file($this->tmp_name, FILEINFO_MIME_TYPE); |
||
459 | } |
||
460 | |||
461 | /** |
||
462 | * Get file size |
||
463 | * |
||
464 | * @return int |
||
465 | */ |
||
466 | protected function get_file_size() |
||
467 | { |
||
468 | return filesize($this->tmp_name); |
||
469 | } |
||
470 | |||
471 | /** |
||
472 | * Set destination path (return TRUE on success) |
||
473 | * |
||
474 | * @param string $destination |
||
475 | * @return bool |
||
476 | */ |
||
477 | protected function set_destination($destination) |
||
478 | { |
||
479 | $this->destination = $destination.DIRECTORY_SEPARATOR; |
||
480 | return $this->destination_exist() ? TRUE : $this->create_destination(); |
||
481 | } |
||
482 | |||
483 | /** |
||
484 | * Checks whether destination folder exists |
||
485 | * |
||
486 | * @return bool |
||
487 | */ |
||
488 | protected function destination_exist() |
||
489 | { |
||
490 | return is_writable($this->root.$this->destination); |
||
491 | } |
||
492 | |||
493 | /** |
||
494 | * Create path to destination |
||
495 | * |
||
496 | * @return bool |
||
497 | */ |
||
498 | protected function create_destination() |
||
499 | { |
||
500 | return mkdir($this->root.$this->destination, $this->default_permissions, true); |
||
501 | } |
||
502 | |||
503 | /** |
||
504 | * Set unique filename |
||
505 | * |
||
506 | * @return string |
||
507 | */ |
||
508 | protected function create_new_filename() |
||
509 | { |
||
510 | $filename = sha1(mt_rand(1, 9999).$this->destination.uniqid()).time().'.'.$this->extension; |
||
511 | $this->set_filename($filename); |
||
512 | } |
||
513 | |||
514 | /** |
||
515 | * Convert bytes to mb. |
||
516 | * |
||
517 | * @param int $bytes |
||
518 | * @return double |
||
519 | */ |
||
520 | protected function bytes_to_mb($bytes) |
||
521 | { |
||
522 | return round(($bytes / 1048576), 2); |
||
523 | } |
||
524 | |||
525 | |||
526 | } // end of Upload |
This check looks from parameters that have been defined for a function or method, but which are not used in the method body.