http://www.mediawiki.org/wiki/Special:Code/MediaWiki/70037
Revision: 70037
Author: btongminh
Date: 2010-07-27 20:38:36 +0000 (Tue, 27 Jul 2010)
Log Message:
-----------
(bug 23380) Uploaded files that are larger than allowed by PHP now show a
useful error message.
Introduced a WebRequestUpload class which is a wrapper around $_FILES and
contains all getUpload* and getFile* methods. This has as advantage that the
upload can be passed along without $wgRequest. Also because I like objects.
Modified Paths:
--------------
trunk/phase3/RELEASE-NOTES
trunk/phase3/includes/AutoLoader.php
trunk/phase3/includes/WebRequest.php
trunk/phase3/includes/upload/UploadBase.php
trunk/phase3/includes/upload/UploadFromFile.php
Modified: trunk/phase3/RELEASE-NOTES
===================================================================
--- trunk/phase3/RELEASE-NOTES 2010-07-27 20:22:33 UTC (rev 70036)
+++ trunk/phase3/RELEASE-NOTES 2010-07-27 20:38:36 UTC (rev 70037)
@@ -253,6 +253,8 @@
page.
* (bug 24517) LocalFile::newFromKey() and OldLocalFile::newFromKey() no longer
throw fatal errors
+* (bug 23380) Uploaded files that are larger than allowed by PHP now show a
+ useful error message.
=== API changes in 1.17 ===
* (bug 22738) Allow filtering by action type on query=logevent.
Modified: trunk/phase3/includes/AutoLoader.php
===================================================================
--- trunk/phase3/includes/AutoLoader.php 2010-07-27 20:22:33 UTC (rev
70036)
+++ trunk/phase3/includes/AutoLoader.php 2010-07-27 20:38:36 UTC (rev
70037)
@@ -228,6 +228,7 @@
'WatchedItem' => 'includes/WatchedItem.php',
'WatchlistEditor' => 'includes/WatchlistEditor.php',
'WebRequest' => 'includes/WebRequest.php',
+ 'WebRequestUpload' => 'includes/WebRequest.php',
'WebResponse' => 'includes/WebResponse.php',
'WikiError' => 'includes/WikiError.php',
'WikiErrorMsg' => 'includes/WikiError.php',
Modified: trunk/phase3/includes/WebRequest.php
===================================================================
--- trunk/phase3/includes/WebRequest.php 2010-07-27 20:22:33 UTC (rev
70036)
+++ trunk/phase3/includes/WebRequest.php 2010-07-27 20:38:36 UTC (rev
70037)
@@ -590,23 +590,20 @@
* @return string or NULL if no such file.
*/
public function getFileTempname( $key ) {
- if( !isset( $_FILES[$key] ) ) {
- return null;
- }
- return $_FILES[$key]['tmp_name'];
+ $file = new WebRequestUpload( $key );
+ return $file->getTempName();
}
/**
* Return the size of the upload, or 0.
*
+ * @deprecated
* @param $key String:
* @return integer
*/
public function getFileSize( $key ) {
- if( !isset( $_FILES[$key] ) ) {
- return 0;
- }
- return $_FILES[$key]['size'];
+ $file = new WebRequestUpload( $key );
+ return $file->getSize();
}
/**
@@ -616,10 +613,8 @@
* @return integer
*/
public function getUploadError( $key ) {
- if( !isset( $_FILES[$key] ) || !isset( $_FILES[$key]['error'] )
) {
- return 0/*UPLOAD_ERR_OK*/;
- }
- return $_FILES[$key]['error'];
+ $file = new WebRequestUpload( $key );
+ return $file->getError();
}
/**
@@ -634,19 +629,19 @@
* @return string or NULL if no such file.
*/
public function getFileName( $key ) {
- global $wgContLang;
- if( !isset( $_FILES[$key] ) ) {
- return null;
- }
- $name = $_FILES[$key]['name'];
-
- # Safari sends filenames in HTML-encoded Unicode form D...
- # Horrid and evil! Let's try to make some kind of sense of it.
- $name = Sanitizer::decodeCharReferences( $name );
- $name = $wgContLang->normalize( $name );
- wfDebug( "WebRequest::getFileName() '" . $_FILES[$key]['name']
. "' normalized to '$name'\n" );
- return $name;
+ $file = new WebRequestUpload( $key );
+ return $file->getName();
}
+
+ /**
+ * Return a WebRequestUpload object corresponding to the key
+ *
+ * @param @key string
+ * @return WebRequestUpload
+ */
+ public function getUpload( $key ) {
+ return new WebRequestUpload( $key );
+ }
/**
* Return a handle to WebResponse style object, for setting cookies,
@@ -770,6 +765,96 @@
}
/**
+ * Object to access the $_FILES array
+ */
+class WebRequestUpload {
+ protected $doesExist;
+ protected $fileInfo;
+
+ /**
+ * Constructor. Should only be called by WebRequest
+ *
+ * @param $key string Key in $_FILES array (name of form field)
+ */
+ public function __construct( $key ) {
+ $this->doesExist = isset( $_FILES[$key] );
+ if ( $this->doesExist ) {
+ $this->fileInfo = $_FILES[$key];
+ }
+ }
+
+ /**
+ * Return whether a file with this name was uploaded.
+ *
+ * @return bool
+ */
+ public function exists() {
+ return $this->doesExist;
+ }
+
+ /**
+ * Return the original filename of the uploaded file
+ *
+ * @return mixed Filename or null if non-existent
+ */
+ public function getName() {
+ if ( !$this->exists() ) {
+ return null;
+ }
+
+ global $wgContLang;
+ $name = $this->fileInfo['name'];
+
+ # Safari sends filenames in HTML-encoded Unicode form D...
+ # Horrid and evil! Let's try to make some kind of sense of it.
+ $name = Sanitizer::decodeCharReferences( $name );
+ $name = $wgContLang->normalize( $name );
+ wfDebug( __METHOD__ . ": {$this->fileInfo['name']} normalized
to '$name'\n" );
+ return $name;
+ }
+
+ /**
+ * Return the file size of the uploaded file
+ *
+ * @return int File size or zero if non-existent
+ */
+ public function getSize() {
+ if ( !$this->exists() ) {
+ return 0;
+ }
+
+ return $this->fileInfo['size'];
+ }
+
+ /**
+ * Return the path to the temporary file
+ *
+ * @return mixed Path or null if non-existent
+ */
+ public function getTempName() {
+ if ( !$this->exists() ) {
+ return null;
+ }
+
+ return $this->fileInfo['tmp_name'];
+ }
+
+ /**
+ * Return the upload error. See link for explanation
+ * http://www.php.net/manual/en/features.file-upload.errors.php
+ *
+ * @return int One of the UPLOAD_ constants, 0 if non-existent
+ */
+ public function getError() {
+ if ( !$this->exists() ) {
+ return 0; # UPLOAD_ERR_OK
+ }
+
+ return $this->fileInfo['error'];
+ }
+}
+
+/**
* WebRequest clone which takes values from a provided array.
*
* @ingroup HTTP
Modified: trunk/phase3/includes/upload/UploadBase.php
===================================================================
--- trunk/phase3/includes/upload/UploadBase.php 2010-07-27 20:22:33 UTC (rev
70036)
+++ trunk/phase3/includes/upload/UploadBase.php 2010-07-27 20:38:36 UTC (rev
70037)
@@ -236,7 +236,10 @@
*/
global $wgMaxUploadSize;
if( $this->mFileSize > $wgMaxUploadSize ) {
- return array( 'status' => self::FILE_TOO_LARGE );
+ return array(
+ 'status' => self::FILE_TOO_LARGE,
+ 'max' => $wgMaxUploadSize,
+ );
}
/**
Modified: trunk/phase3/includes/upload/UploadFromFile.php
===================================================================
--- trunk/phase3/includes/upload/UploadFromFile.php 2010-07-27 20:22:33 UTC
(rev 70036)
+++ trunk/phase3/includes/upload/UploadFromFile.php 2010-07-27 20:38:36 UTC
(rev 70037)
@@ -8,16 +8,18 @@
* Implements regular file uploads
*/
class UploadFromFile extends UploadBase {
+ protected $mWebUpload = null;
-
function initializeFromRequest( &$request ) {
+ $this->mWebUpload = $request->getUpload( 'wpUploadFile' );
+
$desiredDestName = $request->getText( 'wpDestFile' );
if( !$desiredDestName )
- $desiredDestName = $request->getFileName(
'wpUploadFile' );
+ $desiredDestName = $this->mWebUpload->getName();
return $this->initializePathInfo(
$desiredDestName,
- $request->getFileTempName( 'wpUploadFile' ),
- $request->getFileSize( 'wpUploadFile' )
+ $this->mWebUpload->getTempName(),
+ $this->mWebUpload->getSize()
);
}
/**
@@ -27,6 +29,35 @@
return $this->initializePathInfo( $name, $tempPath, $fileSize
);
}
static function isValidRequest( $request ) {
- return (bool)$request->getFileTempName( 'wpUploadFile' );
+ # Allow all requests, even if no file is present, so that an
error
+ # because a post_max_size or upload_max_filesize overflow
+ return true;
}
+
+ public function verifyUpload() {
+ # Check for a post_max_size or upload_max_size overflow, so
that a
+ # proper error can be shown to the user
+ if ( is_null( $this->mTempPath ) || $this->isEmptyFile() ) {
+ # Using the Content-length header is not an absolutely
fail-safe
+ # method, but the only available option. Otherwise
broken uploads
+ # will be handled by the parent method and return
empty-file
+ $contentLength = intval( $_SERVER['CONTENT_LENGTH'] );
+ $maxPostSize = wfShorthandToInteger( ini_get(
'post_max_size' ) );
+ if ( $this->mWebUpload->getError() ==
UPLOAD_ERR_INI_SIZE
+ || $contentLength > $maxPostSize ) {
+
+ global $wgMaxUploadSize;
+ return array(
+ 'status' => self::FILE_TOO_LARGE,
+ 'max' => min(
+ $wgMaxUploadSize,
+ wfShorthandToInteger( ini_get(
'upload_max_filesize' ) ),
+ $maxPostSize
+ ),
+ );
+ }
+ }
+
+ return parent::verifyUpload();
+ }
}
_______________________________________________
MediaWiki-CVS mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs