Kaydet (Commit) 7fd59e09 authored tarafından Benjamin Peterson's avatar Benjamin Peterson

properly handle file closing in error cases (closes #22266)

üst ce2ec49d
...@@ -417,6 +417,7 @@ class _Stream: ...@@ -417,6 +417,7 @@ class _Stream:
self.pos = 0L self.pos = 0L
self.closed = False self.closed = False
try:
if comptype == "gz": if comptype == "gz":
try: try:
import zlib import zlib
...@@ -429,7 +430,7 @@ class _Stream: ...@@ -429,7 +430,7 @@ class _Stream:
else: else:
self._init_write_gz() self._init_write_gz()
if comptype == "bz2": elif comptype == "bz2":
try: try:
import bz2 import bz2
except ImportError: except ImportError:
...@@ -439,6 +440,11 @@ class _Stream: ...@@ -439,6 +440,11 @@ class _Stream:
self.cmp = bz2.BZ2Decompressor() self.cmp = bz2.BZ2Decompressor()
else: else:
self.cmp = bz2.BZ2Compressor() self.cmp = bz2.BZ2Compressor()
except:
if not self._extfileobj:
self.fileobj.close()
self.closed = True
raise
def __del__(self): def __del__(self):
if hasattr(self, "closed") and not self.closed: if hasattr(self, "closed") and not self.closed:
...@@ -1685,9 +1691,12 @@ class TarFile(object): ...@@ -1685,9 +1691,12 @@ class TarFile(object):
if filemode not in ("r", "w"): if filemode not in ("r", "w"):
raise ValueError("mode must be 'r' or 'w'") raise ValueError("mode must be 'r' or 'w'")
t = cls(name, filemode, stream = _Stream(name, filemode, comptype, fileobj, bufsize)
_Stream(name, filemode, comptype, fileobj, bufsize), try:
**kwargs) t = cls(name, filemode, stream, **kwargs)
except:
stream.close()
raise
t._extfileobj = False t._extfileobj = False
return t return t
...@@ -1718,17 +1727,23 @@ class TarFile(object): ...@@ -1718,17 +1727,23 @@ class TarFile(object):
except (ImportError, AttributeError): except (ImportError, AttributeError):
raise CompressionError("gzip module is not available") raise CompressionError("gzip module is not available")
if fileobj is None: try:
fileobj = bltn_open(name, mode + "b") fileobj = gzip.GzipFile(name, mode, compresslevel, fileobj)
except OSError:
if fileobj is not None and mode == 'r':
raise ReadError("not a gzip file")
raise
try: try:
t = cls.taropen(name, mode, t = cls.taropen(name, mode, fileobj, **kwargs)
gzip.GzipFile(name, mode, compresslevel, fileobj),
**kwargs)
except IOError: except IOError:
fileobj.close()
if mode == 'r': if mode == 'r':
raise ReadError("not a gzip file") raise ReadError("not a gzip file")
raise raise
except:
fileobj.close()
raise
t._extfileobj = False t._extfileobj = False
return t return t
...@@ -1753,9 +1768,13 @@ class TarFile(object): ...@@ -1753,9 +1768,13 @@ class TarFile(object):
try: try:
t = cls.taropen(name, mode, fileobj, **kwargs) t = cls.taropen(name, mode, fileobj, **kwargs)
except (IOError, EOFError): except (IOError, EOFError):
fileobj.close()
if mode == 'r': if mode == 'r':
raise ReadError("not a bzip2 file") raise ReadError("not a bzip2 file")
raise raise
except:
fileobj.close()
raise
t._extfileobj = False t._extfileobj = False
return t return t
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment