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 | * Deleted file in the 'filearchive' table. |
||
4 | * |
||
5 | * This program is free software; you can redistribute it and/or modify |
||
6 | * it under the terms of the GNU General Public License as published by |
||
7 | * the Free Software Foundation; either version 2 of the License, or |
||
8 | * (at your option) any later version. |
||
9 | * |
||
10 | * This program is distributed in the hope that it will be useful, |
||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
13 | * GNU General Public License for more details. |
||
14 | * |
||
15 | * You should have received a copy of the GNU General Public License along |
||
16 | * with this program; if not, write to the Free Software Foundation, Inc., |
||
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||
18 | * http://www.gnu.org/copyleft/gpl.html |
||
19 | * |
||
20 | * @file |
||
21 | * @ingroup FileAbstraction |
||
22 | */ |
||
23 | |||
24 | /** |
||
25 | * Class representing a row of the 'filearchive' table |
||
26 | * |
||
27 | * @ingroup FileAbstraction |
||
28 | */ |
||
29 | class ArchivedFile { |
||
30 | /** @var int Filearchive row ID */ |
||
31 | private $id; |
||
32 | |||
33 | /** @var string File name */ |
||
34 | private $name; |
||
35 | |||
36 | /** @var string FileStore storage group */ |
||
37 | private $group; |
||
38 | |||
39 | /** @var string FileStore SHA-1 key */ |
||
40 | private $key; |
||
41 | |||
42 | /** @var int File size in bytes */ |
||
43 | private $size; |
||
44 | |||
45 | /** @var int Size in bytes */ |
||
46 | private $bits; |
||
47 | |||
48 | /** @var int Width */ |
||
49 | private $width; |
||
50 | |||
51 | /** @var int Height */ |
||
52 | private $height; |
||
53 | |||
54 | /** @var string Metadata string */ |
||
55 | private $metadata; |
||
56 | |||
57 | /** @var string MIME type */ |
||
58 | private $mime; |
||
59 | |||
60 | /** @var string Media type */ |
||
61 | private $media_type; |
||
62 | |||
63 | /** @var string Upload description */ |
||
64 | private $description; |
||
65 | |||
66 | /** @var int User ID of uploader */ |
||
67 | private $user; |
||
68 | |||
69 | /** @var string User name of uploader */ |
||
70 | private $user_text; |
||
71 | |||
72 | /** @var string Time of upload */ |
||
73 | private $timestamp; |
||
74 | |||
75 | /** @var bool Whether or not all this has been loaded from the database (loadFromXxx) */ |
||
76 | private $dataLoaded; |
||
77 | |||
78 | /** @var int Bitfield akin to rev_deleted */ |
||
79 | private $deleted; |
||
80 | |||
81 | /** @var string SHA-1 hash of file content */ |
||
82 | private $sha1; |
||
83 | |||
84 | /** @var string Number of pages of a multipage document, or false for |
||
85 | * documents which aren't multipage documents |
||
86 | */ |
||
87 | private $pageCount; |
||
88 | |||
89 | /** @var string Original base filename */ |
||
90 | private $archive_name; |
||
91 | |||
92 | /** @var MediaHandler */ |
||
93 | protected $handler; |
||
94 | |||
95 | /** @var Title */ |
||
96 | protected $title; # image title |
||
97 | |||
98 | /** |
||
99 | * @throws MWException |
||
100 | * @param Title $title |
||
101 | * @param int $id |
||
102 | * @param string $key |
||
103 | * @param string $sha1 |
||
104 | */ |
||
105 | function __construct( $title, $id = 0, $key = '', $sha1 = '' ) { |
||
106 | $this->id = -1; |
||
107 | $this->title = false; |
||
0 ignored issues
–
show
|
|||
108 | $this->name = false; |
||
0 ignored issues
–
show
The property
$name was declared of type string , but false is of type false . Maybe add a type cast?
This check looks for assignments to scalar types that may be of the wrong type. To ensure the code behaves as expected, it may be a good idea to add an explicit type cast. $answer = 42;
$correct = false;
$correct = (bool) $answer;
![]() |
|||
109 | $this->group = 'deleted'; // needed for direct use of constructor |
||
110 | $this->key = ''; |
||
111 | $this->size = 0; |
||
112 | $this->bits = 0; |
||
113 | $this->width = 0; |
||
114 | $this->height = 0; |
||
115 | $this->metadata = ''; |
||
116 | $this->mime = "unknown/unknown"; |
||
117 | $this->media_type = ''; |
||
118 | $this->description = ''; |
||
119 | $this->user = 0; |
||
120 | $this->user_text = ''; |
||
121 | $this->timestamp = null; |
||
122 | $this->deleted = 0; |
||
123 | $this->dataLoaded = false; |
||
124 | $this->exists = false; |
||
0 ignored issues
–
show
The property
exists does not exist. Did you maybe forget to declare it?
In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code: class MyClass { }
$x = new MyClass();
$x->foo = true;
Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion: class MyClass {
public $foo;
}
$x = new MyClass();
$x->foo = true;
![]() |
|||
125 | $this->sha1 = ''; |
||
126 | |||
127 | if ( $title instanceof Title ) { |
||
128 | $this->title = File::normalizeTitle( $title, 'exception' ); |
||
129 | $this->name = $title->getDBkey(); |
||
130 | } |
||
131 | |||
132 | if ( $id ) { |
||
133 | $this->id = $id; |
||
134 | } |
||
135 | |||
136 | if ( $key ) { |
||
137 | $this->key = $key; |
||
138 | } |
||
139 | |||
140 | if ( $sha1 ) { |
||
141 | $this->sha1 = $sha1; |
||
142 | } |
||
143 | |||
144 | if ( !$id && !$key && !( $title instanceof Title ) && !$sha1 ) { |
||
145 | throw new MWException( "No specifications provided to ArchivedFile constructor." ); |
||
146 | } |
||
147 | } |
||
148 | |||
149 | /** |
||
150 | * Loads a file object from the filearchive table |
||
151 | * @throws MWException |
||
152 | * @return bool|null True on success or null |
||
153 | */ |
||
154 | public function load() { |
||
155 | if ( $this->dataLoaded ) { |
||
156 | return true; |
||
157 | } |
||
158 | $conds = []; |
||
159 | |||
160 | if ( $this->id > 0 ) { |
||
161 | $conds['fa_id'] = $this->id; |
||
162 | } |
||
163 | if ( $this->key ) { |
||
164 | $conds['fa_storage_group'] = $this->group; |
||
165 | $conds['fa_storage_key'] = $this->key; |
||
166 | } |
||
167 | if ( $this->title ) { |
||
168 | $conds['fa_name'] = $this->title->getDBkey(); |
||
169 | } |
||
170 | if ( $this->sha1 ) { |
||
171 | $conds['fa_sha1'] = $this->sha1; |
||
172 | } |
||
173 | |||
174 | if ( !count( $conds ) ) { |
||
175 | throw new MWException( "No specific information for retrieving archived file" ); |
||
176 | } |
||
177 | |||
178 | if ( !$this->title || $this->title->getNamespace() == NS_FILE ) { |
||
179 | $this->dataLoaded = true; // set it here, to have also true on miss |
||
180 | $dbr = wfGetDB( DB_REPLICA ); |
||
181 | $row = $dbr->selectRow( |
||
182 | 'filearchive', |
||
183 | self::selectFields(), |
||
184 | $conds, |
||
185 | __METHOD__, |
||
186 | [ 'ORDER BY' => 'fa_timestamp DESC' ] |
||
187 | ); |
||
188 | if ( !$row ) { |
||
189 | // this revision does not exist? |
||
190 | return null; |
||
191 | } |
||
192 | |||
193 | // initialize fields for filestore image object |
||
194 | $this->loadFromRow( $row ); |
||
195 | } else { |
||
196 | throw new MWException( 'This title does not correspond to an image page.' ); |
||
197 | } |
||
198 | $this->exists = true; |
||
199 | |||
200 | return true; |
||
201 | } |
||
202 | |||
203 | /** |
||
204 | * Loads a file object from the filearchive table |
||
205 | * |
||
206 | * @param stdClass $row |
||
207 | * @return ArchivedFile |
||
208 | */ |
||
209 | public static function newFromRow( $row ) { |
||
210 | $file = new ArchivedFile( Title::makeTitle( NS_FILE, $row->fa_name ) ); |
||
211 | $file->loadFromRow( $row ); |
||
212 | |||
213 | return $file; |
||
214 | } |
||
215 | |||
216 | /** |
||
217 | * Fields in the filearchive table |
||
218 | * @return array |
||
219 | */ |
||
220 | static function selectFields() { |
||
221 | return [ |
||
222 | 'fa_id', |
||
223 | 'fa_name', |
||
224 | 'fa_archive_name', |
||
225 | 'fa_storage_key', |
||
226 | 'fa_storage_group', |
||
227 | 'fa_size', |
||
228 | 'fa_bits', |
||
229 | 'fa_width', |
||
230 | 'fa_height', |
||
231 | 'fa_metadata', |
||
232 | 'fa_media_type', |
||
233 | 'fa_major_mime', |
||
234 | 'fa_minor_mime', |
||
235 | 'fa_description', |
||
236 | 'fa_user', |
||
237 | 'fa_user_text', |
||
238 | 'fa_timestamp', |
||
239 | 'fa_deleted', |
||
240 | 'fa_deleted_timestamp', /* Used by LocalFileRestoreBatch */ |
||
241 | 'fa_sha1', |
||
242 | ]; |
||
243 | } |
||
244 | |||
245 | /** |
||
246 | * Load ArchivedFile object fields from a DB row. |
||
247 | * |
||
248 | * @param stdClass $row Object database row |
||
249 | * @since 1.21 |
||
250 | */ |
||
251 | public function loadFromRow( $row ) { |
||
252 | $this->id = intval( $row->fa_id ); |
||
253 | $this->name = $row->fa_name; |
||
254 | $this->archive_name = $row->fa_archive_name; |
||
255 | $this->group = $row->fa_storage_group; |
||
256 | $this->key = $row->fa_storage_key; |
||
257 | $this->size = $row->fa_size; |
||
258 | $this->bits = $row->fa_bits; |
||
259 | $this->width = $row->fa_width; |
||
260 | $this->height = $row->fa_height; |
||
261 | $this->metadata = $row->fa_metadata; |
||
262 | $this->mime = "$row->fa_major_mime/$row->fa_minor_mime"; |
||
263 | $this->media_type = $row->fa_media_type; |
||
264 | $this->description = $row->fa_description; |
||
265 | $this->user = $row->fa_user; |
||
266 | $this->user_text = $row->fa_user_text; |
||
267 | $this->timestamp = $row->fa_timestamp; |
||
268 | $this->deleted = $row->fa_deleted; |
||
269 | if ( isset( $row->fa_sha1 ) ) { |
||
270 | $this->sha1 = $row->fa_sha1; |
||
271 | } else { |
||
272 | // old row, populate from key |
||
273 | $this->sha1 = LocalRepo::getHashFromKey( $this->key ); |
||
274 | } |
||
275 | if ( !$this->title ) { |
||
276 | $this->title = Title::makeTitleSafe( NS_FILE, $row->fa_name ); |
||
277 | } |
||
278 | } |
||
279 | |||
280 | /** |
||
281 | * Return the associated title object |
||
282 | * |
||
283 | * @return Title |
||
284 | */ |
||
285 | public function getTitle() { |
||
286 | if ( !$this->title ) { |
||
287 | $this->load(); |
||
288 | } |
||
289 | return $this->title; |
||
290 | } |
||
291 | |||
292 | /** |
||
293 | * Return the file name |
||
294 | * |
||
295 | * @return string |
||
296 | */ |
||
297 | public function getName() { |
||
298 | if ( $this->name === false ) { |
||
299 | $this->load(); |
||
300 | } |
||
301 | |||
302 | return $this->name; |
||
303 | } |
||
304 | |||
305 | /** |
||
306 | * @return int |
||
307 | */ |
||
308 | public function getID() { |
||
309 | $this->load(); |
||
310 | |||
311 | return $this->id; |
||
312 | } |
||
313 | |||
314 | /** |
||
315 | * @return bool |
||
316 | */ |
||
317 | public function exists() { |
||
318 | $this->load(); |
||
319 | |||
320 | return $this->exists; |
||
321 | } |
||
322 | |||
323 | /** |
||
324 | * Return the FileStore key |
||
325 | * @return string |
||
326 | */ |
||
327 | public function getKey() { |
||
328 | $this->load(); |
||
329 | |||
330 | return $this->key; |
||
331 | } |
||
332 | |||
333 | /** |
||
334 | * Return the FileStore key (overriding base File class) |
||
335 | * @return string |
||
336 | */ |
||
337 | public function getStorageKey() { |
||
338 | return $this->getKey(); |
||
339 | } |
||
340 | |||
341 | /** |
||
342 | * Return the FileStore storage group |
||
343 | * @return string |
||
344 | */ |
||
345 | public function getGroup() { |
||
346 | return $this->group; |
||
347 | } |
||
348 | |||
349 | /** |
||
350 | * Return the width of the image |
||
351 | * @return int |
||
352 | */ |
||
353 | public function getWidth() { |
||
354 | $this->load(); |
||
355 | |||
356 | return $this->width; |
||
357 | } |
||
358 | |||
359 | /** |
||
360 | * Return the height of the image |
||
361 | * @return int |
||
362 | */ |
||
363 | public function getHeight() { |
||
364 | $this->load(); |
||
365 | |||
366 | return $this->height; |
||
367 | } |
||
368 | |||
369 | /** |
||
370 | * Get handler-specific metadata |
||
371 | * @return string |
||
372 | */ |
||
373 | public function getMetadata() { |
||
374 | $this->load(); |
||
375 | |||
376 | return $this->metadata; |
||
377 | } |
||
378 | |||
379 | /** |
||
380 | * Return the size of the image file, in bytes |
||
381 | * @return int |
||
382 | */ |
||
383 | public function getSize() { |
||
384 | $this->load(); |
||
385 | |||
386 | return $this->size; |
||
387 | } |
||
388 | |||
389 | /** |
||
390 | * Return the bits of the image file, in bytes |
||
391 | * @return int |
||
392 | */ |
||
393 | public function getBits() { |
||
394 | $this->load(); |
||
395 | |||
396 | return $this->bits; |
||
397 | } |
||
398 | |||
399 | /** |
||
400 | * Returns the MIME type of the file. |
||
401 | * @return string |
||
402 | */ |
||
403 | public function getMimeType() { |
||
404 | $this->load(); |
||
405 | |||
406 | return $this->mime; |
||
407 | } |
||
408 | |||
409 | /** |
||
410 | * Get a MediaHandler instance for this file |
||
411 | * @return MediaHandler |
||
412 | */ |
||
413 | function getHandler() { |
||
414 | if ( !isset( $this->handler ) ) { |
||
415 | $this->handler = MediaHandler::getHandler( $this->getMimeType() ); |
||
0 ignored issues
–
show
It seems like
\MediaHandler::getHandler($this->getMimeType()) can also be of type false . However, the property $handler is declared as type object<MediaHandler> . 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;
}
![]() |
|||
416 | } |
||
417 | |||
418 | return $this->handler; |
||
419 | } |
||
420 | |||
421 | /** |
||
422 | * Returns the number of pages of a multipage document, or false for |
||
423 | * documents which aren't multipage documents |
||
424 | * @return bool|int |
||
425 | */ |
||
426 | View Code Duplication | function pageCount() { |
|
427 | if ( !isset( $this->pageCount ) ) { |
||
428 | // @FIXME: callers expect File objects |
||
429 | if ( $this->getHandler() && $this->handler->isMultiPage( $this ) ) { |
||
430 | $this->pageCount = $this->handler->pageCount( $this ); |
||
0 ignored issues
–
show
The property
$pageCount was declared of type string , but $this->handler->pageCount($this) is of type boolean . 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;
![]() |
|||
431 | } else { |
||
432 | $this->pageCount = false; |
||
0 ignored issues
–
show
The property
$pageCount was declared of type string , but false is of type false . Maybe add a type cast?
This check looks for assignments to scalar types that may be of the wrong type. To ensure the code behaves as expected, it may be a good idea to add an explicit type cast. $answer = 42;
$correct = false;
$correct = (bool) $answer;
![]() |
|||
433 | } |
||
434 | } |
||
435 | |||
436 | return $this->pageCount; |
||
437 | } |
||
438 | |||
439 | /** |
||
440 | * Return the type of the media in the file. |
||
441 | * Use the value returned by this function with the MEDIATYPE_xxx constants. |
||
442 | * @return string |
||
443 | */ |
||
444 | public function getMediaType() { |
||
445 | $this->load(); |
||
446 | |||
447 | return $this->media_type; |
||
448 | } |
||
449 | |||
450 | /** |
||
451 | * Return upload timestamp. |
||
452 | * |
||
453 | * @return string |
||
454 | */ |
||
455 | public function getTimestamp() { |
||
456 | $this->load(); |
||
457 | |||
458 | return wfTimestamp( TS_MW, $this->timestamp ); |
||
459 | } |
||
460 | |||
461 | /** |
||
462 | * Get the SHA-1 base 36 hash of the file |
||
463 | * |
||
464 | * @return string |
||
465 | * @since 1.21 |
||
466 | */ |
||
467 | function getSha1() { |
||
468 | $this->load(); |
||
469 | |||
470 | return $this->sha1; |
||
471 | } |
||
472 | |||
473 | /** |
||
474 | * Returns ID or name of user who uploaded the file |
||
475 | * |
||
476 | * @note Prior to MediaWiki 1.23, this method always |
||
477 | * returned the user id, and was inconsistent with |
||
478 | * the rest of the file classes. |
||
479 | * @param string $type 'text' or 'id' |
||
480 | * @return int|string |
||
481 | * @throws MWException |
||
482 | */ |
||
483 | public function getUser( $type = 'text' ) { |
||
484 | $this->load(); |
||
485 | |||
486 | if ( $type == 'text' ) { |
||
487 | return $this->user_text; |
||
488 | } elseif ( $type == 'id' ) { |
||
489 | return (int)$this->user; |
||
490 | } |
||
491 | |||
492 | throw new MWException( "Unknown type '$type'." ); |
||
493 | } |
||
494 | |||
495 | /** |
||
496 | * Return the user name of the uploader. |
||
497 | * |
||
498 | * @deprecated since 1.23 Use getUser( 'text' ) instead. |
||
499 | * @return string |
||
500 | */ |
||
501 | public function getUserText() { |
||
502 | wfDeprecated( __METHOD__, '1.23' ); |
||
503 | $this->load(); |
||
504 | if ( $this->isDeleted( File::DELETED_USER ) ) { |
||
505 | return 0; |
||
506 | } else { |
||
507 | return $this->user_text; |
||
508 | } |
||
509 | } |
||
510 | |||
511 | /** |
||
512 | * Return upload description. |
||
513 | * |
||
514 | * @return string |
||
515 | */ |
||
516 | public function getDescription() { |
||
517 | $this->load(); |
||
518 | if ( $this->isDeleted( File::DELETED_COMMENT ) ) { |
||
519 | return 0; |
||
520 | } else { |
||
521 | return $this->description; |
||
522 | } |
||
523 | } |
||
524 | |||
525 | /** |
||
526 | * Return the user ID of the uploader. |
||
527 | * |
||
528 | * @return int |
||
529 | */ |
||
530 | public function getRawUser() { |
||
531 | $this->load(); |
||
532 | |||
533 | return $this->user; |
||
534 | } |
||
535 | |||
536 | /** |
||
537 | * Return the user name of the uploader. |
||
538 | * |
||
539 | * @return string |
||
540 | */ |
||
541 | public function getRawUserText() { |
||
542 | $this->load(); |
||
543 | |||
544 | return $this->user_text; |
||
545 | } |
||
546 | |||
547 | /** |
||
548 | * Return upload description. |
||
549 | * |
||
550 | * @return string |
||
551 | */ |
||
552 | public function getRawDescription() { |
||
553 | $this->load(); |
||
554 | |||
555 | return $this->description; |
||
556 | } |
||
557 | |||
558 | /** |
||
559 | * Returns the deletion bitfield |
||
560 | * @return int |
||
561 | */ |
||
562 | public function getVisibility() { |
||
563 | $this->load(); |
||
564 | |||
565 | return $this->deleted; |
||
566 | } |
||
567 | |||
568 | /** |
||
569 | * for file or revision rows |
||
570 | * |
||
571 | * @param int $field One of DELETED_* bitfield constants |
||
572 | * @return bool |
||
573 | */ |
||
574 | public function isDeleted( $field ) { |
||
575 | $this->load(); |
||
576 | |||
577 | return ( $this->deleted & $field ) == $field; |
||
578 | } |
||
579 | |||
580 | /** |
||
581 | * Determine if the current user is allowed to view a particular |
||
582 | * field of this FileStore image file, if it's marked as deleted. |
||
583 | * @param int $field |
||
584 | * @param null|User $user User object to check, or null to use $wgUser |
||
585 | * @return bool |
||
586 | */ |
||
587 | public function userCan( $field, User $user = null ) { |
||
588 | $this->load(); |
||
589 | |||
590 | $title = $this->getTitle(); |
||
591 | return Revision::userCanBitfield( $this->deleted, $field, $user, $title ?: null ); |
||
592 | } |
||
593 | } |
||
594 |
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.
Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..