Fixed Image\Gd should increase memory limit _before_ calling imagecreatefrom{gif,jpeg,png}

Steffen

Well-known member
Affected version
2.0.6
The method \XF\Image\Gd::_imageFromFile increases the memory limit depending on the width and height of the image. But this only happens after the image has already been loaded into memory. Therefore, large images can trigger "Allowed memory size of ... bytes exhausted" errors.

If you use the default $config['maxImageResizePixelCount'] = 20000000; then this error is unlikely to happen because the default memory limit of 128 MB is probably enough for most images that are smaller than 20 megapixels. But if you increase $config['maxImageResizePixelCount'] then you're likely to run into this issue and the code doesn't really do what the comment claims it does. :)

Possible patch:

Diff:
diff --git a/src/XF/Image/Gd.php b/src/XF/Image/Gd.php
index 622eff4fe..06229e6f8 100644
--- a/src/XF/Image/Gd.php
+++ b/src/XF/Image/Gd.php
@@ -12,6 +12,18 @@ class Gd extends AbstractDriver

         $image = null;

+        // approximately 5 bytes per pixel, times a 1.2 fudge factor, times 2 to support a second copy
+        // (such as for rotation via EXIF data)
+        if ($size = @getimagesize($file))
+        {
+            $memoryBuffer = ($size[0] * $size[1] * 5) * 1.2 * 2;
+            $availableMemory = \XF::getAvailableMemory();
+            if ($availableMemory && $availableMemory < $memoryBuffer)
+            {
+                \XF::increaseMemoryLimit($memoryBuffer - $availableMemory);
+            }
+        }
+
         switch ($type)
         {
             case IMAGETYPE_GIF:
@@ -50,15 +62,6 @@ class Gd extends AbstractDriver

         $this->setImage($image);

-        // approximately 5 bytes per pixel, times a 1.2 fudge factor, times 2 to support a second copy
-        // (such as for rotation via EXIF data)
-        $memoryBuffer = ($this->width * $this->height * 5) * 1.2 * 2;
-        $availableMemory = \XF::getAvailableMemory();
-        if ($availableMemory && $availableMemory < $memoryBuffer)
-        {
-            \XF::increaseMemoryLimit($memoryBuffer - $availableMemory);
-        }
-
         return true;
     }
 
Top Bottom