Add better error message for files which exceeds $wgMaxImageArea

Added a TransformTooBigImageAreaError to allow setting an extra message.
Added also size-*pixel messages to show the value of $wgMaxImageArea
with some formatting.

This error is still throwing for all files, to fix bug T34387 this needs
a follow up with a proper check. I am not sure, if a File::isLocal() is
okay, because files from a DBForeignRepo maybe transformed on the same
server, so the check needs to be done also for this. For APIForeignRepo
the check is done on the foreign server.

Change-Id: Ieba12e424c8bddb1961a30d3f9ea5c8ff241abb5
This commit is contained in:
umherirrender 2014-06-25 21:30:08 +02:00 committed by Gergő Tisza
parent e86a49424c
commit cf5f6414ce
6 changed files with 88 additions and 25 deletions

View file

@ -1179,6 +1179,7 @@ $wgAutoloadLocalClasses = array(
'TraditionalImageGallery' => __DIR__ . '/includes/gallery/TraditionalImageGallery.php',
'TransactionProfiler' => __DIR__ . '/includes/profiler/TransactionProfiler.php',
'TransformParameterError' => __DIR__ . '/includes/media/MediaTransformOutput.php',
'TransformTooBigImageAreaError' => __DIR__ . '/includes/media/MediaTransformOutput.php',
'TransformationalImageHandler' => __DIR__ . '/includes/media/TransformationalImageHandler.php',
'UDPRCFeedEngine' => __DIR__ . '/includes/rcfeed/UDPRCFeedEngine.php',
'UIDGenerator' => __DIR__ . '/includes/utils/UIDGenerator.php',

View file

@ -477,3 +477,24 @@ class TransformParameterError extends MediaTransformError {
wfMessage( 'thumbnail_invalid_params' )->text() );
}
}
/**
* Shortcut class for parameter file size errors
*
* @ingroup Media
* @since 1.25
*/
class TransformTooBigImageAreaError extends MediaTransformError {
function __construct( $params, $maxImageArea ) {
$msg = wfMessage( 'thumbnail_toobigimagearea' );
parent::__construct( 'thumbnail_error',
max( isset( $params['width'] ) ? $params['width'] : 0, 120 ),
max( isset( $params['height'] ) ? $params['height'] : 0, 120 ),
$msg->rawParams(
$msg->getLanguage()->formatComputingNumbers(
$maxImageArea, 1000, "size-$1pixel" )
)->text()
);
}
}

View file

