diff --git a/Lib/tarfile.py b/Lib/tarfile.py --- a/Lib/tarfile.py +++ b/Lib/tarfile.py @@ -55,13 +55,7 @@ grp = pwd = None # os.symlink on Windows prior to 6.0 raises NotImplementedError -symlink_exception = (AttributeError, NotImplementedError) -try: - # OSError (winerror=1314) will be raised if the caller does not hold the - # SeCreateSymbolicLinkPrivilege privilege - symlink_exception += (OSError,) -except NameError: - pass +symlink_exception = (AttributeError, NotImplementedError, OSError) # from tarfile import * __all__ = ["TarFile", "TarInfo", "is_tarfile", "TarError", "ReadError", @@ -2205,7 +2199,12 @@ else: self._extract_member(self._find_link_target(tarinfo), targetpath) - except symlink_exception: + except symlink_exception as e: + # On Windows, OSError (winerror=1314) will be raised if the caller + # does not hold the SeCreateSymbolicLinkPrivilege privilege. + if getattr(e, "winerror", None) is None: + raise + try: self._extract_member(self._find_link_target(tarinfo), targetpath) diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py --- a/Lib/test/test_tarfile.py +++ b/Lib/test/test_tarfile.py @@ -525,12 +525,21 @@ data = f.read() self.assertEqual(md5sum(data), md5_regtype) + @support.skip_unless_symlink + def test_extract_symlink(self): + # Test symlink extraction (e.g. bug #23228). + with tarfile.open(tarname, errorlevel=1, encoding="iso8859-1") as tar: + tar.extract("ustar/regtype", TEMPDIR) + self.addCleanup(support.unlink, os.path.join(TEMPDIR, "ustar/regtype")) + tar.extract("ustar/symtype", TEMPDIR) self.addCleanup(support.unlink, os.path.join(TEMPDIR, "ustar/symtype")) with open(os.path.join(TEMPDIR, "ustar/symtype"), "rb") as f: data = f.read() self.assertEqual(md5sum(data), md5_regtype) + self.assertRaises(FileExistsError, tar.extract, "ustar/symtype", TEMPDIR) + def test_extractall(self): # Test if extractall() correctly restores directory permissions # and times (see issue1735).