summaryrefslogtreecommitdiff
path: root/includes/upload/UploadBase.php
diff options
context:
space:
mode:
Diffstat (limited to 'includes/upload/UploadBase.php')
-rw-r--r--includes/upload/UploadBase.php100
1 files changed, 46 insertions, 54 deletions
diff --git a/includes/upload/UploadBase.php b/includes/upload/UploadBase.php
index a97edbc7..32eeeb38 100644
--- a/includes/upload/UploadBase.php
+++ b/includes/upload/UploadBase.php
@@ -1,7 +1,10 @@
<?php
/**
- * @file
- * @ingroup upload
+ * @defgroup Upload
+ */
+
+/**
+ * @ingroup Upload
*
* UploadBase and subclasses are the backend of MediaWiki's file uploads.
* The frontends are formed by ApiUpload and SpecialUpload.
@@ -12,7 +15,6 @@
* @author Bryan Tong Minh
* @author Michael Dale
*/
-
abstract class UploadBase {
protected $mTempPath;
protected $mDesiredDestName, $mDestName, $mRemoveTempFile, $mSourceType;
@@ -37,6 +39,7 @@ abstract class UploadBase {
const HOOK_ABORTED = 11;
const FILE_TOO_LARGE = 12;
const WINDOWS_NONASCII_FILENAME = 13;
+ const FILENAME_TOO_LONG = 14;
public function getVerificationErrorCode( $error ) {
$code_to_status = array(self::EMPTY_FILE => 'empty-file',
@@ -49,6 +52,7 @@ abstract class UploadBase {
self::VERIFICATION_ERROR => 'verification-error',
self::HOOK_ABORTED => 'hookaborted',
self::WINDOWS_NONASCII_FILENAME => 'windows-nonascii-filename',
+ self::FILENAME_TOO_LONG => 'filename-toolong',
);
if( isset( $code_to_status[$error] ) ) {
return $code_to_status[$error];
@@ -161,6 +165,9 @@ abstract class UploadBase {
*/
public function initializePathInfo( $name, $tempPath, $fileSize, $removeTempFile = false ) {
$this->mDesiredDestName = $name;
+ if ( FileBackend::isStoragePath( $tempPath ) ) {
+ throw new MWException( __METHOD__ . " given storage path `$tempPath`." );
+ }
$this->mTempPath = $tempPath;
$this->mFileSize = $fileSize;
$this->mRemoveTempFile = $removeTempFile;
@@ -195,39 +202,17 @@ abstract class UploadBase {
}
/**
- * Append a file to the Repo file
- *
- * @param $srcPath String: path to source file
- * @param $toAppendPath String: path to the Repo file that will be appended to.
- * @return Status Status
- */
- protected function appendToUploadFile( $srcPath, $toAppendPath ) {
- $repo = RepoGroup::singleton()->getLocalRepo();
- $status = $repo->append( $srcPath, $toAppendPath );
- return $status;
- }
-
- /**
- * Finish appending to the Repo file
- *
- * @param $toAppendPath String: path to the Repo file that will be appended to.
- * @return Status Status
- */
- protected function appendFinish( $toAppendPath ) {
- $repo = RepoGroup::singleton()->getLocalRepo();
- $status = $repo->appendFinish( $toAppendPath );
- return $status;
- }
-
-
- /**
* @param $srcPath String: the source path
* @return the real path if it was a virtual URL
*/
function getRealPath( $srcPath ) {
$repo = RepoGroup::singleton()->getLocalRepo();
if ( $repo->isVirtualUrl( $srcPath ) ) {
- return $repo->resolveVirtualUrl( $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
+ return $tmpFile->getPath();
}
return $srcPath;
}
@@ -355,12 +340,12 @@ abstract class UploadBase {
* @return mixed true of the file is verified, array otherwise.
*/
protected function verifyFile() {
- global $wgAllowJavaUploads;
+ global $wgAllowJavaUploads, $wgDisableUploadScriptChecks;
# get the title, even though we are doing nothing with it, because
# we need to populate mFinalExtension
$this->getTitle();
- $this->mFileProps = File::getPropsFromPath( $this->mTempPath, $this->mFinalExtension );
+ $this->mFileProps = FSFile::getPropsFromPath( $this->mTempPath, $this->mFinalExtension );
# check mime type, if desired
$mime = $this->mFileProps[ 'file-mime' ];
@@ -370,13 +355,15 @@ abstract class UploadBase {
}
# check for htmlish code and javascript
- if( self::detectScript( $this->mTempPath, $mime, $this->mFinalExtension ) ) {
- return array( 'uploadscripted' );
- }
- if( $this->mFinalExtension == 'svg' || $mime == 'image/svg+xml' ) {
- if( $this->detectScriptInSvg( $this->mTempPath ) ) {
+ if ( !$wgDisableUploadScriptChecks ) {
+ if( self::detectScript( $this->mTempPath, $mime, $this->mFinalExtension ) ) {
return array( 'uploadscripted' );
}
+ if( $this->mFinalExtension == 'svg' || $mime == 'image/svg+xml' ) {
+ if( $this->detectScriptInSvg( $this->mTempPath ) ) {
+ return array( 'uploadscripted' );
+ }
+ }
}
# Check for Java applets, which if uploaded can bypass cross-site
@@ -445,7 +432,7 @@ abstract class UploadBase {
}
/**
- * Alias for verifyTitlePermissions. The function was originally 'verifyPermissions'
+ * Alias for verifyTitlePermissions. The function was originally 'verifyPermissions'
* but that suggests it's checking the user, when it's really checking the title + user combination.
* @param $user User object to verify the permissions against
* @return mixed An array as returned by getUserPermissionsErrors or true
@@ -478,7 +465,7 @@ abstract class UploadBase {
$permErrors = $nt->getUserPermissionsErrors( 'edit', $user );
$permErrorsUpload = $nt->getUserPermissionsErrors( 'upload', $user );
if ( !$nt->exists() ) {
- $permErrorsCreate = $nt->getUserPermissionsErrors( 'createpage', $user );
+ $permErrorsCreate = $nt->getUserPermissionsErrors( 'create', $user );
} else {
$permErrorsCreate = array();
}
@@ -544,7 +531,7 @@ abstract class UploadBase {
}
// Check dupes against existing files
- $hash = File::sha1Base36( $this->mTempPath );
+ $hash = FSFile::getSha1Base36FromPath( $this->mTempPath );
$dupes = RepoGroup::singleton()->findBySha1( $hash );
$title = $this->getTitle();
// Remove all matches against self
@@ -589,7 +576,7 @@ abstract class UploadBase {
if ( $watch ) {
$user->addWatch( $this->getLocalFile()->getTitle() );
}
-
+
wfRunHooks( 'UploadComplete', array( &$this ) );
}
@@ -606,7 +593,7 @@ abstract class UploadBase {
if ( $this->mTitle !== false ) {
return $this->mTitle;
}
-
+
/* Assume that if a user specified File:Something.jpg, this is an error
* and that the namespace prefix needs to be stripped of.
*/
@@ -617,6 +604,13 @@ abstract class UploadBase {
$this->mFilteredName = $this->mDesiredDestName;
}
+ # oi_archive_name is max 255 bytes, which include a timestamp and an
+ # exclamation mark, so restrict file name to 240 bytes.
+ if ( strlen( $this->mFilteredName ) > 240 ) {
+ $this->mTitleError = self::FILENAME_TOO_LONG;
+ return $this->mTitle = null;
+ }
+
/**
* Chop off any directories in the given filename. Then
* filter out illegal characters, and try to make a legible name
@@ -631,6 +625,8 @@ abstract class UploadBase {
}
$this->mFilteredName = $nt->getDBkey();
+
+
/**
* We'll want to blacklist against *any* 'extension', and use
* only the final one for the whitelist.
@@ -677,7 +673,7 @@ abstract class UploadBase {
$this->mTitleError = self::FILETYPE_BADTYPE;
return $this->mTitle = null;
}
-
+
// Windows may be broken with special characters, see bug XXX
if ( wfIsWindows() && !preg_match( '/^[\x0-\x7f]*$/', $nt->getText() ) ) {
$this->mTitleError = self::WINDOWS_NONASCII_FILENAME;
@@ -742,14 +738,12 @@ abstract class UploadBase {
* This method returns the file object, which also has a 'fileKey' property which can be passed through a form or
* API request to find this stashed file again.
*
- * @param $key String: (optional) the file key used to find the file info again. If not supplied, a key will be autogenerated.
* @return UploadStashFile stashed file
*/
- public function stashFile( $key = null ) {
+ public function stashFile() {
// was stashSessionFile
$stash = RepoGroup::singleton()->getLocalRepo()->getUploadStash();
-
- $file = $stash->stashFile( $this->mTempPath, $this->getSourceType(), $key );
+ $file = $stash->stashFile( $this->mTempPath, $this->getSourceType() );
$this->mLocalFile = $file;
return $file;
}
@@ -757,21 +751,19 @@ abstract class UploadBase {
/**
* Stash a file in a temporary directory, returning a key which can be used to find the file again. See stashFile().
*
- * @param $key String: (optional) the file key used to find the file info again. If not supplied, a key will be autogenerated.
* @return String: file key
*/
- public function stashFileGetKey( $key = null ) {
- return $this->stashFile( $key )->getFileKey();
+ public function stashFileGetKey() {
+ return $this->stashFile()->getFileKey();
}
- /**
+ /**
* alias for stashFileGetKey, for backwards compatibility
*
- * @param $key String: (optional) the file key used to find the file info again. If not supplied, a key will be autogenerated.
* @return String: file key
*/
- public function stashSession( $key = null ) {
- return $this->stashFileGetKey( $key );
+ public function stashSession() {
+ return $this->stashFileGetKey();
}
/**