tarfile silently stops/skips on bad member header (e.g. checksum mismatch)
未關閉
還沒有人認領這個 Issue。
type-bug
- 主要語言
- Python
- 星號
- 77.2k
- 分支
- 36k
- PR 合併指標
- PR 指標待擷取
描述
Bug report
Bug description:
When reading a tar archive that includes a file with a bad header (such as a checksum mismatch), getmembers simply stops listing the members at that file, without reporting an error, and ignoring the files that come after it (Edit: unless ignore_zeros=True is set).
I would expect instead that getmembers lists all members, and extractfile raises a TarError when trying to extract a file with an invalid header (such as a bad chksum or typeflag).
import os
import contextlib
import subprocess
from io import BytesIO
from tarfile import TarFile, TarInfo
from tempfile import TemporaryDirectory
# generate a tar file in memory
bio = BytesIO()
with TarFile(mode="w", fileobj=bio, errorlevel=2) as tf:
ti = TarInfo()
ti.size = 3
for name, data in (("foo", b"123"), ("bar", b"456"), ("quz", b"789")):
ti.name = name
tf.addfile(ti, BytesIO(data))
# break the checksum of the second file 'bar'
assert b"\x00006425\x00" in bio.getvalue()
broken = bio.getvalue().replace(b"\x00006425\x00", b"\x00106425\x00")
# try to read the tar file
with TarFile(fileobj=BytesIO(broken), errorlevel=2) as tf:
for ti in tf.getmembers():
print(repr(ti.name))
with tf.extractfile(ti) as fh:
print(repr(fh.read()))
# => only "foo" is extracted
with TemporaryDirectory() as td:
with contextlib.chdir(td):
with TarFile(fileobj=BytesIO(broken), errorlevel=2) as tf:
tf.extractall()
print(os.listdir())
# => again only "foo" is extracted
os.unlink("foo")
with TarFile(fileobj=BytesIO(broken), errorlevel=2) as tf:
tf.extractall(filter="data")
print(os.listdir())
# => filter doesn't change anything
with open("test.tar", "wb") as fh:
fh.write(broken)
subprocess.run(["tar", "tvf", "test.tar"], check=False)
# => GNU tar 1.34 correctly identifies error and continues processing
Output:
'foo'
b'123'
['foo']
['foo']
-rw-r--r-- 0/0 3 1970-01-01 00:00 foo
tar: Skipping to next header
-rw-r--r-- 0/0 3 1970-01-01 00:00 quz
tar: Exiting with failure status due to previous errors
CPython versions tested on:
3.12, 3.13
Operating systems tested on:
Linux, Windows
貢獻指南
從這裡開始
- 先讀完整個 Issue,再讀專案的貢獻指南。
- 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
- Fork 儲存庫,在一個分支上完成修改。
- 送出 Pull Request,並在描述裡引用這個 Issue 編號。
研究方向
使用提供的 BytesIO 範例重現該行為,然後從報告中列出的進入點 TarFile.getmembers()、extractfile() 和 extractall() 開始。追蹤無效成員標頭的處理方式,以及後續標頭是如何被存取到的。完成的標準是:依要求回報錯誤的標頭,同時後續有效成員仍可繼續處理,且受影響的行為有測試涵蓋。
由索引模型根據 Issue 內容生成。
評估
- 技術堆疊
- python
- 領域
- backend
- Issue 類型
- 缺陷
- 難度
- 4/5
- 預估耗時
- 3-5 天
- 活躍度
- 停滯
- 描述清晰度
- 基本清楚
- 新手友好度
- 48/100