summaryrefslogtreecommitdiffstats
path: root/Lib/test
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/test
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/test')
-rw-r--r--Lib/test/test_tarfile.py46
1 files changed, 46 insertions, 0 deletions
diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py
index 6a90108..cae9680 100644
--- a/Lib/test/test_tarfile.py
+++ b/Lib/test/test_tarfile.py
@@ -1549,6 +1549,52 @@ class GNUWriteTest(unittest.TestCase):
("longlnk/" * 127) + "longlink_")
+class DeviceHeaderTest(WriteTestBase, unittest.TestCase):
+
+ prefix = "w:"
+
+ def test_headers_written_only_for_device_files(self):
+ # Regression test for bpo-18819.
+ tempdir = os.path.join(TEMPDIR, "device_header_test")
+ os.mkdir(tempdir)
+ try:
+ tar = tarfile.open(tmpname, self.mode)
+ try:
+ input_blk = tarfile.TarInfo(name="my_block_device")
+ input_reg = tarfile.TarInfo(name="my_regular_file")
+ input_blk.type = tarfile.BLKTYPE
+ input_reg.type = tarfile.REGTYPE
+ tar.addfile(input_blk)
+ tar.addfile(input_reg)
+ finally:
+ tar.close()
+
+ # devmajor and devminor should be *interpreted* as 0 in both...
+ tar = tarfile.open(tmpname, "r")
+ try:
+ output_blk = tar.getmember("my_block_device")
+ output_reg = tar.getmember("my_regular_file")
+ finally:
+ tar.close()
+ self.assertEqual(output_blk.devmajor, 0)
+ self.assertEqual(output_blk.devminor, 0)
+ self.assertEqual(output_reg.devmajor, 0)
+ self.assertEqual(output_reg.devminor, 0)
+
+ # ...but the fields should not actually be set on regular files:
+ with open(tmpname, "rb") as infile:
+ buf = infile.read()
+ buf_blk = buf[output_blk.offset:output_blk.offset_data]
+ buf_reg = buf[output_reg.offset:output_reg.offset_data]
+ # See `struct posixheader` in GNU docs for byte offsets:
+ # <https://www.gnu.org/software/tar/manual/html_node/Standard.html>
+ device_headers = slice(329, 329 + 16)
+ self.assertEqual(buf_blk[device_headers], b"0000000\0" * 2)
+ self.assertEqual(buf_reg[device_headers], b"\0" * 16)
+ finally:
+ support.rmtree(tempdir)
+
+
class CreateTest(WriteTestBase, unittest.TestCase):
prefix = "x:"