From e45da2ae17e79cd2e02bc894f3c825f9126101a0 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Mon, 5 Jun 2023 11:07:09 +1000 Subject: [PATCH 1/2] Do not close provided file handles with libtiff --- src/PIL/TiffImagePlugin.py | 10 +--------- src/libImaging/TiffDecode.c | 6 +++++- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/src/PIL/TiffImagePlugin.py b/src/PIL/TiffImagePlugin.py index 1ca1b6ea9af..3476786421f 100644 --- a/src/PIL/TiffImagePlugin.py +++ b/src/PIL/TiffImagePlugin.py @@ -1253,9 +1253,8 @@ def _load_libtiff(self): # To be nice on memory footprint, if there's a # file descriptor, use that instead of reading # into a string in python. - # libtiff closes the file descriptor, so pass in a dup. try: - fp = hasattr(self.fp, "fileno") and os.dup(self.fp.fileno()) + fp = hasattr(self.fp, "fileno") and self.fp.fileno() # flush the file descriptor, prevents error on pypy 2.4+ # should also eliminate the need for fp.tell # in _seek @@ -1305,18 +1304,11 @@ def _load_libtiff(self): # UNDONE -- so much for that buffer size thing. n, err = decoder.decode(self.fp.read()) - if fp: - try: - os.close(fp) - except OSError: - pass - self.tile = [] self.readonly = 0 self.load_end() - # libtiff closed the fp in a, we need to close self.fp, if possible if close_self_fp: self.fp.close() self.fp = None # might be shared diff --git a/src/libImaging/TiffDecode.c b/src/libImaging/TiffDecode.c index 428cd93d278..9361de83479 100644 --- a/src/libImaging/TiffDecode.c +++ b/src/libImaging/TiffDecode.c @@ -720,7 +720,11 @@ ImagingLibTiffDecode( } decode_err: - TIFFClose(tiff); + if (clientstate->fp) { + TIFFCleanup(tiff); + } else { + TIFFClose(tiff); + } TRACE(("Done Decoding, Returning \n")); // Returning -1 here to force ImageFile.load to break, rather than // even think about looping back around. From 0835be95cbbdc1beaac0dfaccd7a358621f619bf Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Mon, 5 Jun 2023 15:07:11 +1000 Subject: [PATCH 2/2] Added comment --- src/libImaging/TiffDecode.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libImaging/TiffDecode.c b/src/libImaging/TiffDecode.c index 9361de83479..35122f18245 100644 --- a/src/libImaging/TiffDecode.c +++ b/src/libImaging/TiffDecode.c @@ -720,9 +720,14 @@ ImagingLibTiffDecode( } decode_err: + // TIFFClose in libtiff calls tif_closeproc and TIFFCleanup if (clientstate->fp) { + // Pillow will manage the closing of the file rather than libtiff + // So only call TIFFCleanup TIFFCleanup(tiff); } else { + // When tif_closeproc refers to our custom _tiffCloseProc though, + // that is fine, as it does not close the file TIFFClose(tiff); } TRACE(("Done Decoding, Returning \n"));