@@ -841,6 +841,57 @@ def test_next_on_empty_tarfile(self):
841
841
with tarfile .open (fileobj = fd , mode = "r" ) as tf :
842
842
self .assertEqual (tf .next (), None )
843
843
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
+
844
895
class MiscReadTest (MiscReadTestBase , unittest .TestCase ):
845
896
test_fail_comp = None
846
897
0 commit comments