From e0f80563a2a5a2ce93ed6e916863e6b03b1996e8 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Tue, 19 Nov 2024 23:38:43 +1100 Subject: [PATCH] 8559 suggestion --- src/PIL/TiffImagePlugin.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/PIL/TiffImagePlugin.py b/src/PIL/TiffImagePlugin.py index 6bf39b75a5f..5c88f5e53ef 100644 --- a/src/PIL/TiffImagePlugin.py +++ b/src/PIL/TiffImagePlugin.py @@ -1216,10 +1216,6 @@ def seek(self, frame: int) -> None: def _seek(self, frame: int) -> None: self.fp = self._fp - # reset buffered io handle in case fp - # was passed to libtiff, invalidating the buffer - self.fp.tell() - while len(self._frame_pos) <= frame: if not self.__next: msg = "no more images in TIFF file" @@ -1303,10 +1299,6 @@ def load_end(self) -> None: if not self.is_animated: self._close_exclusive_fp_after_loading = True - # reset buffered io handle in case fp - # was passed to libtiff, invalidating the buffer - self.fp.tell() - # load IFD data from fp before it is closed exif = self.getexif() for key in TiffTags.TAGS_V2_GROUPS: @@ -1381,8 +1373,16 @@ def _load_libtiff(self) -> Image.core.PixelAccess | None: logger.debug("have fileno, calling fileno version of the decoder.") if not close_self_fp: self.fp.seek(0) + # Save and restore the file position, because libtiff will move it + # outside of the Python runtime, and that will confuse + # io.BufferedReader and possibly others. + # This must use os.lseek, and not fp.seek(), + # because fp.seek() may just adjust it's internal buffer pointer + # and not actually move the OS file handle. + pos = os.lseek(fp, 0, os.SEEK_CUR) # 4 bytes, otherwise the trace might error out n, err = decoder.decode(b"fpfp") + os.lseek(fp, pos, os.SEEK_SET) else: # we have something else. logger.debug("don't have fileno or getvalue. just reading")