Skip to content

Commit 682138a

Browse files
committed
bpo-39688: tarfile: compute next header offset using pax size for sparse file
In case of a sparse file, the tarinfo.size attribute is set to the sparse file expanded size (pax attribute GNU.sparse.size or GNU.sparse.size) and do not correspond to the actual size of the data block. The size of the data block is specified by the size pax header if present or by the ustar size header. Moreover, for GNU sparse 1.0 files, the data block start at the beginning of the sparse mapping and not after the sparse mapping and so the offset should be computed from here.
1 parent 4dee92b commit 682138a

1 file changed

Lines changed: 8 additions & 3 deletions

File tree

Lib/tarfile.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1292,17 +1292,22 @@ def _proc_pax(self, tarfile):
12921292
if self.type in (XHDTYPE, SOLARIS_XHDTYPE):
12931293
# Patch the TarInfo object with the extended header info.
12941294
next._apply_pax_info(pax_headers, tarfile.encoding, tarfile.errors)
1295-
next.offset = self.offset
12961295

12971296
if "size" in pax_headers:
12981297
# If the extended header replaces the size field,
12991298
# we need to recalculate the offset where the next
13001299
# header starts.
1301-
offset = next.offset_data
1300+
offset = next.offset + BLOCKSIZE
13021301
if next.isreg() or next.type not in SUPPORTED_TYPES:
1303-
offset += next._block(next.size)
1302+
try:
1303+
size = PAX_NUMBER_FIELDS["size"](pax_headers["size"])
1304+
except ValueError:
1305+
size = 0
1306+
offset += next._block(size)
13041307
tarfile.offset = offset
13051308

1309+
next.offset = self.offset
1310+
13061311
return next
13071312

13081313
def _proc_gnusparse_00(self, next, pax_headers, buf):

0 commit comments

Comments
 (0)