mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-01-13 10:46:16 +03:00
Merge pull request #580 from wiredfool/libtiff-fd-leak
Fixes libtiff leaking open files
This commit is contained in:
commit
0baa82ac69
|
@ -693,10 +693,11 @@ class TiffImageFile(ImageFile.ImageFile):
|
||||||
if not len(self.tile) == 1:
|
if not len(self.tile) == 1:
|
||||||
raise IOError("Not exactly one tile")
|
raise IOError("Not exactly one tile")
|
||||||
|
|
||||||
d, e, o, a = self.tile[0]
|
# (self._compression, (extents tuple), 0, (rawmode, self._compression, fp))
|
||||||
d = Image._getdecoder(self.mode, 'libtiff', a, self.decoderconfig)
|
ignored, extents, ignored_2, args = self.tile[0]
|
||||||
|
decoder = Image._getdecoder(self.mode, 'libtiff', args, self.decoderconfig)
|
||||||
try:
|
try:
|
||||||
d.setimage(self.im, e)
|
decoder.setimage(self.im, extents)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
raise IOError("Couldn't set the image")
|
raise IOError("Couldn't set the image")
|
||||||
|
|
||||||
|
@ -712,27 +713,30 @@ class TiffImageFile(ImageFile.ImageFile):
|
||||||
# with here by reordering.
|
# with here by reordering.
|
||||||
if Image.DEBUG:
|
if Image.DEBUG:
|
||||||
print ("have getvalue. just sending in a string from getvalue")
|
print ("have getvalue. just sending in a string from getvalue")
|
||||||
n,e = d.decode(self.fp.getvalue())
|
n,err = decoder.decode(self.fp.getvalue())
|
||||||
elif hasattr(self.fp, "fileno"):
|
elif hasattr(self.fp, "fileno"):
|
||||||
# we've got a actual file on disk, pass in the fp.
|
# we've got a actual file on disk, pass in the fp.
|
||||||
if Image.DEBUG:
|
if Image.DEBUG:
|
||||||
print ("have fileno, calling fileno version of the decoder.")
|
print ("have fileno, calling fileno version of the decoder.")
|
||||||
self.fp.seek(0)
|
self.fp.seek(0)
|
||||||
n,e = d.decode(b"fpfp") # 4 bytes, otherwise the trace might error out
|
n,err = decoder.decode(b"fpfp") # 4 bytes, otherwise the trace might error out
|
||||||
else:
|
else:
|
||||||
# we have something else.
|
# we have something else.
|
||||||
if Image.DEBUG:
|
if Image.DEBUG:
|
||||||
print ("don't have fileno or getvalue. just reading")
|
print ("don't have fileno or getvalue. just reading")
|
||||||
# UNDONE -- so much for that buffer size thing.
|
# UNDONE -- so much for that buffer size thing.
|
||||||
n, e = d.decode(self.fp.read())
|
n,err = decoder.decode(self.fp.read())
|
||||||
|
|
||||||
|
|
||||||
self.tile = []
|
self.tile = []
|
||||||
self.readonly = 0
|
self.readonly = 0
|
||||||
|
# libtiff closed the fp in a, we need to close self.fp, if possible
|
||||||
|
if hasattr(self.fp, 'close'):
|
||||||
|
self.fp.close()
|
||||||
self.fp = None # might be shared
|
self.fp = None # might be shared
|
||||||
|
|
||||||
if e < 0:
|
if err < 0:
|
||||||
raise IOError(e)
|
raise IOError(err)
|
||||||
|
|
||||||
self.load_end()
|
self.load_end()
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
from tester import *
|
from tester import *
|
||||||
|
import os
|
||||||
|
|
||||||
from PIL import Image, TiffImagePlugin
|
from PIL import Image, TiffImagePlugin
|
||||||
|
|
||||||
|
@ -295,3 +296,13 @@ def xtest_bw_compression_wRGB():
|
||||||
assert_exception(IOError, lambda: im.save(out, compression='group3'))
|
assert_exception(IOError, lambda: im.save(out, compression='group3'))
|
||||||
assert_exception(IOError, lambda: im.save(out, compression='group4'))
|
assert_exception(IOError, lambda: im.save(out, compression='group4'))
|
||||||
|
|
||||||
|
def test_fp_leak():
|
||||||
|
im = Image.open("Tests/images/lena_g4_500.tif")
|
||||||
|
fn = im.fp.fileno()
|
||||||
|
|
||||||
|
assert_no_exception(lambda: os.fstat(fn))
|
||||||
|
im.load() # this should close it.
|
||||||
|
assert_exception(OSError, lambda: os.fstat(fn))
|
||||||
|
im = None # this should force even more closed.
|
||||||
|
assert_exception(OSError, lambda: os.fstat(fn))
|
||||||
|
assert_exception(OSError, lambda: os.close(fn))
|
||||||
|
|
Loading…
Reference in New Issue
Block a user