From 5c9ddcc052cb95c6bb1ae64e5bb36a3564414442 Mon Sep 17 00:00:00 2001
From: Thomas Bruederli <bruederli@kolabsys.com>
Date: Mon, 03 Nov 2014 09:49:49 -0500
Subject: [PATCH] Check available memory for image resizing with GD on Windows (#1489937)

---
 program/lib/Roundcube/rcube_image.php |   34 ++++++++++++++++++++++++++++++++++
 1 files changed, 34 insertions(+), 0 deletions(-)

diff --git a/program/lib/Roundcube/rcube_image.php b/program/lib/Roundcube/rcube_image.php
index 77ce164..9c9f08b 100644
--- a/program/lib/Roundcube/rcube_image.php
+++ b/program/lib/Roundcube/rcube_image.php
@@ -59,11 +59,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,8 +74,11 @@
                 'gd_type' => $gd_type,
                 'width'   => $width,
                 'height'  => $height,
+                'channels' => $channels,
             );
         }
+
+        return null;
     }
 
     /**
@@ -179,6 +184,11 @@
                 @chmod($filename, 0600);
                 return $type;
             }
+        }
+
+        // do we have enough memory? (#1489937)
+        if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN' && !$this->mem_check($props)) {
+            return false;
         }
 
         // use GD extension
@@ -327,6 +337,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')) {
                 $image = imagecreatefromjpeg($this->image_file);
@@ -406,4 +422,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