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