@@ -1679,6 +1679,33 @@ def test_missing_fileobj(self):
16791679            with  self .assertRaises (ValueError ):
16801680                tar .addfile (tarinfo )
16811681
1682+     @unittest .skipUnless (os_helper .can_symlink (), 'requires symlink support' ) 
1683+     @unittest .mock .patch ('os.chown' ) 
1684+     @unittest .mock .patch ('os.utime' ) 
1685+     @unittest .mock .patch ('os.chmod' ) 
1686+     def  test_deferred_directory_attributes_update (self , mock_chmod , mock_utime , mock_chown ):
1687+         # Regression test for gh-127987: setting attributes on arbitrary files 
1688+         tempdir  =  os .path .join (TEMPDIR , 'test127987' )
1689+         def  mock_chmod_side_effect (path , mode , ** kwargs ):
1690+             target_path  =  os .path .realpath (path )
1691+             if  os .path .commonpath ([target_path , tempdir ]) !=  tempdir :
1692+                 raise  Exception ("should not try to chmod anything outside the destination" , target_path )
1693+         mock_chmod .side_effect  =  mock_chmod_side_effect 
1694+ 
1695+         outside_tree_dir  =  os .path .join (TEMPDIR , 'outside_tree_dir' )
1696+         with  ArchiveMaker () as  arc :
1697+             arc .add ('x' , symlink_to = '.' )
1698+             arc .add ('x' , type = tarfile .DIRTYPE , mode = '?rwsrwsrwt' )
1699+             arc .add ('x' , symlink_to = ('y/'  *  99  +  '../'  *  99  +  outside_tree_dir ))
1700+             arc .add ('y/'  *  99 , symlink_to = ('../'  *  98 ))
1701+ 
1702+         os .makedirs (outside_tree_dir )
1703+         try :
1704+             arc .open ().extractall (path = tempdir , filter = 'tar' )
1705+         finally :
1706+             os_helper .rmtree (outside_tree_dir )
1707+             os_helper .rmtree (tempdir )
1708+ 
16821709
16831710class  GzipWriteTest (GzipTest , WriteTest ):
16841711    pass 
0 commit comments