summaryrefslogtreecommitdiffstats
path: root/Lib/tarfile.py
diff options
context:
space:
mode:
authorWilliam Chargin <wchargin@gmail.com>2020-02-12 19:56:02 (GMT)
committerGitHub <noreply@github.com>2020-02-12 19:56:02 (GMT)
commit674935b8caf33e47c78f1b8e197b1b77a04992d2 (patch)
treefc7f81510ae2bdf298f3fc8dd2c3d2b7584ebc18 /Lib/tarfile.py
parent4fac7ed43ebf1771a8fe86fdfe7b9991f3be78cd (diff)
downloadcpython-674935b8caf33e47c78f1b8e197b1b77a04992d2.zip
cpython-674935b8caf33e47c78f1b8e197b1b77a04992d2.tar.gz
cpython-674935b8caf33e47c78f1b8e197b1b77a04992d2.tar.bz2
bpo-18819: tarfile: only set device fields for device files (GH-18080)
The GNU docs describe the `devmajor` and `devminor` fields of the tar header struct only in the context of character and block special files, suggesting that in other cases they are not populated. Typical utilities behave accordingly; this patch teaches `tarfile` to do the same.
Diffstat (limited to 'Lib/tarfile.py')
-rwxr-xr-xLib/tarfile.py12
1 files changed, 10 insertions, 2 deletions
diff --git a/Lib/tarfile.py b/Lib/tarfile.py
index 90a2c95..e2b6053 100755
--- a/Lib/tarfile.py
+++ b/Lib/tarfile.py
@@ -930,6 +930,14 @@ class TarInfo(object):
"""Return a header block. info is a dictionary with file
information, format must be one of the *_FORMAT constants.
"""
+ has_device_fields = info.get("type") in (CHRTYPE, BLKTYPE)
+ if has_device_fields:
+ devmajor = itn(info.get("devmajor", 0), 8, format)
+ devminor = itn(info.get("devminor", 0), 8, format)
+ else:
+ devmajor = stn("", 8, encoding, errors)
+ devminor = stn("", 8, encoding, errors)
+
parts = [
stn(info.get("name", ""), 100, encoding, errors),
itn(info.get("mode", 0) & 0o7777, 8, format),
@@ -943,8 +951,8 @@ class TarInfo(object):
info.get("magic", POSIX_MAGIC),
stn(info.get("uname", ""), 32, encoding, errors),
stn(info.get("gname", ""), 32, encoding, errors),
- itn(info.get("devmajor", 0), 8, format),
- itn(info.get("devminor", 0), 8, format),
+ devmajor,
+ devminor,
stn(info.get("prefix", ""), 155, encoding, errors)
]