From bd0551b22076b82a6d49e9f7a2b2e0c90a1b2326 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak <alec@alec.pl> Date: Fri, 05 Feb 2016 07:25:27 -0500 Subject: [PATCH] Secure also downloads of addressbook exports, managesieve script exports and Enigma keys exports --- program/lib/Roundcube/rcube_image.php | 71 ++++++++++++++++++++++++++++++++--- 1 files changed, 64 insertions(+), 7 deletions(-) diff --git a/program/lib/Roundcube/rcube_image.php b/program/lib/Roundcube/rcube_image.php index a432d92..b5eec5e 100644 --- a/program/lib/Roundcube/rcube_image.php +++ b/program/lib/Roundcube/rcube_image.php @@ -1,6 +1,6 @@ <?php -/* +/** +-----------------------------------------------------------------------+ | This file is part of the Roundcube Webmail client | | Copyright (C) 2005-2012, The Roundcube Dev Team | @@ -41,6 +41,11 @@ ); + /** + * Class constructor + * + * @param string $filename Image file name/path + */ function __construct($filename) { $this->image_file = $filename; @@ -59,11 +64,13 @@ $height = $imsize[1]; $gd_type = $imsize['2']; $type = image_type_to_extension($imsize['2'], false); + $channels = $imsize['channels']; } // use ImageMagick if (!$type && ($data = $this->identify())) { list($type, $width, $height) = $data; + $channels = null; } if ($type) { @@ -72,17 +79,20 @@ 'gd_type' => $gd_type, 'width' => $width, 'height' => $height, + 'channels' => $channels, ); } + + return null; } /** * Resize image to a given size. Use only to shrink an image. * If an image is smaller than specified size it will be not resized. * - * @param int $size Max width/height size - * @param string $filename Output filename - * @param boolean $browser_compat Convert to image type displayable by any browser + * @param int $size Max width/height size + * @param string $filename Output filename + * @param boolean $browser_compat Convert to image type displayable by any browser * * @return mixed Output type on success, False on failure */ @@ -181,6 +191,11 @@ } } + // do we have enough memory? (#1489937) + if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN' && !$this->mem_check($props)) { + return false; + } + // use GD extension if ($props['gd_type']) { if ($props['gd_type'] == IMAGETYPE_JPEG && function_exists('imagecreatefromjpeg')) { @@ -228,6 +243,24 @@ imagecopyresampled($new_image, $image, 0, 0, 0, 0, $width, $height, $props['width'], $props['height']); $image = $new_image; + // fix rotation of image if EXIF data exists and specifies rotation (GD strips the EXIF data) + if ($this->image_file && $type == 'jpg' && function_exists('exif_read_data')) { + $exif = exif_read_data($this->image_file); + if ($exif && $exif['Orientation']) { + switch ($exif['Orientation']) { + case 3: + $image = imagerotate($image, 180, 0); + break; + case 6: + $image = imagerotate($image, -90, 0); + break; + case 8: + $image = imagerotate($image, 90, 0); + break; + } + } + } + if ($props['gd_type'] == IMAGETYPE_JPEG) { $result = imagejpeg($image, $filename, 75); } @@ -252,9 +285,9 @@ /** * Convert image to a given type * - * @param int $type Destination file type (see class constants) - * @param string $filename Output filename (if empty, original file will be used - * and filename extension will be modified) + * @param int $type Destination file type (see class constants) + * @param string $filename Output filename (if empty, original file will be used + * and filename extension will be modified) * * @return bool True on success, False on failure */ @@ -308,6 +341,12 @@ // use GD extension (TIFF isn't supported) $props = $this->props(); + + // do we have enough memory? (#1489937) + if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN' && !$this->mem_check($props)) { + return false; + } + if ($props['gd_type']) { if ($props['gd_type'] == IMAGETYPE_JPEG && function_exists('imagecreatefromjpeg')) { @@ -388,4 +427,22 @@ catch (Exception $e) {} } } + + /** + * Check if we have enough memory to load specified image + */ + private function mem_check($props) + { + // image size is unknown, we can't calculate required memory + if (!$props['width']) { + return true; + } + + // channels: CMYK - 4, RGB - 3 + $multip = ($props['channels'] ?: 3) + 1; + + // calculate image size in memory (in bytes) + $size = $props['width'] * $props['height'] * $multip; + return rcube_utils::mem_check($size); + } } -- Gitblit v1.9.1