mirror of
https://github.com/python/cpython.git
synced 2025-08-09 11:29:45 +00:00
bpo-45863: tarfile: don't zero out header fields unnecessarily (GH-29693)
Numeric fields of type float, notably mtime, can't be represented
exactly in the ustar header, so the pax header is used. But it is
helpful to set them to the nearest int (i.e. second rather than
nanosecond precision mtimes) in the ustar header as well, for the
benefit of unarchivers that don't understand the pax header.
Add test for tarfile.TarInfo.create_pax_header to confirm correct
behaviour.
(cherry picked from commit bf2d44ffb0
)
Co-authored-by: Joshua Root <jmr@macports.org>
This commit is contained in:
parent
bde3765a3f
commit
b0517a1217
3 changed files with 71 additions and 6 deletions
|
@ -887,15 +887,24 @@ class TarInfo(object):
|
|||
# Test number fields for values that exceed the field limit or values
|
||||
# that like to be stored as float.
|
||||
for name, digits in (("uid", 8), ("gid", 8), ("size", 12), ("mtime", 12)):
|
||||
if name in pax_headers:
|
||||
# The pax header has priority. Avoid overflow.
|
||||
info[name] = 0
|
||||
continue
|
||||
needs_pax = False
|
||||
|
||||
val = info[name]
|
||||
if not 0 <= val < 8 ** (digits - 1) or isinstance(val, float):
|
||||
pax_headers[name] = str(val)
|
||||
val_is_float = isinstance(val, float)
|
||||
val_int = round(val) if val_is_float else val
|
||||
if not 0 <= val_int < 8 ** (digits - 1):
|
||||
# Avoid overflow.
|
||||
info[name] = 0
|
||||
needs_pax = True
|
||||
elif val_is_float:
|
||||
# Put rounded value in ustar header, and full
|
||||
# precision value in pax header.
|
||||
info[name] = val_int
|
||||
needs_pax = True
|
||||
|
||||
# The existing pax header has priority.
|
||||
if needs_pax and name not in pax_headers:
|
||||
pax_headers[name] = str(val)
|
||||
|
||||
# Create a pax extended header if necessary.
|
||||
if pax_headers:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue