mirror of
https://github.com/python/cpython.git
synced 2026-10-28 18:35:21 +08:00
gh-150075: tar.addfile() now sets member offsets in active TarInfo (GH-150278)
The on-disk data was correct, but the in-memory TarInfo was not being properly updated. --------- Signed-off-by: grantlouisherman <grantlouisherman041@gmail.com> Co-authored-by: Ethan Furman <ethan@stoneleaf.us>
This commit is contained in:
1 parent
ba96fab734
commit
0a86a343f0
3 files changed
+28
-1
No files matched your search
+4
-1
@@ -2456,11 +2456,14 @@ class TarFile(object):
|
||||
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)
|
||||
|
||||
@@ -1700,6 +1700,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',
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
tar.addfile() now sets member offsets in TarInfo objects
|
||||
Reference in new issue
Block a user