const WINDOWS_NONASCII_FILENAME = 13;
const FILENAME_TOO_LONG = 14;
- const SESSION_STATUS_KEY = 'wsUploadStatusData';
-
/**
* @param int $error
* @return string
// Give hooks the chance to handle this request
$className = null;
- wfRunHooks( 'UploadCreateFromRequest', array( $type, &$className ) );
+ Hooks::run( 'UploadCreateFromRequest', array( $type, &$className ) );
if ( is_null( $className ) ) {
$className = 'UploadFrom' . $type;
wfDebug( __METHOD__ . ": class name: $className\n" );
* @return string|bool The real path if it was a virtual URL Returns false on failure
*/
function getRealPath( $srcPath ) {
- wfProfileIn( __METHOD__ );
$repo = RepoGroup::singleton()->getLocalRepo();
if ( $repo->isVirtualUrl( $srcPath ) ) {
/** @todo Just make uploads work with storage paths UploadFromStash
} else {
$path = $srcPath;
}
- wfProfileOut( __METHOD__ );
return $path;
}
* @return mixed Const 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 );
}
*/
$maxSize = self::getMaxUploadSize( $this->getSourceType() );
if ( $this->mFileSize > $maxSize ) {
- wfProfileOut( __METHOD__ );
return array(
'status' => self::FILE_TOO_LARGE,
*/
$verification = $this->verifyFile();
if ( $verification !== true ) {
- wfProfileOut( __METHOD__ );
return array(
'status' => self::VERIFICATION_ERROR,
*/
$result = $this->validateName();
if ( $result !== true ) {
- wfProfileOut( __METHOD__ );
return $result;
}
$error = '';
- if ( !wfRunHooks( 'UploadVerification',
+ if ( !Hooks::run( 'UploadVerification',
array( $this->mDestName, $this->mTempPath, &$error ) )
) {
- wfProfileOut( __METHOD__ );
return array( 'status' => self::HOOK_ABORTED, 'error' => $error );
}
- wfProfileOut( __METHOD__ );
-
return array( 'status' => self::OK );
}
*/
protected function verifyMimeType( $mime ) {
global $wgVerifyMimeType;
- wfProfileIn( __METHOD__ );
if ( $wgVerifyMimeType ) {
wfDebug( "mime: <$mime> extension: <{$this->mFinalExtension}>\n" );
global $wgMimeTypeBlacklist;
if ( $this->checkFileExtension( $mime, $wgMimeTypeBlacklist ) ) {
- wfProfileOut( __METHOD__ );
return array( 'filetype-badmime', $mime );
}
$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;
}
* @return mixed True of the file is verified, array otherwise.
*/
protected function verifyFile() {
- global $wgVerifyMimeType;
- wfProfileIn( __METHOD__ );
+ global $wgVerifyMimeType, $wgDisableUploadScriptChecks;
$status = $this->verifyPartialFile();
if ( $status !== true ) {
- wfProfileOut( __METHOD__ );
return $status;
}
if ( $wgVerifyMimeType ) {
# 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 );
}
}
+ # check for htmlish code and javascript
+ if ( !$wgDisableUploadScriptChecks ) {
+ if ( $this->mFinalExtension == 'svg' || $mime == 'image/svg+xml' ) {
+ $svgStatus = $this->detectScriptInSvg( $this->mTempPath, false );
+ if ( $svgStatus !== false ) {
+
+ return $svgStatus;
+ }
+ }
+ }
+
$handler = MediaHandler::getHandler( $mime );
if ( $handler ) {
$handlerStatus = $handler->verifyUpload( $this->mTempPath );
if ( !$handlerStatus->isOK() ) {
$errors = $handlerStatus->getErrorsArray();
- wfProfileOut( __METHOD__ );
return reset( $errors );
}
}
- wfRunHooks( 'UploadVerifyFile', array( $this, $mime, &$status ) );
+ Hooks::run( 'UploadVerifyFile', array( $this, $mime, &$status ) );
if ( $status !== true ) {
- wfProfileOut( __METHOD__ );
return $status;
}
wfDebug( __METHOD__ . ": all clear; passing.\n" );
- wfProfileOut( __METHOD__ );
return true;
}
*/
protected function verifyPartialFile() {
global $wgAllowJavaUploads, $wgDisableUploadScriptChecks;
- wfProfileIn( __METHOD__ );
# getTitle() sets some internal parameters like $this->mFinalExtension
$this->getTitle();
$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' ) {
- $svgStatus = $this->detectScriptInSvg( $this->mTempPath );
+ $svgStatus = $this->detectScriptInSvg( $this->mTempPath, true );
if ( $svgStatus !== false ) {
- wfProfileOut( __METHOD__ );
return $svgStatus;
}
$errors = $zipStatus->getErrorsArray();
$error = reset( $errors );
if ( $error[0] !== 'zip-wrong-format' ) {
- wfProfileOut( __METHOD__ );
return $error;
}
}
if ( $this->mJavaDetected ) {
- wfProfileOut( __METHOD__ );
return array( 'uploadjava' );
}
# Scan the uploaded file for viruses
$virus = $this->detectVirus( $this->mTempPath );
if ( $virus ) {
- wfProfileOut( __METHOD__ );
return array( 'uploadvirus', $virus );
}
- wfProfileOut( __METHOD__ );
-
return true;
}
*/
public function checkWarnings() {
global $wgLang;
- wfProfileIn( __METHOD__ );
$warnings = array();
}
}
- wfProfileOut( __METHOD__ );
-
return $warnings;
}
* @return Status Indicating the whether the upload succeeded.
*/
public function performUpload( $comment, $pageText, $watch, $user ) {
- wfProfileIn( __METHOD__ );
$status = $this->getLocalFile()->upload(
$this->mTempPath,
WatchedItem::IGNORE_USER_RIGHTS
);
}
- wfRunHooks( 'UploadComplete', array( &$this ) );
+ Hooks::run( 'UploadComplete', array( &$this ) );
$this->postProcessUpload();
}
- wfProfileOut( __METHOD__ );
-
return $status;
}
$sizes = $wgUploadThumbnailRenderMap;
rsort( $sizes );
+ $file = $this->getLocalFile();
+
foreach ( $sizes as $size ) {
- $jobs[] = new ThumbnailRenderJob( $this->getLocalFile()->getTitle(), array(
- 'transformParams' => array( 'width' => $size ),
- ) );
+ if ( $file->isVectorized()
+ || $file->getWidth() > $size ) {
+ $jobs[] = new ThumbnailRenderJob( $file->getTitle(), array(
+ 'transformParams' => array( 'width' => $size ),
+ ) );
+ }
}
- JobQueueGroup::singleton()->push( $jobs );
+ if ( $jobs ) {
+ JobQueueGroup::singleton()->push( $jobs );
+ }
}
/**
*/
public function stashFile( User $user = null ) {
// was stashSessionFile
- wfProfileIn( __METHOD__ );
$stash = RepoGroup::singleton()->getLocalRepo()->getUploadStash( $user );
$file = $stash->stashFile( $this->mTempPath, $this->getSourceType() );
$this->mLocalFile = $file;
- wfProfileOut( __METHOD__ );
-
return $file;
}
*/
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.
$chunk = strtolower( $chunk );
if ( !$chunk ) {
- wfProfileOut( __METHOD__ );
return false;
}
# check for HTML doctype
if ( preg_match( "/<!DOCTYPE *X?HTML/i", $chunk ) ) {
- wfProfileOut( __METHOD__ );
return true;
}
// PHP/expat will interpret the given encoding in the xml declaration (bug 47304)
if ( $extension == 'svg' || strpos( $mime, 'image/svg' ) === 0 ) {
if ( self::checkXMLEncodingMissmatch( $file ) ) {
- wfProfileOut( __METHOD__ );
return true;
}
foreach ( $tags as $tag ) {
if ( false !== strpos( $chunk, $tag ) ) {
wfDebug( __METHOD__ . ": found something that may make it be mistaken for html: $tag\n" );
- wfProfileOut( __METHOD__ );
return true;
}
# look for script-types
if ( preg_match( '!type\s*=\s*[\'"]?\s*(?:\w*/)?(?:ecma|java)!sim', $chunk ) ) {
wfDebug( __METHOD__ . ": found script types\n" );
- wfProfileOut( __METHOD__ );
return true;
}
# look for html-style script-urls
if ( preg_match( '!(?:href|src|data)\s*=\s*[\'"]?\s*(?:ecma|java)script:!sim', $chunk ) ) {
wfDebug( __METHOD__ . ": found html-style script urls\n" );
- wfProfileOut( __METHOD__ );
return true;
}
# look for css-style script-urls
if ( preg_match( '!url\s*\(\s*[\'"]?\s*(?:ecma|java)script:!sim', $chunk ) ) {
wfDebug( __METHOD__ . ": found css-style script urls\n" );
- wfProfileOut( __METHOD__ );
return true;
}
wfDebug( __METHOD__ . ": no scripts found\n" );
- wfProfileOut( __METHOD__ );
return false;
}
/**
* @param string $filename
+ * @param bool $partial
* @return mixed False of the file is verified (does not contain scripts), array otherwise.
*/
- protected function detectScriptInSvg( $filename ) {
+ protected function detectScriptInSvg( $filename, $partial ) {
$this->mSVGNSError = false;
$check = new XmlTypeCheck(
$filename,
);
if ( $check->wellFormed !== true ) {
// Invalid xml (bug 58553)
- return array( 'uploadinvalidxml' );
+ // But only when non-partial (bug 65724)
+ return $partial ? false : array( 'uploadinvalidxml' );
} elseif ( $check->filterMatch ) {
if ( $this->mSVGNSError ) {
return array( 'uploadscriptednamespace', $this->mSVGNSError );
*/
public static function detectVirus( $file ) {
global $wgAntivirus, $wgAntivirusSetup, $wgAntivirusRequired, $wgOut;
- wfProfileIn( __METHOD__ );
if ( !$wgAntivirus ) {
wfDebug( __METHOD__ . ": virus scanner disabled\n" );
- wfProfileOut( __METHOD__ );
return null;
}
wfDebug( __METHOD__ . ": unknown virus scanner: $wgAntivirus\n" );
$wgOut->wrapWikiMsg( "<div class=\"error\">\n$1\n</div>",
array( 'virus-badscanner', $wgAntivirus ) );
- wfProfileOut( __METHOD__ );
return wfMessage( 'virus-unknownscanner' )->text() . " $wgAntivirus";
}
wfDebug( __METHOD__ . ": FOUND VIRUS! scanner feedback: $output \n" );
}
- wfProfileOut( __METHOD__ );
-
return $output;
}
}
/**
- * Get the current status of a chunked upload (used for polling).
- * The status will be read from the *current* user session.
+ * Get the current status of a chunked upload (used for polling)
+ *
+ * The value will be read from cache.
+ *
+ * @param User $user
* @param string $statusKey
* @return Status[]|bool
*/
- public static function getSessionStatus( $statusKey ) {
- return isset( $_SESSION[self::SESSION_STATUS_KEY][$statusKey] )
- ? $_SESSION[self::SESSION_STATUS_KEY][$statusKey]
- : false;
+ public static function getSessionStatus( User $user, $statusKey ) {
+ $key = wfMemcKey( 'uploadstatus', $user->getId() ?: md5( $user->getName() ), $statusKey );
+
+ return wfGetCache( CACHE_ANYTHING )->get( $key );
}
/**
- * Set the current status of a chunked upload (used for polling).
- * The status will be stored in the *current* user session.
+ * Set the current status of a chunked upload (used for polling)
+ *
+ * The value will be set in cache for 1 day
+ *
+ * @param User $user
* @param string $statusKey
* @param array|bool $value
* @return void
*/
- public static function setSessionStatus( $statusKey, $value ) {
+ public static function setSessionStatus( User $user, $statusKey, $value ) {
+ $key = wfMemcKey( 'uploadstatus', $user->getId() ?: md5( $user->getName() ), $statusKey );
+
+ $cache = wfGetCache( CACHE_ANYTHING );
if ( $value === false ) {
- unset( $_SESSION[self::SESSION_STATUS_KEY][$statusKey] );
+ $cache->delete( $key );
} else {
- $_SESSION[self::SESSION_STATUS_KEY][$statusKey] = $value;
+ $cache->set( $key, $value, 86400 );
}
}
}