@ -61,29 +61,6 @@ abstract class TransformationalImageHandler extends ImageHandler {
}
}
# Check if the file is smaller than the maximum image area for thumbnailing
# For historical reasons, hook starts with BitmapHandler
$checkImageAreaHookResult = null;
Hooks::run(
'BitmapHandlerCheckImageArea',
array( $image, &$params, &$checkImageAreaHookResult )
);
if ( is_null( $checkImageAreaHookResult ) ) {
global $wgMaxImageArea;
if ( $srcWidth * $srcHeight > $wgMaxImageArea
&& !( $image->getMimeType() == 'image/jpeg'
&& $this->getScalerType( false, false ) == 'im' )
) {
# Only ImageMagick can efficiently downsize jpg images without loading
# the entire file in memory
return false;
}
} else {
return $checkImageAreaHookResult;
}
return true;
}
@ -190,6 +167,11 @@ abstract class TransformationalImageHandler extends ImageHandler {
return $this->getClientScalingThumbnailImage( $image, $scalerParams );
}
if ( !$this->isImageAreaOkForThumbnaling( $image, $params ) ) {
global $wgMaxImageArea;
return new TransformTooBigImageAreaError( $params, $wgMaxImageArea );
}
if ( $flags & self::TRANSFORM_LATER ) {
wfDebug( __METHOD__ . ": Transforming later per flags.\n" );
$newParams = array(
@ -596,4 +578,43 @@ abstract class TransformationalImageHandler extends ImageHandler {
public function mustRender( $file ) {
return $this->canRotate() && $this->getRotation( $file ) != 0;
}
/**
* Check if the file is smaller than the maximum image area for thumbnailing.
*
* Runs the 'BitmapHandlerCheckImageArea' hook.
*
* @param File $file
* @param array $params
* @return bool
* @since 1.25
*/
public function isImageAreaOkForThumbnaling( $file, $params ) {
global $wgMaxImageArea;
# For historical reasons, hook starts with BitmapHandler
$checkImageAreaHookResult = null;
Hooks::run(
'BitmapHandlerCheckImageArea',
array( $file, $params, &$checkImageAreaHookResult )
);
if ( !is_null( $checkImageAreaHookResult ) ) {
// was set by hook, so return that value
return (bool)$checkImageAreaHookResult;
}
$srcWidth = $file->getWidth( $params['page'] );
$srcHeight = $file->getHeight( $params['page'] );
if ( $srcWidth * $srcHeight > $wgMaxImageArea
&& !( $file->getMimeType() == 'image/jpeg'
&& $this->getScalerType( false, false ) == 'im' )
) {
# Only ImageMagick can efficiently downsize jpg images without loading
# the entire file in memory
return false;
}
return true;
}
}

View file

@ -2274,6 +2274,7 @@
"thumbnail-temp-create": "Unable to create temporary thumbnail file",
"thumbnail-dest-create": "Unable to save thumbnail to destination",
"thumbnail_invalid_params": "Invalid thumbnail parameters",
"thumbnail_toobigimagearea": "File with dimensions greater than $1",
"thumbnail_dest_directory": "Unable to create destination directory",
"thumbnail_image-type": "Image type not supported",
"thumbnail_gd-library": "Incomplete GD library configuration: Missing function $1",
@ -3139,6 +3140,15 @@
"size-exabytes": "$1 EB",
"size-zetabytes": "$1 ZB",
"size-yottabytes": "$1 YB",
"size-pixel": "$1 P",
"size-kilopixel": "$1 KP",
"size-megapixel": "$1 MP",
"size-gigapixel": "$1 GP",
"size-terapixel": "$1 TP",
"size-petapixel": "$1 PP",
"size-exapixel": "$1 EP",
"size-zetapixel": "$1 ZP",
"size-yottapixel": "$1 YP",
"bitrate-bits": "$1 bps",
"bitrate-kilobits": "$1 kbps",
"bitrate-megabits": "$1 Mbps",

View file

@ -2438,6 +2438,7 @@
"thumbnail-temp-create": "Used as thumbnail error message.\n\nSee also:\n* {{msg-mw|Thumbnail-dest-create}}\n* {{msg-mw|Thumbnail invalid params}}\n* {{msg-mw|Thumbnail dest directory}}",
"thumbnail-dest-create": "Used as thumbnail error message.\n\nSee also:\n* {{msg-mw|Thumbnail error}}\n* {{msg-mw|Thumbnail-temp-create}}\n* {{msg-mw|Thumbnail invalid params}}\n* {{msg-mw|Thumbnail dest directory}}",
"thumbnail_invalid_params": "Used as thumbnail error message.\n\nSee also:\n* {{msg-mw|Thumbnail-temp-create}}\n* {{msg-mw|Thumbnail-dest-create}}\n* {{msg-mw|Thumbnail dest directory}}",
"thumbnail_toobigimagearea": "Used as thumbnail error message.\n\n* $1 - Size in pixel (see {{msg-mw|size-megapixel}} and friends)",
"thumbnail_dest_directory": "Used as thumbnail error message.\n\nSee also:\n* {{msg-mw|Thumbnail error}}\n* {{msg-mw|Thumbnail-temp-create}}\n* {{msg-mw|Thumbnail-dest-create}}\n* {{msg-mw|Thumbnail invalid params}}",
"thumbnail_image-type": "This is the parameter 1 of the message {{msg-mw|thumbnail error}}",
"thumbnail_gd-library": "This is the parameter 1 of the message {{msg-mw|thumbnail error}}.\n*$1 is a function name of the GD library",
@ -3303,6 +3304,15 @@
"size-exabytes": "{{optional}}\nSize (of a file, typically) in exbibytes (1 exbibytes = 1024×1024×1024×1024×1024×1024 bytes).",
"size-zetabytes": "{{optional}}\nSize (of a file, typically) in zebibytes (1 zebibytes = 1024×1024×1024×1024×1024×1024×1024 bytes).",
"size-yottabytes": "{{optional}}\nSize (of a file, typically) in yobibytes (1 yobibytes = 1024×1024×1024×1024×1024×1024×1024×1024 bytes).",
"size-pixel": "{{optional}}\nSize (of a file, typically) in pixel.",
"size-kilopixel": "{{optional}}\nSize (of a file, typically) in kilopixel (1 kilopixel = 1000 pixel).",
"size-megapixel": "{{optional}}\nSize (of a file, typically) in megapixel (1 megapixel = 1000×1000 pixel).",
"size-gigapixel": "{{optional}}\nSize (of a file, typically) in gigapixel (1 gigapixel = 1000×1000×1000 pixel).",
"size-terapixel": "{{optional}}\nSize (of a file, typically) in terapixel (1 terapixel = 1000×1000×1000×1000 pixel).",
"size-petapixel": "{{optional}}\nSize (of a file, typically) in petapixel (1 petapixel = 1000×1000×1000×1000×1000 pixel).",
"size-exapixel": "{{optional}}\nSize (of a file, typically) in exapixel (1 exapixel = 1000×1000×1000×1000×1000×1000 pixel).",
"size-zetapixel": "{{optional}}\nSize (of a file, typically) in zetapixel (1 zetapixel = 1000×1000×1000×1000×1000×1000×1000 pixel).",
"size-yottapixel": "{{optional}}\nSize (of a file, typically) in yottapixel (1 yottapixel = 1000×1000×1000×1000×1000×1000×1000×1000 pixel).",
"bitrate-bits": "{{optional}}\nBitrate (of a file, typically) in bits.",
"bitrate-kilobits": "{{optional}}\nBitrate (of a file, typically) in kilobits (1 kilobit = 1000 bits).",
"bitrate-megabits": "{{optional}}\nBitrate (of a file, typically) in megabits (1 megabits = 1000×1000 bits).",

View file

@ -113,7 +113,7 @@ class BitmapScalingTest extends MediaWikiTestCase {
$file = new FakeDimensionFile( array( 4000, 4000 ) );
$handler = new BitmapHandler;
$params = array( 'width' => '3700' ); // Still bigger than max size.
$this->assertEquals( 'TransformParameterError',
$this->assertEquals( 'TransformTooBigImageAreaError',
get_class( $handler->doTransform( $file, 'dummy path', '', $params ) ) );
}
@ -125,7 +125,7 @@ class BitmapScalingTest extends MediaWikiTestCase {
$file->mustRender = true;
$handler = new BitmapHandler;
$params = array( 'width' => '5000' ); // Still bigger than max size.
$this->assertEquals( 'TransformParameterError',
$this->assertEquals( 'TransformTooBigImageAreaError',
get_class( $handler->doTransform( $file, 'dummy path', '', $params ) ) );
}