You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
tarfile: GNU sparse 1.0 pax tar header offset not properly computed #83869
When tarfile open a tar containing a sparse file where actual data is bigger than 0o77777777777 bytes (~8GB), it fails listing members after this file. As so, it is impossible to access/extract files located after a such file inside the archive.
A tar file presenting the issue is available at https://genua.fr/sample.tar.xz
Uncompressed the file is ~16GB.
It containes two files:
disk.img a 50GB sparse file containing ~16GB of data
README.txt a simple text file containing "This last file is not properly listed"
disk.img was generated using the folowing python script:
members [<TarInfo 'disk.img' at 0x7f5b14242b38>]
offset 17179806208
members should also list README.txt.
I think I have found the root cause of the bug: Because the file is bigger than 0o77777777777, it's size cannot be specified inside the tar ustar header, so a "size" pax extented header is generated. This header contain the full size of the file block in the tar.
As the file is sparse, as of sparse format 1.0, the file block contains first a sparse mapping, then the file data. So this block size is the size of the mapping added to the size of the data.
Because the file is sparse, a GNU.sparse.realsize header is also added containing the full expanded file size (here 50GB).
the file offset is moved forward from GNU.sparse.realsize (50GB) instead of pax_headers["size"]. Moreover, the move is done from next.offset_data which is set at https://github.com/python/cpython/blob/master/Lib/tarfile.py#L1338 to after the sparse mapping.
The move forward in the sparse file should be made from next.offset + BLOCKSIZE.
I am currently unable to create pull request on github (error 500)
nitmir commented on Feb 19, 2020
nitmirmannequin
MannequinAuthor
More actions
hum trying to be clever and I am doing mistakes.
This commit is simpler and effectively fixes the issue nitmir@682138a
tarinfo.offset_data is where tarfile start reading the file data and thus must be set to the beginning of the actual data for a sparse file even if the data block starts before.
Activity
nitmir commentedon Feb 19, 2020
When tarfile open a tar containing a sparse file where actual data is bigger than 0o77777777777 bytes (~8GB), it fails listing members after this file. As so, it is impossible to access/extract files located after a such file inside the archive.
A tar file presenting the issue is available at https://genua.fr/sample.tar.xz
Uncompressed the file is ~16GB.
It containes two files:
disk.img was generated using the folowing python script:
sample.tar was generated using GNU tar 1.30 on a Debian 10 with the following command:
tar --format pax -cvSf sample.tar disk.img README.txt
The following script expose the issue:
Its output is:
members [<TarInfo 'disk.img' at 0x7f5b14242b38>]
offset 17179806208
members should also list README.txt.
I think I have found the root cause of the bug: Because the file is bigger than 0o77777777777, it's size cannot be specified inside the tar ustar header, so a "size" pax extented header is generated. This header contain the full size of the file block in the tar.
As the file is sparse, as of sparse format 1.0, the file block contains first a sparse mapping, then the file data. So this block size is the size of the mapping added to the size of the data.
Because the file is sparse, a GNU.sparse.realsize header is also added containing the full expanded file size (here 50GB).
Here
cpython/Lib/tarfile.py
Line 1350 in 4dee92b
cpython/Lib/tarfile.py
Line 1297 in 4dee92b
The move forward in the sparse file should be made from next.offset + BLOCKSIZE.
nitmir commentedon Feb 19, 2020
This commit fix the issue nitmir@50c1f68
I am currently unable to create pull request on github (error 500)
nitmir commentedon Feb 19, 2020
hum trying to be clever and I am doing mistakes.
This commit is simpler and effectively fixes the issue nitmir@682138a
tarinfo.offset_data is where tarfile start reading the file data and thus must be set to the beginning of the actual data for a sparse file even if the data block starts before.
gh-83869: tarfile: compute next header offset using pax size for spar…
[3.13] gh-83869: tarfile: compute next header offset using pax size f…
[3.14] gh-83869: tarfile: compute next header offset using pax size f…
[3.15] gh-83869: tarfile: compute next header offset using pax size f…
gpshead commentedon Oct 14, 2026
This appears to have caused a regression FYI - #159435 @serhiy-storchaka