From 63601400e476c6cf43d985f3e7b9864681695ed4 Mon Sep 17 00:00:00 2001 From: Pierre Schmitz Date: Fri, 18 Jan 2013 16:46:04 +0100 Subject: Update to MediaWiki 1.20.2 this update includes: * adjusted Arch Linux skin * updated FluxBBAuthPlugin * patch for https://bugzilla.wikimedia.org/show_bug.cgi?id=44024 --- includes/upload/UploadBase.php | 148 ++++++++++++++++++++++++++++++++--------- 1 file changed, 118 insertions(+), 30 deletions(-) (limited to 'includes/upload/UploadBase.php') diff --git a/includes/upload/UploadBase.php b/includes/upload/UploadBase.php index 6cc2287a..d40b53d3 100644 --- a/includes/upload/UploadBase.php +++ b/includes/upload/UploadBase.php @@ -1,6 +1,28 @@ 'empty-file', self::FILE_TOO_LARGE => 'file-too-large', @@ -64,6 +90,7 @@ abstract class UploadBase { /** * Returns true if uploads are enabled. * Can be override by subclasses. + * @return bool */ public static function isEnabled() { global $wgEnableUploads; @@ -82,6 +109,7 @@ abstract class UploadBase { * Can be overriden by subclasses. * * @param $user User + * @return bool */ public static function isAllowed( $user ) { foreach ( array( 'upload', 'edit' ) as $permission ) { @@ -100,6 +128,7 @@ abstract class UploadBase { * * @param $request WebRequest * @param $type + * @return null */ public static function createFromRequest( &$request, $type = null ) { $type = $type ? $type : $request->getVal( 'wpSourceType', 'File' ); @@ -140,6 +169,8 @@ abstract class UploadBase { /** * Check whether a request if valid for this handler + * @param $request + * @return bool */ public static function isValidRequest( $request ) { return false; @@ -161,7 +192,7 @@ abstract class UploadBase { * @param $tempPath string the temporary path * @param $fileSize int the file size * @param $removeTempFile bool (false) remove the temporary file? - * @return null + * @throws MWException */ public function initializePathInfo( $name, $tempPath, $fileSize, $removeTempFile = false ) { $this->mDesiredDestName = $name; @@ -180,6 +211,7 @@ abstract class UploadBase { /** * Fetch the file. Usually a no-op + * @return Status */ public function fetchFile() { return Status::newGood(); @@ -203,17 +235,20 @@ abstract class UploadBase { /** * @param $srcPath String: the source path - * @return the real path if it was a virtual URL + * @return string the real path if it was a virtual URL */ function getRealPath( $srcPath ) { + wfProfileIn( __METHOD__ ); $repo = RepoGroup::singleton()->getLocalRepo(); if ( $repo->isVirtualUrl( $srcPath ) ) { // @TODO: just make uploads work with storage paths // UploadFromStash loads files via virtuals URLs $tmpFile = $repo->getLocalCopy( $srcPath ); $tmpFile->bind( $this ); // keep alive with $thumb + wfProfileOut( __METHOD__ ); return $tmpFile->getPath(); } + wfProfileOut( __METHOD__ ); return $srcPath; } @@ -222,10 +257,13 @@ abstract class UploadBase { * @return mixed self::OK or else an array with error information */ public function verifyUpload() { + wfProfileIn( __METHOD__ ); + /** * If there was no filename or a zero size given, give up quick. */ if( $this->isEmptyFile() ) { + wfProfileOut( __METHOD__ ); return array( 'status' => self::EMPTY_FILE ); } @@ -234,6 +272,7 @@ abstract class UploadBase { */ $maxSize = self::getMaxUploadSize( $this->getSourceType() ); if( $this->mFileSize > $maxSize ) { + wfProfileOut( __METHOD__ ); return array( 'status' => self::FILE_TOO_LARGE, 'max' => $maxSize, @@ -247,6 +286,7 @@ abstract class UploadBase { */ $verification = $this->verifyFile(); if( $verification !== true ) { + wfProfileOut( __METHOD__ ); return array( 'status' => self::VERIFICATION_ERROR, 'details' => $verification @@ -258,15 +298,19 @@ abstract class UploadBase { */ $result = $this->validateName(); if( $result !== true ) { + wfProfileOut( __METHOD__ ); return $result; } $error = ''; if( !wfRunHooks( 'UploadVerification', - array( $this->mDestName, $this->mTempPath, &$error ) ) ) { + array( $this->mDestName, $this->mTempPath, &$error ) ) ) + { + wfProfileOut( __METHOD__ ); return array( 'status' => self::HOOK_ABORTED, 'error' => $error ); } + wfProfileOut( __METHOD__ ); return array( 'status' => self::OK ); } @@ -304,15 +348,18 @@ abstract class UploadBase { */ protected function verifyMimeType( $mime ) { global $wgVerifyMimeType; + wfProfileIn( __METHOD__ ); if ( $wgVerifyMimeType ) { wfDebug ( "\n\nmime: <$mime> extension: <{$this->mFinalExtension}>\n\n"); global $wgMimeTypeBlacklist; if ( $this->checkFileExtension( $mime, $wgMimeTypeBlacklist ) ) { + wfProfileOut( __METHOD__ ); return array( 'filetype-badmime', $mime ); } # XXX: Missing extension will be caught by validateName() via getTitle() if ( $this->mFinalExtension != '' && !$this->verifyExtension( $mime, $this->mFinalExtension ) ) { + wfProfileOut( __METHOD__ ); return array( 'filetype-mime-mismatch', $this->mFinalExtension, $mime ); } @@ -326,11 +373,13 @@ abstract class UploadBase { $ieTypes = $magic->getIEMimeTypes( $this->mTempPath, $chunk, $extMime ); foreach ( $ieTypes as $ieType ) { if ( $this->checkFileExtension( $ieType, $wgMimeTypeBlacklist ) ) { + wfProfileOut( __METHOD__ ); return array( 'filetype-bad-ie-mime', $ieType ); } } } + wfProfileOut( __METHOD__ ); return true; } @@ -341,6 +390,8 @@ abstract class UploadBase { */ protected function verifyFile() { global $wgAllowJavaUploads, $wgDisableUploadScriptChecks; + wfProfileIn( __METHOD__ ); + # get the title, even though we are doing nothing with it, because # we need to populate mFinalExtension $this->getTitle(); @@ -351,16 +402,19 @@ abstract class UploadBase { $mime = $this->mFileProps[ 'file-mime' ]; $status = $this->verifyMimeType( $mime ); if ( $status !== true ) { + wfProfileOut( __METHOD__ ); return $status; } # check for htmlish code and javascript if ( !$wgDisableUploadScriptChecks ) { if( self::detectScript( $this->mTempPath, $mime, $this->mFinalExtension ) ) { + wfProfileOut( __METHOD__ ); return array( 'uploadscripted' ); } if( $this->mFinalExtension == 'svg' || $mime == 'image/svg+xml' ) { if( $this->detectScriptInSvg( $this->mTempPath ) ) { + wfProfileOut( __METHOD__ ); return array( 'uploadscripted' ); } } @@ -376,10 +430,12 @@ abstract class UploadBase { $errors = $zipStatus->getErrorsArray(); $error = reset( $errors ); if ( $error[0] !== 'zip-wrong-format' ) { + wfProfileOut( __METHOD__ ); return $error; } } if ( $this->mJavaDetected ) { + wfProfileOut( __METHOD__ ); return array( 'uploadjava' ); } } @@ -387,6 +443,7 @@ abstract class UploadBase { # Scan the uploaded file for viruses $virus = $this->detectVirus( $this->mTempPath ); if ( $virus ) { + wfProfileOut( __METHOD__ ); return array( 'uploadvirus', $virus ); } @@ -395,16 +452,19 @@ abstract class UploadBase { $handlerStatus = $handler->verifyUpload( $this->mTempPath ); if ( !$handlerStatus->isOK() ) { $errors = $handlerStatus->getErrorsArray(); + wfProfileOut( __METHOD__ ); return reset( $errors ); } } wfRunHooks( 'UploadVerifyFile', array( $this, $mime, &$status ) ); if ( $status !== true ) { + wfProfileOut( __METHOD__ ); return $status; } wfDebug( __METHOD__ . ": all clear; passing.\n" ); + wfProfileOut( __METHOD__ ); return true; } @@ -490,6 +550,7 @@ abstract class UploadBase { */ public function checkWarnings() { global $wgLang; + wfProfileIn( __METHOD__ ); $warnings = array(); @@ -550,6 +611,7 @@ abstract class UploadBase { $warnings['duplicate-archive'] = $archivedImage->getName(); } + wfProfileOut( __METHOD__ ); return $warnings; } @@ -557,11 +619,16 @@ abstract class UploadBase { * Really perform the upload. Stores the file in the local repo, watches * if necessary and runs the UploadComplete hook. * + * @param $comment + * @param $pageText + * @param $watch * @param $user User * * @return Status indicating the whether the upload succeeded. */ public function performUpload( $comment, $pageText, $watch, $user ) { + wfProfileIn( __METHOD__ ); + $status = $this->getLocalFile()->upload( $this->mTempPath, $comment, @@ -576,10 +643,10 @@ abstract class UploadBase { if ( $watch ) { $user->addWatch( $this->getLocalFile()->getTitle() ); } - wfRunHooks( 'UploadComplete', array( &$this ) ); } + wfProfileOut( __METHOD__ ); return $status; } @@ -699,7 +766,7 @@ abstract class UploadBase { /** * Return the local file and initializes if necessary. * - * @return LocalFile + * @return LocalFile|null */ public function getLocalFile() { if( is_null( $this->mLocalFile ) ) { @@ -709,26 +776,6 @@ abstract class UploadBase { return $this->mLocalFile; } - /** - * NOTE: Probably should be deprecated in favor of UploadStash, but this is sometimes - * called outside that context. - * - * Stash a file in a temporary directory for later processing - * after the user has confirmed it. - * - * If the user doesn't explicitly cancel or accept, these files - * can accumulate in the temp directory. - * - * @param $saveName String: the destination filename - * @param $tempSrc String: the source temporary file to save - * @return String: full path the stashed file, or false on failure - */ - protected function saveTempUploadedFile( $saveName, $tempSrc ) { - $repo = RepoGroup::singleton()->getLocalRepo(); - $status = $repo->storeTemp( $saveName, $tempSrc ); - return $status; - } - /** * If the user does not supply all necessary information in the first upload form submission (either by accident or * by design) then we may want to stash the file temporarily, get more information, and publish the file later. @@ -742,9 +789,13 @@ abstract class UploadBase { */ public function stashFile() { // was stashSessionFile + wfProfileIn( __METHOD__ ); + $stash = RepoGroup::singleton()->getLocalRepo()->getUploadStash(); $file = $stash->stashFile( $this->mTempPath, $this->getSourceType() ); $this->mLocalFile = $file; + + wfProfileOut( __METHOD__ ); return $file; } @@ -787,6 +838,7 @@ abstract class UploadBase { * earlier pseudo-'extensions' to determine type and execute * scripts, so the blacklist needs to check them all. * + * @param $filename string * @return array */ public static function splitExtensions( $filename ) { @@ -870,6 +922,7 @@ abstract class UploadBase { */ public static function detectScript( $file, $mime, $extension ) { global $wgAllowTitlesInSVG; + wfProfileIn( __METHOD__ ); # ugly hack: for text files, always look at the entire file. # For binary field, just check the first K. @@ -885,6 +938,7 @@ abstract class UploadBase { $chunk = strtolower( $chunk ); if( !$chunk ) { + wfProfileOut( __METHOD__ ); return false; } @@ -908,6 +962,7 @@ abstract class UploadBase { # check for HTML doctype if ( preg_match( "/filterMatch; @@ -984,6 +1048,9 @@ abstract class UploadBase { /** * @todo Replace this with a whitelist filter! + * @param $element string + * @param $attribs array + * @return bool */ public function checkSvgScriptCallback( $element, $attribs ) { $strippedElement = $this->stripXmlNamespace( $element ); @@ -1054,7 +1121,7 @@ abstract class UploadBase { } - # use handler attribute with remote / data / script + # use handler attribute with remote / data / script if( $stripped == 'handler' && preg_match( '!(http|https|data|script):!sim', $value ) ) { wfDebug( __METHOD__ . ": Found svg setting handler with remote/data/script '$attrib'='$value' in uploaded file.\n" ); return true; @@ -1082,6 +1149,10 @@ abstract class UploadBase { return false; //No scripts detected } + /** + * @param $name string + * @return string + */ private function stripXmlNamespace( $name ) { // 'http://www.w3.org/2000/svg:script' -> 'script' $parts = explode( ':', strtolower( $name ) ); @@ -1100,9 +1171,11 @@ abstract class UploadBase { */ public static function detectVirus( $file ) { global $wgAntivirus, $wgAntivirusSetup, $wgAntivirusRequired, $wgOut; + wfProfileIn( __METHOD__ ); if ( !$wgAntivirus ) { wfDebug( __METHOD__ . ": virus scanner disabled\n" ); + wfProfileOut( __METHOD__ ); return null; } @@ -1110,7 +1183,8 @@ abstract class UploadBase { wfDebug( __METHOD__ . ": unknown virus scanner: $wgAntivirus\n" ); $wgOut->wrapWikiMsg( "
\n$1\n
", array( 'virus-badscanner', $wgAntivirus ) ); - return wfMsg( 'virus-unknownscanner' ) . " $wgAntivirus"; + wfProfileOut( __METHOD__ ); + return wfMessage( 'virus-unknownscanner' )->text() . " $wgAntivirus"; } # look up scanner configuration @@ -1152,17 +1226,21 @@ abstract class UploadBase { wfDebug( __METHOD__ . ": failed to scan $file (code $exitCode).\n" ); if ( $wgAntivirusRequired ) { - return wfMsg( 'virus-scanfailed', array( $exitCode ) ); + wfProfileOut( __METHOD__ ); + return wfMessage( 'virus-scanfailed', array( $exitCode ) )->text(); } else { + wfProfileOut( __METHOD__ ); return null; } } elseif ( $mappedCode === AV_SCAN_ABORTED ) { # scan failed because filetype is unknown (probably imune) wfDebug( __METHOD__ . ": unsupported file type $file (code $exitCode).\n" ); + wfProfileOut( __METHOD__ ); return null; } elseif ( $mappedCode === AV_NO_VIRUS ) { # no virus found wfDebug( __METHOD__ . ": file passed virus scan.\n" ); + wfProfileOut( __METHOD__ ); return false; } else { $output = trim( $output ); @@ -1179,6 +1257,7 @@ abstract class UploadBase { } wfDebug( __METHOD__ . ": FOUND VIRUS! scanner feedback: $output \n" ); + wfProfileOut( __METHOD__ ); return $output; } } @@ -1325,6 +1404,8 @@ abstract class UploadBase { /** * Helper function that checks whether the filename looks like a thumbnail + * @param $filename string + * @return bool */ public static function isThumbName( $filename ) { $n = strrpos( $filename, '.' ); @@ -1387,13 +1468,20 @@ abstract class UploadBase { return $info; } - + /** + * @param $error array + * @return Status + */ public function convertVerifyErrorToStatus( $error ) { $code = $error['status']; unset( $code['status'] ); return Status::newFatal( $this->getVerificationErrorCode( $code ), $error ); } + /** + * @param $forType null|string + * @return int + */ public static function getMaxUploadSize( $forType = null ) { global $wgMaxUploadSize; -- cgit v1.2.2