1
+ import errno
1
2
import sys
2
3
import os
3
4
import io
@@ -3691,34 +3692,55 @@ def test_modes(self):
3691
3692
arc .add ('read_group_only' , mode = '?---r-----' )
3692
3693
arc .add ('no_bits' , mode = '?---------' )
3693
3694
arc .add ('dir/' , mode = '?---rwsrwt' )
3695
+ arc .add ('dir_all_bits/' , mode = '?rwsrwsrwt' )
3694
3696
3695
- # On some systems, setting the sticky bit is a no-op.
3696
- # Check if that's the case.
3697
+ # On some systems, setting the uid, gid, and/or sticky bit is a no-ops.
3698
+ # Check which bits we can set, so we can compare tarfile machinery to
3699
+ # a simple chmod.
3697
3700
tmp_filename = os .path .join (TEMPDIR , "tmp.file" )
3698
3701
with open (tmp_filename , 'w' ):
3699
3702
pass
3700
- os .chmod (tmp_filename , os .stat (tmp_filename ).st_mode | stat .S_ISVTX )
3701
- have_sticky_files = (os .stat (tmp_filename ).st_mode & stat .S_ISVTX )
3702
- os .unlink (tmp_filename )
3703
+ try :
3704
+ new_mode = (os .stat (tmp_filename ).st_mode
3705
+ | stat .S_ISVTX | stat .S_ISGID | stat .S_ISUID )
3706
+ try :
3707
+ os .chmod (tmp_filename , new_mode )
3708
+ except OSError as exc :
3709
+ if exc .errno == getattr (errno , "EFTYPE" , 0 ):
3710
+ # gh-108948: On FreeBSD, regular users cannot set
3711
+ # the sticky bit.
3712
+ self .skipTest ("chmod() failed with EFTYPE: "
3713
+ "regular users cannot set sticky bit" )
3714
+ else :
3715
+ raise
3716
+
3717
+ got_mode = os .stat (tmp_filename ).st_mode
3718
+ _t_file = 't' if (got_mode & stat .S_ISVTX ) else 'x'
3719
+ _suid_file = 's' if (got_mode & stat .S_ISUID ) else 'x'
3720
+ _sgid_file = 's' if (got_mode & stat .S_ISGID ) else 'x'
3721
+ finally :
3722
+ os .unlink (tmp_filename )
3703
3723
3704
3724
os .mkdir (tmp_filename )
3705
- os .chmod (tmp_filename , os .stat (tmp_filename ).st_mode | stat .S_ISVTX )
3706
- have_sticky_dirs = (os .stat (tmp_filename ).st_mode & stat .S_ISVTX )
3725
+ new_mode = (os .stat (tmp_filename ).st_mode
3726
+ | stat .S_ISVTX | stat .S_ISGID | stat .S_ISUID )
3727
+ os .chmod (tmp_filename , new_mode )
3728
+ got_mode = os .stat (tmp_filename ).st_mode
3729
+ _t_dir = 't' if (got_mode & stat .S_ISVTX ) else 'x'
3730
+ _suid_dir = 's' if (got_mode & stat .S_ISUID ) else 'x'
3731
+ _sgid_dir = 's' if (got_mode & stat .S_ISGID ) else 'x'
3707
3732
os .rmdir (tmp_filename )
3708
3733
3709
3734
with self .check_context (arc .open (), 'fully_trusted' ):
3710
- if have_sticky_files :
3711
- self .expect_file ('all_bits' , mode = '?rwsrwsrwt' )
3712
- else :
3713
- self .expect_file ('all_bits' , mode = '?rwsrwsrwx' )
3735
+ self .expect_file ('all_bits' ,
3736
+ mode = f'?rw{ _suid_file } rw{ _sgid_file } rw{ _t_file } ' )
3714
3737
self .expect_file ('perm_bits' , mode = '?rwxrwxrwx' )
3715
3738
self .expect_file ('exec_group_other' , mode = '?rw-rwxrwx' )
3716
3739
self .expect_file ('read_group_only' , mode = '?---r-----' )
3717
3740
self .expect_file ('no_bits' , mode = '?---------' )
3718
- if have_sticky_dirs :
3719
- self .expect_file ('dir/' , mode = '?---rwsrwt' )
3720
- else :
3721
- self .expect_file ('dir/' , mode = '?---rwsrwx' )
3741
+ self .expect_file ('dir/' , mode = f'?---rw{ _sgid_dir } rw{ _t_dir } ' )
3742
+ self .expect_file ('dir_all_bits/' ,
3743
+ mode = f'?rw{ _suid_dir } rw{ _sgid_dir } rw{ _t_dir } ' )
3722
3744
3723
3745
with self .check_context (arc .open (), 'tar' ):
3724
3746
self .expect_file ('all_bits' , mode = '?rwxr-xr-x' )
@@ -3727,6 +3749,7 @@ def test_modes(self):
3727
3749
self .expect_file ('read_group_only' , mode = '?---r-----' )
3728
3750
self .expect_file ('no_bits' , mode = '?---------' )
3729
3751
self .expect_file ('dir/' , mode = '?---r-xr-x' )
3752
+ self .expect_file ('dir_all_bits/' , mode = '?rwxr-xr-x' )
3730
3753
3731
3754
with self .check_context (arc .open (), 'data' ):
3732
3755
normal_dir_mode = stat .filemode (stat .S_IMODE (
@@ -3737,6 +3760,7 @@ def test_modes(self):
3737
3760
self .expect_file ('read_group_only' , mode = '?rw-r-----' )
3738
3761
self .expect_file ('no_bits' , mode = '?rw-------' )
3739
3762
self .expect_file ('dir/' , mode = normal_dir_mode )
3763
+ self .expect_file ('dir_all_bits/' , mode = normal_dir_mode )
3740
3764
3741
3765
def test_pipe (self ):
3742
3766
# Test handling of a special file
0 commit comments