Skip to content

Commit 011525e

Browse files
committed
Fix closes issue10761: tarfile.extractall failure when symlinked files are present.
1 parent bdfa2e6 commit 011525e

File tree

3 files changed

+32
-0
lines changed

3 files changed

+32
-0
lines changed

Lib/tarfile.py

+2
Original file line numberDiff line numberDiff line change
@@ -2239,6 +2239,8 @@ def makelink(self, tarinfo, targetpath):
22392239
if hasattr(os, "symlink") and hasattr(os, "link"):
22402240
# For systems that support symbolic and hard links.
22412241
if tarinfo.issym():
2242+
if os.path.exists(targetpath):
2243+
os.unlink(targetpath)
22422244
os.symlink(tarinfo.linkname, targetpath)
22432245
else:
22442246
# See extract().

Lib/test/test_tarfile.py

+27
Original file line numberDiff line numberDiff line change
@@ -843,6 +843,33 @@ def test_cwd(self):
843843
finally:
844844
os.chdir(cwd)
845845

846+
def test_extractall_symlinks(self):
847+
# Test if extractall works properly when tarfile contains symlinks
848+
tempdir = os.path.join(TEMPDIR, "testsymlinks")
849+
temparchive = os.path.join(TEMPDIR, "testsymlinks.tar")
850+
os.mkdir(tempdir)
851+
try:
852+
source_file = os.path.join(tempdir,'source')
853+
target_file = os.path.join(tempdir,'symlink')
854+
with open(source_file,'w') as f:
855+
f.write('something\n')
856+
os.symlink(source_file, target_file)
857+
tar = tarfile.open(temparchive,'w')
858+
tar.add(source_file, arcname=os.path.basename(source_file))
859+
tar.add(target_file, arcname=os.path.basename(target_file))
860+
tar.close()
861+
# Let's extract it to the location which contains the symlink
862+
tar = tarfile.open(temparchive,'r')
863+
# this should not raise OSError: [Errno 17] File exists
864+
try:
865+
tar.extractall(path=tempdir)
866+
except OSError:
867+
self.fail("extractall failed with symlinked files")
868+
finally:
869+
tar.close()
870+
finally:
871+
os.unlink(temparchive)
872+
shutil.rmtree(tempdir)
846873

847874
class StreamWriteTest(WriteTestBase):
848875

Misc/NEWS

+3
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ Core and Builtins
6565
Library
6666
-------
6767

68+
- Issue #10761: Fix tarfile.extractall failure when symlinked files are
69+
present. Initial patch by Scott Leerssen.
70+
6871
- Issue #11763: don't use difflib in TestCase.assertMultiLineEqual if the
6972
strings are too long.
7073

0 commit comments

Comments
 (0)