diff --git a/Tests/test_file_jpeg.py b/Tests/test_file_jpeg.py index f2002ecb891..4b2ffe70d0c 100644 --- a/Tests/test_file_jpeg.py +++ b/Tests/test_file_jpeg.py @@ -870,6 +870,30 @@ def test_getxmp(self): with Image.open("Tests/images/hopper.jpg") as im: assert im.getxmp() == {} + @pytest.mark.timeout(timeout=1) + def test_eof(self): + # Even though this decoder never says that it is finished + # the image should still end when there is no new data + class InfiniteMockPyDecoder(ImageFile.PyDecoder): + def decode(self, buffer): + return 0, 0 + + decoder = InfiniteMockPyDecoder(None) + + def closure(mode, *args): + decoder.__init__(mode, *args) + return decoder + + Image.register_decoder("INFINITE", closure) + + with Image.open(TEST_FILE) as im: + im.tile = [ + ("INFINITE", (0, 0, 128, 128), 0, ("RGB", 0, 1)), + ] + ImageFile.LOAD_TRUNCATED_IMAGES = True + im.load() + ImageFile.LOAD_TRUNCATED_IMAGES = False + @pytest.mark.skipif(not is_win32(), reason="Windows only") @skip_unless_feature("jpg") diff --git a/src/PIL/JpegImagePlugin.py b/src/PIL/JpegImagePlugin.py index a4fc5936b61..ccdcc20a896 100644 --- a/src/PIL/JpegImagePlugin.py +++ b/src/PIL/JpegImagePlugin.py @@ -401,9 +401,10 @@ def load_read(self, read_bytes): """ s = self.fp.read(read_bytes) - if not s and ImageFile.LOAD_TRUNCATED_IMAGES: + if not s and ImageFile.LOAD_TRUNCATED_IMAGES and not hasattr(self, "_ended"): # Premature EOF. # Pretend file is finished adding EOI marker + self._ended = True return b"\xFF\xD9" return s