Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #19457 -- ImageField size detection failed for some files.

This was caused by PIL raising a zlib truncated stream error since we fed
the parser with chunks instead of the whole image.
  • Loading branch information...
commit 3aa4b8165da23a2f094d0eeffacbda5484f4c1f6 1 parent bacb097
Anton Baklanov authored December 13, 2012 apollo13 committed January 01, 2013
14  django/core/files/images.py
@@ -4,7 +4,11 @@
4 4
 Requires PIL, as you might imagine.
5 5
 """
6 6
 
  7
+import zlib
  8
+import sys
  9
+
7 10
 from django.core.files import File
  11
+from django.utils import six
8 12
 
9 13
 class ImageFile(File):
10 14
     """
@@ -55,7 +59,15 @@ def get_image_dimensions(file_or_path, close=False):
55 59
             data = file.read(chunk_size)
56 60
             if not data:
57 61
                 break
58  
-            p.feed(data)
  62
+            try:
  63
+                p.feed(data)
  64
+            except zlib.error as e:
  65
+                # ignore zlib complaining on truncated stream, just feed more
  66
+                # data to parser (ticket #19457).
  67
+                if e.message.startswith("Error -5"):
  68
+                    pass
  69
+                else:
  70
+                    six.reraise(*sys.exc_info())
59 71
             if p.image:
60 72
                 return p.image.size
61 73
             chunk_size = chunk_size*2
BIN  tests/regressiontests/file_storage/magic.png
15  tests/regressiontests/file_storage/tests.py
@@ -7,6 +7,7 @@
7 7
 import sys
8 8
 import tempfile
9 9
 import time
  10
+import zlib
10 11
 from datetime import datetime, timedelta
11 12
 from io import BytesIO
12 13
 
@@ -559,6 +560,20 @@ def test_multiple_calls(self):
559 560
         self.assertEqual(image_pil.size, size_1)
560 561
         self.assertEqual(size_1, size_2)
561 562
 
  563
+    @unittest.skipUnless(Image, "PIL not installed")
  564
+    def test_bug_19457(self):
  565
+        """
  566
+        Regression test for #19457
  567
+        get_image_dimensions fails on some pngs, while Image.size is working good on them
  568
+        """
  569
+        img_path = os.path.join(os.path.dirname(upath(__file__)), "magic.png")
  570
+        try:
  571
+            size = get_image_dimensions(img_path)
  572
+        except zlib.error:
  573
+            self.fail("Exception raised from get_image_dimensions().")
  574
+        self.assertEqual(size, Image.open(img_path).size)
  575
+
  576
+
562 577
 class ContentFileTestCase(unittest.TestCase):
563 578
 
564 579
     def setUp(self):

0 notes on commit 3aa4b81

Claude Paroz

Raises: DeprecationWarning: BaseException.message has been deprecated as of Python 2.6
You should probably use e.args[0] here.

Claude Paroz

or simply raise ?
Generally, reraising is interesting when you want to modify exception parameters.

Florian Apolloner

Hrmpf, why doesn't my python show those :(

Florian Apolloner

sigh I shouldn't touch Django today I guess :/

Please sign in to comment.
Something went wrong with that request. Please try again.