From 7c8e0e44578df91496a74c4007313717971f75b2 Mon Sep 17 00:00:00 2001 From: Vytis Banaitis Date: Wed, 9 Aug 2017 16:16:14 +0300 Subject: [PATCH] Fix ZeroDivisionError when EXIF contains invalid DPI (0/0). --- PIL/JpegImagePlugin.py | 3 ++- Tests/images/exif-dpi-zerodivision.jpg | Bin 0 -> 10949 bytes Tests/test_file_jpeg.py | 10 ++++++++++ 3 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 Tests/images/exif-dpi-zerodivision.jpg diff --git a/PIL/JpegImagePlugin.py b/PIL/JpegImagePlugin.py index 47fb0a6df..6837ba450 100644 --- a/PIL/JpegImagePlugin.py +++ b/PIL/JpegImagePlugin.py @@ -131,9 +131,10 @@ def APP(self, marker): # 1 dpcm = 2.54 dpi dpi *= 2.54 self.info["dpi"] = dpi, dpi - except (KeyError, SyntaxError): + except (KeyError, SyntaxError, ZeroDivisionError): # SyntaxError for invalid/unreadable exif # KeyError for dpi not included + # ZeroDivisionError for invalid dpi rational value self.info["dpi"] = 72, 72 diff --git a/Tests/images/exif-dpi-zerodivision.jpg b/Tests/images/exif-dpi-zerodivision.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2e784cf6a883c2e94171b1996a0db7a7a8b2c9da GIT binary patch literal 10949 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 literal 0 HcmV?d00001 diff --git a/Tests/test_file_jpeg.py b/Tests/test_file_jpeg.py index 7487263d7..7f701d0f6 100644 --- a/Tests/test_file_jpeg.py +++ b/Tests/test_file_jpeg.py @@ -535,6 +535,16 @@ class TestFileJpeg(PillowTestCase): # Act / Assert self.assertEqual(im.info.get("dpi"), (508, 508)) + def test_dpi_exif_zero_division(self): + # Arrange + # This is photoshop-200dpi.jpg with EXIF resolution set to 0/0: + # exiftool -XResolution=0/0 -YResolution=0/0 photoshop-200dpi.jpg + im = Image.open("Tests/images/exif-dpi-zerodivision.jpg") + + # Act / Assert + # This should return the default, and not raise a ZeroDivisionError + self.assertEqual(im.info.get("dpi"), (72, 72)) + def test_no_dpi_in_exif(self): # Arrange # This is photoshop-200dpi.jpg with resolution removed from EXIF: