From dc56c6064f445010a4fa6e8d239a6cabde6c7cf7 Mon Sep 17 00:00:00 2001 From: Peter Rowlands Date: Fri, 3 Apr 2020 20:34:22 +0900 Subject: [PATCH] png: initialize _n_frames - ImageFile._seek_check() will not EOF unless _n_frames is properly set for standard (non-animated) PNG images --- Tests/test_file_png.py | 3 +++ src/PIL/PngImagePlugin.py | 8 ++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/Tests/test_file_png.py b/Tests/test_file_png.py index 469d186e8..3c5286ad0 100644 --- a/Tests/test_file_png.py +++ b/Tests/test_file_png.py @@ -635,7 +635,10 @@ class TestFilePng: def test_seek(self): with Image.open(TEST_PNG_FILE) as im: + assert im.n_frames == 1 im.seek(0) + with pytest.raises(EOFError): + im.seek(1) @pytest.mark.skipif(is_win32(), reason="Requires Unix or macOS") diff --git a/src/PIL/PngImagePlugin.py b/src/PIL/PngImagePlugin.py index 0291df4b0..3f2a0c5e8 100644 --- a/src/PIL/PngImagePlugin.py +++ b/src/PIL/PngImagePlugin.py @@ -636,7 +636,6 @@ class PngImageFile(ImageFile.ImageFile): if self.fp.read(8) != _MAGIC: raise SyntaxError("not a PNG file") self.__fp = self.fp - self.__frame = 0 # # Parse headers up to the first IDAT or fDAT chunk @@ -685,7 +684,12 @@ class PngImageFile(ImageFile.ImageFile): else: self.__prepare_idat = length # used by load_prepare() - if self._n_frames is not None: + if self._n_frames is None: + # standard PNG image, frame-related attributes still need to be + # initialized for seek()/_seek_check() to behave as expected + self.__frame = 0 + self._n_frames = 1 + else: self._close_exclusive_fp_after_loading = False self.png.save_rewind() self.__rewind_idat = self.__prepare_idat