diff options
author | William Chargin <wchargin@gmail.com> | 2020-02-12 19:56:02 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-02-12 19:56:02 (GMT) |
commit | 674935b8caf33e47c78f1b8e197b1b77a04992d2 (patch) | |
tree | fc7f81510ae2bdf298f3fc8dd2c3d2b7584ebc18 /Lib/test | |
parent | 4fac7ed43ebf1771a8fe86fdfe7b9991f3be78cd (diff) | |
download | cpython-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.py | 46 |
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:" |