1
+ import errno
1
2
import sys
2
3
import os
3
4
import io
@@ -3651,34 +3652,55 @@ def test_modes(self):
3651
3652
arc .add ('read_group_only' , mode = '?---r-----' )
3652
3653
arc .add ('no_bits' , mode = '?---------' )
3653
3654
arc .add ('dir/' , mode = '?---rwsrwt' )
3655
+ arc .add ('dir_all_bits/' , mode = '?rwsrwsrwt' )
3654
3656
3655
- # On some systems, setting the sticky bit is a no-op.
3656
- # Check if that's the case.
3657
+ # On some systems, setting the uid, gid, and/or sticky bit is a no-ops.
3658
+ # Check which bits we can set, so we can compare tarfile machinery to
3659
+ # a simple chmod.
3657
3660
tmp_filename = os .path .join (TEMPDIR , "tmp.file" )
3658
3661
with open (tmp_filename , 'w' ):
3659
3662
pass
3660
- os .chmod (tmp_filename , os .stat (tmp_filename ).st_mode | stat .S_ISVTX )
3661
- have_sticky_files = (os .stat (tmp_filename ).st_mode & stat .S_ISVTX )
3662
- os .unlink (tmp_filename )
3663
+ try :
3664
+ new_mode = (os .stat (tmp_filename ).st_mode
3665
+ | stat .S_ISVTX | stat .S_ISGID | stat .S_ISUID )
3666
+ try :
3667
+ os .chmod (tmp_filename , new_mode )
3668
+ except OSError as exc :
3669
+ if exc .errno == getattr (errno , "EFTYPE" , 0 ):
3670
+ # gh-108948: On FreeBSD, regular users cannot set
3671
+ # the sticky bit.
3672
+ self .skipTest ("chmod() failed with EFTYPE: "
3673
+ "regular users cannot set sticky bit" )
3674
+ else :
3675
+ raise
3676
+
3677
+ got_mode = os .stat (tmp_filename ).st_mode
3678
+ _t_file = 't' if (got_mode & stat .S_ISVTX ) else 'x'
3679
+ _suid_file = 's' if (got_mode & stat .S_ISUID ) else 'x'
3680
+ _sgid_file = 's' if (got_mode & stat .S_ISGID ) else 'x'
3681
+ finally :
3682
+ os .unlink (tmp_filename )
3663
3683
3664
3684
os .mkdir (tmp_filename )
3665
- os .chmod (tmp_filename , os .stat (tmp_filename ).st_mode | stat .S_ISVTX )
3666
- have_sticky_dirs = (os .stat (tmp_filename ).st_mode & stat .S_ISVTX )
3685
+ new_mode = (os .stat (tmp_filename ).st_mode
3686
+ | stat .S_ISVTX | stat .S_ISGID | stat .S_ISUID )
3687
+ os .chmod (tmp_filename , new_mode )
3688
+ got_mode = os .stat (tmp_filename ).st_mode
3689
+ _t_dir = 't' if (got_mode & stat .S_ISVTX ) else 'x'
3690
+ _suid_dir = 's' if (got_mode & stat .S_ISUID ) else 'x'
3691
+ _sgid_dir = 's' if (got_mode & stat .S_ISGID ) else 'x'
3667
3692
os .rmdir (tmp_filename )
3668
3693
3669
3694
with self .check_context (arc .open (), 'fully_trusted' ):
3670
- if have_sticky_files :
3671
- self .expect_file ('all_bits' , mode = '?rwsrwsrwt' )
3672
- else :
3673
- self .expect_file ('all_bits' , mode = '?rwsrwsrwx' )
3695
+ self .expect_file ('all_bits' ,
3696
+ mode = f'?rw{ _suid_file } rw{ _sgid_file } rw{ _t_file } ' )
3674
3697
self .expect_file ('perm_bits' , mode = '?rwxrwxrwx' )
3675
3698
self .expect_file ('exec_group_other' , mode = '?rw-rwxrwx' )
3676
3699
self .expect_file ('read_group_only' , mode = '?---r-----' )
3677
3700
self .expect_file ('no_bits' , mode = '?---------' )
3678
- if have_sticky_dirs :
3679
- self .expect_file ('dir/' , mode = '?---rwsrwt' )
3680
- else :
3681
- self .expect_file ('dir/' , mode = '?---rwsrwx' )
3701
+ self .expect_file ('dir/' , mode = f'?---rw{ _sgid_dir } rw{ _t_dir } ' )
3702
+ self .expect_file ('dir_all_bits/' ,
3703
+ mode = f'?rw{ _suid_dir } rw{ _sgid_dir } rw{ _t_dir } ' )
3682
3704
3683
3705
with self .check_context (arc .open (), 'tar' ):
3684
3706
self .expect_file ('all_bits' , mode = '?rwxr-xr-x' )
@@ -3687,6 +3709,7 @@ def test_modes(self):
3687
3709
self .expect_file ('read_group_only' , mode = '?---r-----' )
3688
3710
self .expect_file ('no_bits' , mode = '?---------' )
3689
3711
self .expect_file ('dir/' , mode = '?---r-xr-x' )
3712
+ self .expect_file ('dir_all_bits/' , mode = '?rwxr-xr-x' )
3690
3713
3691
3714
with self .check_context (arc .open (), 'data' ):
3692
3715
normal_dir_mode = stat .filemode (stat .S_IMODE (
@@ -3697,6 +3720,7 @@ def test_modes(self):
3697
3720
self .expect_file ('read_group_only' , mode = '?rw-r-----' )
3698
3721
self .expect_file ('no_bits' , mode = '?rw-------' )
3699
3722
self .expect_file ('dir/' , mode = normal_dir_mode )
3723
+ self .expect_file ('dir_all_bits/' , mode = normal_dir_mode )
3700
3724
3701
3725
def test_pipe (self ):
3702
3726
# Test handling of a special file
0 commit comments