@@ -3631,7 +3631,12 @@ impl From<User> for libc::passwd {
3631
3631
3632
3632
#[ cfg( not( target_os = "redox" ) ) ] // RedoxFS does not support passwd
3633
3633
impl User {
3634
- fn from_anything<F >( f: F ) -> Result <Option <Self >>
3634
+ /// # Safety
3635
+ ///
3636
+ /// If `f` writes to its `*mut *mut libc::passwd` parameter, then it must
3637
+ /// also initialize the value pointed to by its `*mut libc::group`
3638
+ /// parameter.
3639
+ unsafe fn from_anything<F >( f: F ) -> Result <Option <Self >>
3635
3640
where
3636
3641
F : Fn (
3637
3642
* mut libc:: passwd,
@@ -3661,7 +3666,9 @@ impl User {
3661
3666
if res. is_null( ) {
3662
3667
return Ok ( None ) ;
3663
3668
} else {
3664
- let pwd = unsafe { pwd. assume_init( ) } ;
3669
+ // SAFETY: `f` guarantees that `pwd` is initialized if `res`
3670
+ // is not null.
3671
+ let pwd = pwd. assume_init( ) ;
3665
3672
return Ok ( Some ( User :: from( & pwd) ) ) ;
3666
3673
}
3667
3674
} else if Errno :: last( ) == Errno :: ERANGE {
@@ -3687,9 +3694,13 @@ impl User {
3687
3694
/// assert_eq!(res.name, "root");
3688
3695
/// ```
3689
3696
pub fn from_uid( uid: Uid ) -> Result <Option <Self >> {
3690
- User :: from_anything( |pwd, cbuf, cap, res| unsafe {
3691
- libc:: getpwuid_r( uid. 0 , pwd, cbuf, cap, res)
3692
- } )
3697
+ // SAFETY: `getpwuid_r` will write to `res` if it initializes the value
3698
+ // at `pwd`.
3699
+ unsafe {
3700
+ User :: from_anything( |pwd, cbuf, cap, res| {
3701
+ libc:: getpwuid_r( uid. 0 , pwd, cbuf, cap, res)
3702
+ } )
3703
+ }
3693
3704
}
3694
3705
3695
3706
/// Get a user by name.
@@ -3710,9 +3721,13 @@ impl User {
3710
3721
Ok ( c_str) => c_str,
3711
3722
Err ( _nul_error) => return Ok ( None ) ,
3712
3723
} ;
3713
- User :: from_anything( |pwd, cbuf, cap, res| unsafe {
3714
- libc:: getpwnam_r( name. as_ptr( ) , pwd, cbuf, cap, res)
3715
- } )
3724
+ // SAFETY: `getpwnam_r` will write to `res` if it initializes the value
3725
+ // at `pwd`.
3726
+ unsafe {
3727
+ User :: from_anything( |pwd, cbuf, cap, res| {
3728
+ libc:: getpwnam_r( name. as_ptr( ) , pwd, cbuf, cap, res)
3729
+ } )
3730
+ }
3716
3731
}
3717
3732
}
3718
3733
@@ -3763,7 +3778,12 @@ impl Group {
3763
3778
ret
3764
3779
}
3765
3780
3766
- fn from_anything<F >( f: F ) -> Result <Option <Self >>
3781
+ /// # Safety
3782
+ ///
3783
+ /// If `f` writes to its `*mut *mut libc::group` parameter, then it must
3784
+ /// also initialize the value pointed to by its `*mut libc::group`
3785
+ /// parameter.
3786
+ unsafe fn from_anything<F >( f: F ) -> Result <Option <Self >>
3767
3787
where
3768
3788
F : Fn (
3769
3789
* mut libc:: group,
@@ -3793,7 +3813,9 @@ impl Group {
3793
3813
if res. is_null( ) {
3794
3814
return Ok ( None ) ;
3795
3815
} else {
3796
- let grp = unsafe { grp. assume_init( ) } ;
3816
+ // SAFETY: `f` guarantees that `grp` is initialized if `res`
3817
+ // is not null.
3818
+ let grp = grp. assume_init( ) ;
3797
3819
return Ok ( Some ( Group :: from( & grp) ) ) ;
3798
3820
}
3799
3821
} else if Errno :: last( ) == Errno :: ERANGE {
@@ -3821,9 +3843,13 @@ impl Group {
3821
3843
/// assert!(res.name == "root");
3822
3844
/// ```
3823
3845
pub fn from_gid( gid: Gid ) -> Result <Option <Self >> {
3824
- Group :: from_anything( |grp, cbuf, cap, res| unsafe {
3825
- libc:: getgrgid_r( gid. 0 , grp, cbuf, cap, res)
3826
- } )
3846
+ // SAFETY: `getgrgid_r` will write to `res` if it initializes the value
3847
+ // at `grp`.
3848
+ unsafe {
3849
+ Group :: from_anything( |grp, cbuf, cap, res| {
3850
+ libc:: getgrgid_r( gid. 0 , grp, cbuf, cap, res)
3851
+ } )
3852
+ }
3827
3853
}
3828
3854
3829
3855
/// Get a group by name.
@@ -3846,9 +3872,13 @@ impl Group {
3846
3872
Ok ( c_str) => c_str,
3847
3873
Err ( _nul_error) => return Ok ( None ) ,
3848
3874
} ;
3849
- Group :: from_anything( |grp, cbuf, cap, res| unsafe {
3850
- libc:: getgrnam_r( name. as_ptr( ) , grp, cbuf, cap, res)
3851
- } )
3875
+ // SAFETY: `getgrnam_r` will write to `res` if it initializes the value
3876
+ // at `grp`.
3877
+ unsafe {
3878
+ Group :: from_anything( |grp, cbuf, cap, res| {
3879
+ libc:: getgrnam_r( name. as_ptr( ) , grp, cbuf, cap, res)
3880
+ } )
3881
+ }
3852
3882
}
3853
3883
}
3854
3884
}
0 commit comments