From 9ac888262ae651166e65f0fe1936892b671606dd Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Sat, 8 May 2021 00:25:47 +1000 Subject: [PATCH] Do not allow TIFF to seek to a past frame --- Tests/images/multipage_multiple_frame_loop.tiff | Bin 0 -> 816 bytes Tests/images/multipage_out_of_order.tiff | Bin 0 -> 816 bytes Tests/images/multipage_single_frame_loop.tiff | Bin 0 -> 816 bytes Tests/test_file_tiff.py | 13 +++++++++++++ src/PIL/TiffImagePlugin.py | 7 ++++++- 5 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 Tests/images/multipage_multiple_frame_loop.tiff create mode 100644 Tests/images/multipage_out_of_order.tiff create mode 100644 Tests/images/multipage_single_frame_loop.tiff diff --git a/Tests/images/multipage_multiple_frame_loop.tiff b/Tests/images/multipage_multiple_frame_loop.tiff new file mode 100644 index 0000000000000000000000000000000000000000..b6759b08023f766caa9c66355849d9dd2ebfd610 GIT binary patch literal 816 zcmb_ayAHxI40IAes1sB?q|%WEHg*Qq{s21zNGuF2to>EHsS{tF54+R$xW7oIuEixkf8vkBzvhqL zz#llp-#~@HA2oqL*DEhTG4?J0rqS?^uGNX(&d&+skLCoA`A(-R2GP&S8vFY>$uMwU aryMw?lO-2)Dp2Efn)9%#rFHUI*6Rg47$3&~ literal 0 HcmV?d00001 diff --git a/Tests/images/multipage_out_of_order.tiff b/Tests/images/multipage_out_of_order.tiff new file mode 100644 index 0000000000000000000000000000000000000000..1576a549b58ae83da286c7481c1b8f7f797ad4fd GIT binary patch literal 816 zcmb`FEf2yl5QgtsSjZGCd?aHM0}hWsVD<;_2uLsp40gYVpM^xCNygi**Httjd^G9q zY45J<_qOb9>+{h#3Vuc1-xy#KjL0pL5sd z-oR7GcW@Ep&cO3**iY4T4O(fePV8!0DBge)|ThP?zBDbFJ^5~=Cmp)0+ daH3NNj_IUGd!2H`h)y#b-zX5*sqqmRyy?5o=-`rdS+cWwD&;04Ek}*QM}`FGAIf?N3nvwqX*3L`q7tnhv3 ilN5$?I%U8yofK)WQ;r&^(@e~2L-djO)Tzl4iC!;pIUn!< literal 0 HcmV?d00001 diff --git a/Tests/test_file_tiff.py b/Tests/test_file_tiff.py index c24438c48..dd312d6df 100644 --- a/Tests/test_file_tiff.py +++ b/Tests/test_file_tiff.py @@ -301,6 +301,19 @@ class TestFileTiff: assert im.size == (20, 20) assert im.convert("RGB").getpixel((0, 0)) == (0, 0, 255) + def test_frame_order(self): + # A frame can't progress to itself after reading + with Image.open("Tests/images/multipage_single_frame_loop.tiff") as im: + assert im.n_frames == 1 + + # A frame can't progress to a frame that has already been read + with Image.open("Tests/images/multipage_multiple_frame_loop.tiff") as im: + assert im.n_frames == 2 + + # Frames don't have to be in sequence + with Image.open("Tests/images/multipage_out_of_order.tiff") as im: + assert im.n_frames == 3 + def test___str__(self): filename = "Tests/images/pil136.tiff" with Image.open(filename) as im: diff --git a/src/PIL/TiffImagePlugin.py b/src/PIL/TiffImagePlugin.py index 5d046761a..dd5004edd 100644 --- a/src/PIL/TiffImagePlugin.py +++ b/src/PIL/TiffImagePlugin.py @@ -1067,7 +1067,12 @@ class TiffImageFile(ImageFile.ImageFile): self._frame_pos.append(self.__next) logger.debug("Loading tags, location: %s" % self.fp.tell()) self.tag_v2.load(self.fp) - self.__next = self.tag_v2.next + if self.tag_v2.next in self._frame_pos: + # This IFD has already been processed + # Declare this to be the end of the image + self.__next = 0 + else: + self.__next = self.tag_v2.next if self.__next == 0: self._n_frames = frame + 1 if len(self._frame_pos) == 1: