@@ -833,6 +833,57 @@ def test_next_on_empty_tarfile(self):
833833 with tarfile .open (fileobj = fd , mode = "r" ) as tf :
834834 self .assertEqual (tf .next (), None )
835835
836+ def _setup_symlink_to_target (self , temp_dirpath ):
837+ target_filepath = os .path .join (temp_dirpath , "target" )
838+ ustar_dirpath = os .path .join (temp_dirpath , "ustar" )
839+ hardlink_filepath = os .path .join (ustar_dirpath , "lnktype" )
840+ with open (target_filepath , "wb" ) as f :
841+ f .write (b"target" )
842+ os .makedirs (ustar_dirpath )
843+ os .symlink (target_filepath , hardlink_filepath )
844+ return target_filepath , hardlink_filepath
845+
846+ def _assert_on_file_content (self , filepath , digest ):
847+ with open (filepath , "rb" ) as f :
848+ data = f .read ()
849+ self .assertEqual (sha256sum (data ), digest )
850+
851+ @unittest .skipUnless (
852+ hasattr (os , "link" ), "Missing hardlink implementation"
853+ )
854+ @os_helper .skip_unless_symlink
855+ def test_extract_hardlink_on_symlink (self ):
856+ """
857+ This test verifies that extracting a hardlink will not follow an
858+ existing symlink after a FileExistsError on os.link.
859+ """
860+ with os_helper .temp_dir () as DIR :
861+ target_filepath , hardlink_filepath = self ._setup_symlink_to_target (DIR )
862+ with tarfile .open (tarname , encoding = "iso8859-1" ) as tar :
863+ tar .extract ("ustar/regtype" , DIR , filter = "data" )
864+ tar .extract ("ustar/lnktype" , DIR , filter = "data" )
865+ self ._assert_on_file_content (target_filepath , sha256sum (b"target" ))
866+ self ._assert_on_file_content (hardlink_filepath , sha256_regtype )
867+
868+ @unittest .skipUnless (
869+ hasattr (os , "link" ), "Missing hardlink implementation"
870+ )
871+ @os_helper .skip_unless_symlink
872+ def test_extractall_hardlink_on_symlink (self ):
873+ """
874+ This test verifies that extracting a hardlink will not follow an
875+ existing symlink after a FileExistsError on os.link.
876+ """
877+ with os_helper .temp_dir () as DIR :
878+ target_filepath , hardlink_filepath = self ._setup_symlink_to_target (DIR )
879+ with tarfile .open (tarname , encoding = "iso8859-1" ) as tar :
880+ tar .extractall (
881+ DIR , members = ["ustar/regtype" , "ustar/lnktype" ], filter = "data" ,
882+ )
883+ self ._assert_on_file_content (target_filepath , sha256sum (b"target" ))
884+ self ._assert_on_file_content (hardlink_filepath , sha256_regtype )
885+
886+
836887class MiscReadTest (MiscReadTestBase , unittest .TestCase ):
837888 test_fail_comp = None
838889
0 commit comments