File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -35,6 +35,8 @@ impl Error {
3535 pub const UNSUPPORTED : Error = internal_error ( 0 ) ;
3636 /// The platform-specific `errno` returned a non-positive value.
3737 pub const ERRNO_NOT_POSITIVE : Error = internal_error ( 1 ) ;
38+ /// Encountered an unexpected situation which should not happen in practice.
39+ pub const UNEXPECTED : Error = internal_error ( 2 ) ;
3840 /// Call to iOS [`SecRandomCopyBytes`](https://developer.apple.com/documentation/security/1399291-secrandomcopybytes) failed.
3941 pub const IOS_SEC_RANDOM : Error = internal_error ( 3 ) ;
4042 /// Call to Windows [`RtlGenRandom`](https://docs.microsoft.com/en-us/windows/win32/api/ntsecapi/nf-ntsecapi-rtlgenrandom) failed.
Original file line number Diff line number Diff line change 11use crate :: Error ;
2- use core:: { cmp :: min , mem:: MaybeUninit , num:: NonZeroU32 } ;
2+ use core:: { convert :: TryInto , mem:: MaybeUninit , num:: NonZeroU32 } ;
33
44extern "C" {
55 fn sys_read_entropy ( buffer : * mut u8 , length : usize , flags : u32 ) -> isize ;
@@ -8,14 +8,19 @@ extern "C" {
88pub fn getrandom_inner ( mut dest : & mut [ MaybeUninit < u8 > ] ) -> Result < ( ) , Error > {
99 while !dest. is_empty ( ) {
1010 let res = unsafe { sys_read_entropy ( dest. as_mut_ptr ( ) as * mut u8 , dest. len ( ) , 0 ) } ;
11- if res < 0 {
12- // SAFETY: all Hermit error codes use i32 under the hood:
13- // https://github.com/hermitcore/libhermit-rs/blob/master/src/errno.rs
14- let code = unsafe { NonZeroU32 :: new_unchecked ( ( -res) as u32 ) } ;
15- return Err ( code. into ( ) ) ;
11+ if res > 0 {
12+ dest = dest. get_mut ( res as usize ..) . ok_or ( Error :: UNEXPECTED ) ?;
13+ } else {
14+ // We should not get `res` equal to zero or smaller than `-i32::MAX`.
15+ // If we get such unexpected value after all, we will return `Error::UNEXPECTED`.
16+ let err = res
17+ . checked_neg ( )
18+ . and_then ( |val| val. try_into ( ) . ok ( ) )
19+ . and_then ( NonZeroU32 :: new)
20+ . map ( Into :: into)
21+ . unwrap_or ( Error :: UNEXPECTED ) ;
22+ return Err ( err) ;
1623 }
17- let len = min ( res as usize , dest. len ( ) ) ;
18- dest = & mut dest[ len..] ;
1924 }
2025 Ok ( ( ) )
2126}
Original file line number Diff line number Diff line change 88#![ allow( dead_code) ]
99use crate :: Error ;
1010use core:: {
11- cmp:: min,
1211 mem:: MaybeUninit ,
1312 num:: NonZeroU32 ,
1413 ptr:: NonNull ,
@@ -70,17 +69,19 @@ pub fn sys_fill_exact(
7069) -> Result < ( ) , Error > {
7170 while !buf. is_empty ( ) {
7271 let res = sys_fill ( buf) ;
73- if res < 0 {
74- let err = last_os_error ( ) ;
75- // We should try again if the call was interrupted.
76- if err. raw_os_error ( ) != Some ( libc:: EINTR ) {
77- return Err ( err) ;
72+ match res {
73+ res if res > 0 => buf = buf. get_mut ( res as usize ..) . ok_or ( Error :: UNEXPECTED ) ?,
74+ -1 => {
75+ let err = last_os_error ( ) ;
76+ // We should try again if the call was interrupted.
77+ if err. raw_os_error ( ) != Some ( libc:: EINTR ) {
78+ return Err ( err) ;
79+ }
7880 }
79- } else {
80- // We don't check for EOF (ret = 0) as the data we are reading
81+ // Negative return codes not equal to -1 should be impossible.
82+ // EOF (ret = 0) should be impossible, as the data we are reading
8183 // should be an infinite stream of random bytes.
82- let len = min ( res as usize , buf. len ( ) ) ;
83- buf = & mut buf[ len..] ;
84+ _ => return Err ( Error :: UNEXPECTED ) ,
8485 }
8586 }
8687 Ok ( ( ) )
You can’t perform that action at this time.
0 commit comments