python / python/cpython

tarfile: TarFile.offset attribute is not updated with the remainder when closing a TarFile

未關閉
#129,255 2 則留言 0 個 reaction 已指派 0 人 在 GitHub 檢視

還沒有人認領這個 Issue。

stdlib type-bug
主要語言
Python
星號
77.2k
分支
36k
PR 合併指標
PR 指標待擷取

描述

Bug report

Bug description:

The TarFile.offset attribute is not updated with the remainder when closing the tar.

import io
import pathlib
import tarfile

tar = tarfile.open("test.tar", "w")
t = tarfile.TarInfo("foo")
t.size = 123
tar.addfile(t, io.BytesIO(b"a" * t.size))
tar.close()
assert len(pathlib.Path("test.tar").read_bytes()) == tar.offset  # Fails because tar.offset is 2048, although 10240 bytes have been written

If this intentional, a test case asserting the current behavior should be added.
In case this is not intentional, a suggested change to make the offset match the number of bytes written, and a test case asserting it, are included in the snippet below.
In either case, I'd be happy to submit a PR.

diff --git a/Lib/tarfile.py b/Lib/tarfile.py
index a0fab46b24e..feafb88d2d3 100644
--- a/Lib/tarfile.py
+++ b/Lib/tarfile.py
@@ -2027,6 +2027,7 @@ def close(self):
                 blocks, remainder = divmod(self.offset, RECORDSIZE)
                 if remainder > 0:
                     self.fileobj.write(NUL * (RECORDSIZE - remainder))
+                    self.offset += (RECORDSIZE - remainder)
         finally:
             if not self._extfileobj:
                 self.fileobj.close()
diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py
index 2549b6b35ad..4d1a2b2171b 100644
--- a/Lib/test/test_tarfile.py
+++ b/Lib/test/test_tarfile.py
@@ -1333,6 +1333,18 @@ def test_eof_marker(self):
         with self.open(tmpname, "rb") as fobj:
             self.assertEqual(len(fobj.read()), tarfile.RECORDSIZE * 2)

+    def test_offset_on_close(self):
+        # Check the offset after calling close matches the total number of
+        # bytes written.
+        tar = tarfile.open(tmpname, self.mode)
+        t = tarfile.TarInfo("foo")
+        tar.addfile(t)
+        tar.close()
+
+        with self.open(tmpname, "rb") as fobj:
+            self.assertEqual(len(fobj.read()), tar.offset)
+

 class WriteTest(WriteTestBase, unittest.TestCase):
CPython versions tested on:

3.14, 3.13

Operating systems tested on:

Linux

Linked PRs
  • gh-133919

貢獻指南

開啟貢獻指南

從這裡開始

  1. 先讀完整個 Issue,再讀專案的貢獻指南。
  2. 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
  3. Fork 儲存庫,在一個分支上完成修改。
  4. 送出 Pull Request,並在描述裡引用這個 Issue 編號。

研究方向

相關檔案是 Lib/tarfile.py 和 Lib/test/test_tarfile.py。先閱讀 TarFile.close 和現有的 EOF-marker 測試,然後執行 tarfile 測試套件。完成的標準是明確涵蓋 offset 行為,並且與關閉後寫入的預期位元組數一致。

由索引模型根據 Issue 內容生成。

評估

技術堆疊
python
領域
backend
Issue 類型
缺陷
難度
2/5
預估耗時
1-3 小時
活躍度
停滯
描述清晰度
描述清楚
新手友好度
25/100

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。