python / python/cpython

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

Offen
#129,255 2 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

stdlib type-bug
Vorherrschende Sprache
Python
Sterne
77.2k
Forks
35.9k
PR-Merge-Kennzahlen
PR-Kennzahlen ausstehend

Beschreibung

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

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Die relevanten Dateien sind Lib/tarfile.py und Lib/test/test_tarfile.py. Lies zunächst TarFile.close und die vorhandenen EOF-marker-Tests und führe dann die tarfile-Testsuite aus. Erledigt ist die Aufgabe, wenn das Verhalten des Offsets ausdrücklich abgedeckt ist und der vorgesehenen Anzahl von nach dem Schließen geschriebenen Bytes entspricht.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
python
Bereich
backend
Issue-Typ
Bug
Schwierigkeit
2/5
Geschätzter Aufwand
1-3 Stunden
Aktivitätsstatus
Veraltet
Klarheit
Klar beschrieben
Anfängerfreundlichkeit
25/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.