You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
tarfile: zstopen uses except Exception: and leaks fileobj on BaseException, inconsistent with gzopen/bz2open/xzopen #150077
In Lib/tarfile.py, the four compressed-archive open classmethods all share
the same structure: open an underlying compressed file object, then wrap it
with cls.taropen(...). If taropen fails, they catch the exception, close
the just-opened fileobj, and re-raise.
Three of them — gzopen , bz2open , xzopen — use a bareexcept: for the final cleanup branch. zstopen
uses except Exception: (line 2099) instead:
# Lib/tarfile.py — gzopen / bz2open / xzopen (consistent across all three)except:
fileobj.close()
raise# Lib/tarfile.py — zstopen (the outlier)exceptException:
fileobj.close()
raise
A bare except: is equivalent to except BaseException: and catches KeyboardInterrupt, SystemExit, and asyncio.CancelledError (which is a BaseException subclass since 3.8). except Exception: does not. As a
result, if any of those exceptions is raised during the cls.taropen(...)
call inside zstopen — e.g. the user hits Ctrl+C, the surrounding async task
is cancelled, or the process is shutting down — fileobj.close() is never
called and the file descriptor held by ZstdFile is leaked.
The same scenario is handled correctly by gzopen/bz2open/xzopen.
This is the classic "catch-and-cleanup-and-rethrow" pattern: the bare except: is intentional here, because the only purpose of the handler is to
release the resource before letting the exception propagate. The exception
is not swallowed.
Replacing "compression.zstd.ZstdFile" with "gzip.GzipFile" (and zstopen with gzopen) prints True, confirming the inconsistency.
Suggested fix
In Lib/tarfile.py:2099, change except Exception: to bare except: (or
the equivalent except BaseException:), matching the existing convention in gzopen/bz2open/xzopen:
A parameterized regression test across all four compressed-open methods
should be added to Lib/test/test_tarfile.py so that any future compressed
format added to tarfile is held to the same cleanup contract.
Activity
gh-150077: Fix fileobj leak in `tarfile.TarFile.zstopen` on `BaseExce…