diff --git a/Lib/tarfile.py b/Lib/tarfile.py index b5b28cff419a71..45ffc77ce52089 100644 --- a/Lib/tarfile.py +++ b/Lib/tarfile.py @@ -2360,11 +2360,14 @@ def addfile(self, tarinfo, fileobj=None): raise ValueError("fileobj not provided for non zero-size regular file") tarinfo = copy.copy(tarinfo) - + # get current offset + tarinfo.offset = self.offset buf = tarinfo.tobuf(self.format, self.encoding, self.errors) self.fileobj.write(buf) self.offset += len(buf) + # add original offset to block size bufsize=self.copybufsize + tarinfo.offset_data = self.offset # If there's data to follow, append it. if fileobj is not None: copyfileobj(fileobj, self.fileobj, tarinfo.size, bufsize=bufsize) diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py index 62a262740a7efa..a9b7ab18b5efdc 100644 --- a/Lib/test/test_tarfile.py +++ b/Lib/test/test_tarfile.py @@ -1485,6 +1485,29 @@ class WriteTest(WriteTestBase, unittest.TestCase): prefix = "w:" + def test_addfile_sets_offsets(self): + # gh-150075: addfile() must set offset and offset_data on the + # TarInfo stored in the archive so they match a subsequent read. + data = b"data" + + with tarfile.open(tmpname, self.mode) as tar: + t1 = tarfile.TarInfo("test1.txt") + t1.size = len(data) + tar.addfile(t1, io.BytesIO(data)) + + t2 = tarfile.TarInfo("test2.txt") + t2.size = len(data) + tar.addfile(t2, io.BytesIO(data)) + + write_members = tar.getmembers() + + with tarfile.open(tmpname) as tar: + read_members = tar.getmembers() + + for w, r in zip(write_members, read_members): + self.assertEqual(w.offset, r.offset) + self.assertEqual(w.offset_data, r.offset_data) + def test_100_char_name(self): # The name field in a tar header stores strings of at most 100 chars. # If a string is shorter than 100 chars it has to be padded with '\0', diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-05-21-14-21-06.gh-issue-150075.dLI21Z.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-05-21-14-21-06.gh-issue-150075.dLI21Z.rst new file mode 100644 index 00000000000000..bf04e688025c71 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-05-21-14-21-06.gh-issue-150075.dLI21Z.rst @@ -0,0 +1 @@ +tar.addfile() doesn't set member offsets in 3.15. From reviewing the file it seemed like the copy was not adding the proper offsets to the tarinfo object. The way I fixed this is that I added the classes current offset of when.addFile is called and then added the block size after .tobuf function was called.