Issue #8741: Fixed the TarFile.makelink() method that is responsible
for extracting symbolic and hard link entries as regular files as a
work-around on platforms that do not support filesystem links.
This stopped working reliably after a change in r74571. I also added
a few tests for this functionality.
diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py
index 0d58cda..cda5262 100644
--- a/Lib/test/test_tarfile.py
+++ b/Lib/test/test_tarfile.py
@@ -134,6 +134,26 @@
"read() after readline() failed")
fobj.close()
+ # Test if symbolic and hard links are resolved by extractfile(). The
+ # test link members each point to a regular member whose data is
+ # supposed to be exported.
+ def _test_fileobj_link(self, lnktype, regtype):
+ a = self.tar.extractfile(lnktype)
+ b = self.tar.extractfile(regtype)
+ self.assertEqual(a.name, b.name)
+
+ def test_fileobj_link1(self):
+ self._test_fileobj_link("ustar/lnktype", "ustar/regtype")
+
+ def test_fileobj_link2(self):
+ self._test_fileobj_link("./ustar/linktest2/lnktype", "ustar/linktest1/regtype")
+
+ def test_fileobj_symlink1(self):
+ self._test_fileobj_link("ustar/symtype", "ustar/regtype")
+
+ def test_fileobj_symlink2(self):
+ self._test_fileobj_link("./ustar/linktest2/symtype", "ustar/linktest1/regtype")
+
class CommonReadTest(ReadTest):
@@ -1376,6 +1396,29 @@
fobj.close()
+class LinkEmulationTest(ReadTest):
+
+ # Test for issue #8741 regression. On platforms that do not support
+ # symbolic or hard links tarfile tries to extract these types of members as
+ # the regular files they point to.
+ def _test_link_extraction(self, name):
+ self.tar.extract(name, TEMPDIR)
+ data = open(os.path.join(TEMPDIR, name), "rb").read()
+ self.assertEqual(md5sum(data), md5_regtype)
+
+ def test_hardlink_extraction1(self):
+ self._test_link_extraction("ustar/lnktype")
+
+ def test_hardlink_extraction2(self):
+ self._test_link_extraction("./ustar/linktest2/lnktype")
+
+ def test_symlink_extraction1(self):
+ self._test_link_extraction("ustar/symtype")
+
+ def test_symlink_extraction2(self):
+ self._test_link_extraction("./ustar/linktest2/symtype")
+
+
class GzipMiscReadTest(MiscReadTest):
tarname = gzipname
mode = "r:gz"
@@ -1460,6 +1503,8 @@
if hasattr(os, "link"):
tests.append(HardlinkTest)
+ else:
+ tests.append(LinkEmulationTest)
fobj = open(tarname, "rb")
data = fobj.read()