wikimedia /
mediawiki
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 | * Old file in the oldimage 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 to represent a file in the oldimage table |
||
| 26 | * |
||
| 27 | * @ingroup FileAbstraction |
||
| 28 | */ |
||
| 29 | class OldLocalFile extends LocalFile { |
||
| 30 | /** @var string Timestamp */ |
||
| 31 | protected $requestedTime; |
||
| 32 | |||
| 33 | /** @var string Archive name */ |
||
| 34 | protected $archive_name; |
||
| 35 | |||
| 36 | const CACHE_VERSION = 1; |
||
| 37 | const MAX_CACHE_ROWS = 20; |
||
| 38 | |||
| 39 | /** |
||
| 40 | * @param Title $title |
||
| 41 | * @param FileRepo $repo |
||
| 42 | * @param null|int $time Timestamp or null |
||
| 43 | * @return OldLocalFile |
||
| 44 | * @throws MWException |
||
| 45 | */ |
||
| 46 | static function newFromTitle( $title, $repo, $time = null ) { |
||
| 47 | # The null default value is only here to avoid an E_STRICT |
||
| 48 | if ( $time === null ) { |
||
| 49 | throw new MWException( __METHOD__ . ' got null for $time parameter' ); |
||
| 50 | } |
||
| 51 | |||
| 52 | return new self( $title, $repo, $time, null ); |
||
| 53 | } |
||
| 54 | |||
| 55 | /** |
||
| 56 | * @param Title $title |
||
| 57 | * @param FileRepo $repo |
||
| 58 | * @param string $archiveName |
||
| 59 | * @return OldLocalFile |
||
| 60 | */ |
||
| 61 | static function newFromArchiveName( $title, $repo, $archiveName ) { |
||
| 62 | return new self( $title, $repo, null, $archiveName ); |
||
| 63 | } |
||
| 64 | |||
| 65 | /** |
||
| 66 | * @param stdClass $row |
||
| 67 | * @param FileRepo $repo |
||
| 68 | * @return OldLocalFile |
||
| 69 | */ |
||
| 70 | static function newFromRow( $row, $repo ) { |
||
| 71 | $title = Title::makeTitle( NS_FILE, $row->oi_name ); |
||
| 72 | $file = new self( $title, $repo, null, $row->oi_archive_name ); |
||
| 73 | $file->loadFromRow( $row, 'oi_' ); |
||
| 74 | |||
| 75 | return $file; |
||
| 76 | } |
||
| 77 | |||
| 78 | /** |
||
| 79 | * Create a OldLocalFile from a SHA-1 key |
||
| 80 | * Do not call this except from inside a repo class. |
||
| 81 | * |
||
| 82 | * @param string $sha1 Base-36 SHA-1 |
||
| 83 | * @param LocalRepo $repo |
||
| 84 | * @param string|bool $timestamp MW_timestamp (optional) |
||
| 85 | * |
||
| 86 | * @return bool|OldLocalFile |
||
| 87 | */ |
||
| 88 | View Code Duplication | static function newFromKey( $sha1, $repo, $timestamp = false ) { |
|
| 89 | $dbr = $repo->getSlaveDB(); |
||
| 90 | |||
| 91 | $conds = [ 'oi_sha1' => $sha1 ]; |
||
| 92 | if ( $timestamp ) { |
||
| 93 | $conds['oi_timestamp'] = $dbr->timestamp( $timestamp ); |
||
| 94 | } |
||
| 95 | |||
| 96 | $row = $dbr->selectRow( 'oldimage', self::selectFields(), $conds, __METHOD__ ); |
||
| 97 | if ( $row ) { |
||
| 98 | return self::newFromRow( $row, $repo ); |
||
| 99 | } else { |
||
| 100 | return false; |
||
| 101 | } |
||
| 102 | } |
||
| 103 | |||
| 104 | /** |
||
| 105 | * Fields in the oldimage table |
||
| 106 | * @return array |
||
| 107 | */ |
||
| 108 | static function selectFields() { |
||
| 109 | return [ |
||
| 110 | 'oi_name', |
||
| 111 | 'oi_archive_name', |
||
| 112 | 'oi_size', |
||
| 113 | 'oi_width', |
||
| 114 | 'oi_height', |
||
| 115 | 'oi_metadata', |
||
| 116 | 'oi_bits', |
||
| 117 | 'oi_media_type', |
||
| 118 | 'oi_major_mime', |
||
| 119 | 'oi_minor_mime', |
||
| 120 | 'oi_description', |
||
| 121 | 'oi_user', |
||
| 122 | 'oi_user_text', |
||
| 123 | 'oi_timestamp', |
||
| 124 | 'oi_deleted', |
||
| 125 | 'oi_sha1', |
||
| 126 | ]; |
||
| 127 | } |
||
| 128 | |||
| 129 | /** |
||
| 130 | * @param Title $title |
||
| 131 | * @param FileRepo $repo |
||
| 132 | * @param string $time Timestamp or null to load by archive name |
||
| 133 | * @param string $archiveName Archive name or null to load by timestamp |
||
| 134 | * @throws MWException |
||
| 135 | */ |
||
| 136 | function __construct( $title, $repo, $time, $archiveName ) { |
||
| 137 | parent::__construct( $title, $repo ); |
||
| 138 | $this->requestedTime = $time; |
||
| 139 | $this->archive_name = $archiveName; |
||
| 140 | if ( is_null( $time ) && is_null( $archiveName ) ) { |
||
| 141 | throw new MWException( __METHOD__ . ': must specify at least one of $time or $archiveName' ); |
||
| 142 | } |
||
| 143 | } |
||
| 144 | |||
| 145 | /** |
||
| 146 | * @return bool |
||
| 147 | */ |
||
| 148 | function getCacheKey() { |
||
| 149 | return false; |
||
| 150 | } |
||
| 151 | |||
| 152 | /** |
||
| 153 | * @return string |
||
| 154 | */ |
||
| 155 | function getArchiveName() { |
||
| 156 | if ( !isset( $this->archive_name ) ) { |
||
| 157 | $this->load(); |
||
| 158 | } |
||
| 159 | |||
| 160 | return $this->archive_name; |
||
| 161 | } |
||
| 162 | |||
| 163 | /** |
||
| 164 | * @return bool |
||
| 165 | */ |
||
| 166 | function isOld() { |
||
| 167 | return true; |
||
| 168 | } |
||
| 169 | |||
| 170 | /** |
||
| 171 | * @return bool |
||
| 172 | */ |
||
| 173 | function isVisible() { |
||
| 174 | return $this->exists() && !$this->isDeleted( File::DELETED_FILE ); |
||
| 175 | } |
||
| 176 | |||
| 177 | function loadFromDB( $flags = 0 ) { |
||
| 178 | $this->dataLoaded = true; |
||
| 179 | |||
| 180 | $dbr = ( $flags & self::READ_LATEST ) |
||
| 181 | ? $this->repo->getMasterDB() |
||
|
0 ignored issues
–
show
|
|||
| 182 | : $this->repo->getSlaveDB(); |
||
|
0 ignored issues
–
show
The method
getSlaveDB does only exist in LocalRepo, but not in FileRepo and ForeignAPIRepo.
It seems like the method you are trying to call exists only in some of the possible types. Let’s take a look at an example: class A
{
public function foo() { }
}
class B extends A
{
public function bar() { }
}
/**
* @param A|B $x
*/
function someFunction($x)
{
$x->foo(); // This call is fine as the method exists in A and B.
$x->bar(); // This method only exists in B and might cause an error.
}
Available Fixes
Loading history...
|
|||
| 183 | |||
| 184 | $conds = [ 'oi_name' => $this->getName() ]; |
||
| 185 | View Code Duplication | if ( is_null( $this->requestedTime ) ) { |
|
| 186 | $conds['oi_archive_name'] = $this->archive_name; |
||
| 187 | } else { |
||
| 188 | $conds['oi_timestamp'] = $dbr->timestamp( $this->requestedTime ); |
||
| 189 | } |
||
| 190 | $row = $dbr->selectRow( 'oldimage', $this->getCacheFields( 'oi_' ), |
||
| 191 | $conds, __METHOD__, [ 'ORDER BY' => 'oi_timestamp DESC' ] ); |
||
| 192 | if ( $row ) { |
||
| 193 | $this->loadFromRow( $row, 'oi_' ); |
||
| 194 | } else { |
||
| 195 | $this->fileExists = false; |
||
| 196 | } |
||
| 197 | } |
||
| 198 | |||
| 199 | /** |
||
| 200 | * Load lazy file metadata from the DB |
||
| 201 | */ |
||
| 202 | protected function loadExtraFromDB() { |
||
| 203 | $this->extraDataLoaded = true; |
||
| 204 | $dbr = $this->repo->getSlaveDB(); |
||
|
0 ignored issues
–
show
The method
getSlaveDB does only exist in LocalRepo, but not in FileRepo and ForeignAPIRepo.
It seems like the method you are trying to call exists only in some of the possible types. Let’s take a look at an example: class A
{
public function foo() { }
}
class B extends A
{
public function bar() { }
}
/**
* @param A|B $x
*/
function someFunction($x)
{
$x->foo(); // This call is fine as the method exists in A and B.
$x->bar(); // This method only exists in B and might cause an error.
}
Available Fixes
Loading history...
|
|||
| 205 | $conds = [ 'oi_name' => $this->getName() ]; |
||
| 206 | View Code Duplication | if ( is_null( $this->requestedTime ) ) { |
|
| 207 | $conds['oi_archive_name'] = $this->archive_name; |
||
| 208 | } else { |
||
| 209 | $conds['oi_timestamp'] = $dbr->timestamp( $this->requestedTime ); |
||
| 210 | } |
||
| 211 | // In theory the file could have just been renamed/deleted...oh well |
||
| 212 | $row = $dbr->selectRow( 'oldimage', $this->getLazyCacheFields( 'oi_' ), |
||
| 213 | $conds, __METHOD__, [ 'ORDER BY' => 'oi_timestamp DESC' ] ); |
||
| 214 | |||
| 215 | if ( !$row ) { // fallback to master |
||
| 216 | $dbr = $this->repo->getMasterDB(); |
||
|
0 ignored issues
–
show
The method
getMasterDB does only exist in LocalRepo, but not in FileRepo and ForeignAPIRepo.
It seems like the method you are trying to call exists only in some of the possible types. Let’s take a look at an example: class A
{
public function foo() { }
}
class B extends A
{
public function bar() { }
}
/**
* @param A|B $x
*/
function someFunction($x)
{
$x->foo(); // This call is fine as the method exists in A and B.
$x->bar(); // This method only exists in B and might cause an error.
}
Available Fixes
Loading history...
|
|||
| 217 | $row = $dbr->selectRow( 'oldimage', $this->getLazyCacheFields( 'oi_' ), |
||
| 218 | $conds, __METHOD__, [ 'ORDER BY' => 'oi_timestamp DESC' ] ); |
||
| 219 | } |
||
| 220 | |||
| 221 | if ( $row ) { |
||
| 222 | foreach ( $this->unprefixRow( $row, 'oi_' ) as $name => $value ) { |
||
| 223 | $this->$name = $value; |
||
| 224 | } |
||
| 225 | } else { |
||
| 226 | throw new MWException( "Could not find data for image '{$this->archive_name}'." ); |
||
| 227 | } |
||
| 228 | } |
||
| 229 | |||
| 230 | /** |
||
| 231 | * @param string $prefix |
||
| 232 | * @return array |
||
| 233 | */ |
||
| 234 | function getCacheFields( $prefix = 'img_' ) { |
||
| 235 | $fields = parent::getCacheFields( $prefix ); |
||
| 236 | $fields[] = $prefix . 'archive_name'; |
||
| 237 | $fields[] = $prefix . 'deleted'; |
||
| 238 | |||
| 239 | return $fields; |
||
| 240 | } |
||
| 241 | |||
| 242 | /** |
||
| 243 | * @return string |
||
| 244 | */ |
||
| 245 | function getRel() { |
||
| 246 | return 'archive/' . $this->getHashPath() . $this->getArchiveName(); |
||
| 247 | } |
||
| 248 | |||
| 249 | /** |
||
| 250 | * @return string |
||
| 251 | */ |
||
| 252 | function getUrlRel() { |
||
| 253 | return 'archive/' . $this->getHashPath() . rawurlencode( $this->getArchiveName() ); |
||
| 254 | } |
||
| 255 | |||
| 256 | function upgradeRow() { |
||
| 257 | $this->loadFromFile(); |
||
| 258 | |||
| 259 | # Don't destroy file info of missing files |
||
| 260 | if ( !$this->fileExists ) { |
||
| 261 | wfDebug( __METHOD__ . ": file does not exist, aborting\n" ); |
||
| 262 | |||
| 263 | return; |
||
| 264 | } |
||
| 265 | |||
| 266 | $dbw = $this->repo->getMasterDB(); |
||
|
0 ignored issues
–
show
The method
getMasterDB does only exist in LocalRepo, but not in FileRepo and ForeignAPIRepo.
It seems like the method you are trying to call exists only in some of the possible types. Let’s take a look at an example: class A
{
public function foo() { }
}
class B extends A
{
public function bar() { }
}
/**
* @param A|B $x
*/
function someFunction($x)
{
$x->foo(); // This call is fine as the method exists in A and B.
$x->bar(); // This method only exists in B and might cause an error.
}
Available Fixes
Loading history...
|
|||
| 267 | list( $major, $minor ) = self::splitMime( $this->mime ); |
||
| 268 | |||
| 269 | wfDebug( __METHOD__ . ': upgrading ' . $this->archive_name . " to the current schema\n" ); |
||
| 270 | $dbw->update( 'oldimage', |
||
| 271 | [ |
||
| 272 | 'oi_size' => $this->size, // sanity |
||
| 273 | 'oi_width' => $this->width, |
||
| 274 | 'oi_height' => $this->height, |
||
| 275 | 'oi_bits' => $this->bits, |
||
| 276 | 'oi_media_type' => $this->media_type, |
||
| 277 | 'oi_major_mime' => $major, |
||
| 278 | 'oi_minor_mime' => $minor, |
||
| 279 | 'oi_metadata' => $this->metadata, |
||
| 280 | 'oi_sha1' => $this->sha1, |
||
| 281 | ], [ |
||
| 282 | 'oi_name' => $this->getName(), |
||
| 283 | 'oi_archive_name' => $this->archive_name ], |
||
| 284 | __METHOD__ |
||
| 285 | ); |
||
| 286 | } |
||
| 287 | |||
| 288 | /** |
||
| 289 | * @param int $field One of DELETED_* bitfield constants for file or |
||
| 290 | * revision rows |
||
| 291 | * @return bool |
||
| 292 | */ |
||
| 293 | function isDeleted( $field ) { |
||
| 294 | $this->load(); |
||
| 295 | |||
| 296 | return ( $this->deleted & $field ) == $field; |
||
| 297 | } |
||
| 298 | |||
| 299 | /** |
||
| 300 | * Returns bitfield value |
||
| 301 | * @return int |
||
| 302 | */ |
||
| 303 | function getVisibility() { |
||
| 304 | $this->load(); |
||
| 305 | |||
| 306 | return (int)$this->deleted; |
||
| 307 | } |
||
| 308 | |||
| 309 | /** |
||
| 310 | * Determine if the current user is allowed to view a particular |
||
| 311 | * field of this image file, if it's marked as deleted. |
||
| 312 | * |
||
| 313 | * @param int $field |
||
| 314 | * @param User|null $user User object to check, or null to use $wgUser |
||
| 315 | * @return bool |
||
| 316 | */ |
||
| 317 | function userCan( $field, User $user = null ) { |
||
| 318 | $this->load(); |
||
| 319 | |||
| 320 | return Revision::userCanBitfield( $this->deleted, $field, $user ); |
||
| 321 | } |
||
| 322 | |||
| 323 | /** |
||
| 324 | * Upload a file directly into archive. Generally for Special:Import. |
||
| 325 | * |
||
| 326 | * @param string $srcPath File system path of the source file |
||
| 327 | * @param string $archiveName Full archive name of the file, in the form |
||
| 328 | * $timestamp!$filename, where $filename must match $this->getName() |
||
| 329 | * @param string $timestamp |
||
| 330 | * @param string $comment |
||
| 331 | * @param User $user |
||
| 332 | * @return Status |
||
| 333 | */ |
||
| 334 | function uploadOld( $srcPath, $archiveName, $timestamp, $comment, $user ) { |
||
| 335 | $this->lock(); |
||
| 336 | |||
| 337 | $dstRel = 'archive/' . $this->getHashPath() . $archiveName; |
||
| 338 | $status = $this->publishTo( $srcPath, $dstRel ); |
||
| 339 | |||
| 340 | if ( $status->isGood() ) { |
||
| 341 | if ( !$this->recordOldUpload( $srcPath, $archiveName, $timestamp, $comment, $user ) ) { |
||
| 342 | $status->fatal( 'filenotfound', $srcPath ); |
||
| 343 | } |
||
| 344 | } |
||
| 345 | |||
| 346 | $this->unlock(); |
||
| 347 | |||
| 348 | return $status; |
||
| 349 | } |
||
| 350 | |||
| 351 | /** |
||
| 352 | * Record a file upload in the oldimage table, without adding log entries. |
||
| 353 | * |
||
| 354 | * @param string $srcPath File system path to the source file |
||
| 355 | * @param string $archiveName The archive name of the file |
||
| 356 | * @param string $timestamp |
||
| 357 | * @param string $comment Upload comment |
||
| 358 | * @param User $user User who did this upload |
||
| 359 | * @return bool |
||
| 360 | */ |
||
| 361 | protected function recordOldUpload( $srcPath, $archiveName, $timestamp, $comment, $user ) { |
||
| 362 | $dbw = $this->repo->getMasterDB(); |
||
|
0 ignored issues
–
show
The method
getMasterDB does only exist in LocalRepo, but not in FileRepo and ForeignAPIRepo.
It seems like the method you are trying to call exists only in some of the possible types. Let’s take a look at an example: class A
{
public function foo() { }
}
class B extends A
{
public function bar() { }
}
/**
* @param A|B $x
*/
function someFunction($x)
{
$x->foo(); // This call is fine as the method exists in A and B.
$x->bar(); // This method only exists in B and might cause an error.
}
Available Fixes
Loading history...
|
|||
| 363 | |||
| 364 | $dstPath = $this->repo->getZonePath( 'public' ) . '/' . $this->getRel(); |
||
| 365 | $props = $this->repo->getFileProps( $dstPath ); |
||
| 366 | if ( !$props['fileExists'] ) { |
||
| 367 | return false; |
||
| 368 | } |
||
| 369 | |||
| 370 | $dbw->insert( 'oldimage', |
||
| 371 | [ |
||
| 372 | 'oi_name' => $this->getName(), |
||
| 373 | 'oi_archive_name' => $archiveName, |
||
| 374 | 'oi_size' => $props['size'], |
||
| 375 | 'oi_width' => intval( $props['width'] ), |
||
| 376 | 'oi_height' => intval( $props['height'] ), |
||
| 377 | 'oi_bits' => $props['bits'], |
||
| 378 | 'oi_timestamp' => $dbw->timestamp( $timestamp ), |
||
| 379 | 'oi_description' => $comment, |
||
| 380 | 'oi_user' => $user->getId(), |
||
| 381 | 'oi_user_text' => $user->getName(), |
||
| 382 | 'oi_metadata' => $props['metadata'], |
||
| 383 | 'oi_media_type' => $props['media_type'], |
||
| 384 | 'oi_major_mime' => $props['major_mime'], |
||
| 385 | 'oi_minor_mime' => $props['minor_mime'], |
||
| 386 | 'oi_sha1' => $props['sha1'], |
||
| 387 | ], __METHOD__ |
||
| 388 | ); |
||
| 389 | |||
| 390 | return true; |
||
| 391 | } |
||
| 392 | |||
| 393 | /** |
||
| 394 | * If archive name is an empty string, then file does not "exist" |
||
| 395 | * |
||
| 396 | * This is the case for a couple files on Wikimedia servers where |
||
| 397 | * the old version is "lost". |
||
| 398 | */ |
||
| 399 | public function exists() { |
||
| 400 | $archiveName = $this->getArchiveName(); |
||
| 401 | if ( $archiveName === '' || !is_string( $archiveName ) ) { |
||
| 402 | return false; |
||
| 403 | } |
||
| 404 | return parent::exists(); |
||
| 405 | } |
||
| 406 | } |
||
| 407 |
It seems like the method you are trying to call exists only in some of the possible types.
Let’s take a look at an example:
Available Fixes
Add an additional type-check:
Only allow a single type to be passed if the variable comes from a parameter: