diff -r 4a55b98314cd Lib/tarfile.py --- a/Lib/tarfile.py Mon Jan 12 21:03:41 2015 +0100 +++ b/Lib/tarfile.py Tue Jan 13 10:10:42 2015 +0100 @@ -2177,6 +2177,10 @@ try: # For systems that support symbolic and hard links. if tarinfo.issym(): + # a symlink with that name exists already, we need to replace + # it with our version (see #23228) + if os.path.lexists(targetpath): + os.remove(targetpath) os.symlink(tarinfo.linkname, targetpath) else: # See extract(). diff -r 4a55b98314cd Lib/test/test_tarfile.py --- a/Lib/test/test_tarfile.py Mon Jan 12 21:03:41 2015 +0100 +++ b/Lib/test/test_tarfile.py Tue Jan 13 10:10:42 2015 +0100 @@ -5,6 +5,7 @@ import unittest import tarfile +import tempfile from test import support, script_helper @@ -2167,6 +2168,31 @@ self._test_partial_input("r:bz2") +@unittest.skipIf(hasattr(os, "link"), "requires os.link to be missing") +class TestTarfileLinkExtract(unittest.TestCase): + """Regression test for #23228""" + + def setUp(self): + self.tempdir = tempfile.mkdtemp() + self.cwd = os.getcwd() + os.chdir(self.tempdir) + + def tearDown(self): + os.chdir(self.cwd) + support.rmtree(self.tempdir) + + def test_tarfile_crash(self): + os.mkdir("run") + os.mkdir("var") + os.symlink("run", "var/run") + tarname = "lala.tar" + with tarfile.open(tarname, "w") as w: + w.add("run") + w.add("var") + with tarfile.open(tarname, "r") as r: + r.extractall(".") + + def setUpModule(): support.unlink(TEMPDIR) os.makedirs(TEMPDIR)