Fix closes issue #12088 - fixes the tarfile.extractall issue when the
symlinks/hardlink was broken. It handles now in a graceful manner (No exception is raised, behavior similar GNU tar).
This commit is contained in:
parent
72bb99d343
commit
4dd89ce6bf
|
@ -2239,12 +2239,14 @@ class TarFile(object):
|
|||
if hasattr(os, "symlink") and hasattr(os, "link"):
|
||||
# For systems that support symbolic and hard links.
|
||||
if tarinfo.issym():
|
||||
if os.path.exists(targetpath):
|
||||
if os.path.lexists(targetpath):
|
||||
os.unlink(targetpath)
|
||||
os.symlink(tarinfo.linkname, targetpath)
|
||||
else:
|
||||
# See extract().
|
||||
if os.path.exists(tarinfo._link_target):
|
||||
if os.path.lexists(targetpath):
|
||||
os.unlink(targetpath)
|
||||
os.link(tarinfo._link_target, targetpath)
|
||||
else:
|
||||
self._extract_member(self._find_link_target(tarinfo), targetpath)
|
||||
|
|
|
@ -872,6 +872,66 @@ class WriteTest(WriteTestBase):
|
|||
os.unlink(temparchive)
|
||||
shutil.rmtree(tempdir)
|
||||
|
||||
@unittest.skipUnless(hasattr(os, 'symlink'), "needs os.symlink")
|
||||
def test_extractall_broken_symlinks(self):
|
||||
# Test if extractall works properly when tarfile contains broken
|
||||
# symlinks
|
||||
tempdir = os.path.join(TEMPDIR, "testsymlinks")
|
||||
temparchive = os.path.join(TEMPDIR, "testsymlinks.tar")
|
||||
os.mkdir(tempdir)
|
||||
try:
|
||||
source_file = os.path.join(tempdir,'source')
|
||||
target_file = os.path.join(tempdir,'symlink')
|
||||
with open(source_file,'w') as f:
|
||||
f.write('something\n')
|
||||
os.symlink(source_file, target_file)
|
||||
tar = tarfile.open(temparchive,'w')
|
||||
tar.add(target_file, arcname=os.path.basename(target_file))
|
||||
tar.close()
|
||||
# remove the real file
|
||||
os.unlink(source_file)
|
||||
# Let's extract it to the location which contains the symlink
|
||||
tar = tarfile.open(temparchive,'r')
|
||||
# this should not raise OSError: [Errno 17] File exists
|
||||
try:
|
||||
tar.extractall(path=tempdir)
|
||||
except OSError:
|
||||
self.fail("extractall failed with broken symlinked files")
|
||||
finally:
|
||||
tar.close()
|
||||
finally:
|
||||
os.unlink(temparchive)
|
||||
shutil.rmtree(tempdir)
|
||||
|
||||
@unittest.skipUnless(hasattr(os, 'link'), "needs os.link")
|
||||
def test_extractall_hardlinks(self):
|
||||
# Test if extractall works properly when tarfile contains symlinks
|
||||
tempdir = os.path.join(TEMPDIR, "testsymlinks")
|
||||
temparchive = os.path.join(TEMPDIR, "testsymlinks.tar")
|
||||
os.mkdir(tempdir)
|
||||
try:
|
||||
source_file = os.path.join(tempdir,'source')
|
||||
target_file = os.path.join(tempdir,'symlink')
|
||||
with open(source_file,'w') as f:
|
||||
f.write('something\n')
|
||||
os.link(source_file, target_file)
|
||||
tar = tarfile.open(temparchive,'w')
|
||||
tar.add(source_file, arcname=os.path.basename(source_file))
|
||||
tar.add(target_file, arcname=os.path.basename(target_file))
|
||||
tar.close()
|
||||
# Let's extract it to the location which contains the symlink
|
||||
tar = tarfile.open(temparchive,'r')
|
||||
# this should not raise OSError: [Errno 17] File exists
|
||||
try:
|
||||
tar.extractall(path=tempdir)
|
||||
except OSError:
|
||||
self.fail("extractall failed with linked files")
|
||||
finally:
|
||||
tar.close()
|
||||
finally:
|
||||
os.unlink(temparchive)
|
||||
shutil.rmtree(tempdir)
|
||||
|
||||
class StreamWriteTest(WriteTestBase):
|
||||
|
||||
mode = "w|"
|
||||
|
|
Loading…
Reference in New Issue