From 00105b2bf542695ddeff2c2875353ab7cf1728af Mon Sep 17 00:00:00 2001 From: Brian Smith Date: Fri, 31 May 2024 15:45:54 -0700 Subject: [PATCH 1/7] error: Replace another `as` with use of `TryFrom`. --- src/error.rs | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/error.rs b/src/error.rs index 5eff99eb..b52ca530 100644 --- a/src/error.rs +++ b/src/error.rs @@ -94,18 +94,16 @@ impl Error { /// [1]: https://doc.rust-lang.org/std/io/struct.Error.html#method.raw_os_error #[inline] pub fn raw_os_error(self) -> Option { - if self.0.get() < Self::INTERNAL_START { - match () { - #[cfg(target_os = "solid_asp3")] + const _: () = assert!(i32::MAX.unsigned_abs() == Error::INTERNAL_START - 1); + i32::try_from(self.0.get()).ok().map(|errno| { + if cfg!(target_os = "solid_asp3") { // On SOLID, negate the error code again to obtain the original // error code. - () => Some(-(self.0.get() as i32)), - #[cfg(not(target_os = "solid_asp3"))] - () => Some(self.0.get() as i32), + -errno + } else { + errno } - } else { - None - } + }) } /// Extract the bare error code. From f0752e5425bd80b2003f09c11f1335647cfe827f Mon Sep 17 00:00:00 2001 From: Brian Smith Date: Fri, 31 May 2024 15:49:28 -0700 Subject: [PATCH 2/7] util_libc: Avoid `as` conversion in ssize_t-to-usize conversions. --- src/util_libc.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/util_libc.rs b/src/util_libc.rs index 7708bfcc..1ff5068b 100644 --- a/src/util_libc.rs +++ b/src/util_libc.rs @@ -55,9 +55,9 @@ pub fn sys_fill_exact( ) -> Result<(), Error> { while !buf.is_empty() { let res = sys_fill(buf); - match res { - res if res > 0 => buf = buf.get_mut(res as usize..).ok_or(Error::UNEXPECTED)?, - -1 => { + match usize::try_from(res) { + Ok(res) if res > 0 => buf = buf.get_mut(res..).ok_or(Error::UNEXPECTED)?, + Err(_) if res == -1 => { let err = last_os_error(); // We should try again if the call was interrupted. if err.raw_os_error() != Some(libc::EINTR) { From 782223d04e842282b561f700019fb5b573fd0b4d Mon Sep 17 00:00:00 2001 From: Brian Smith Date: Sun, 2 Jun 2024 11:30:26 -0700 Subject: [PATCH 3/7] util_libc: Clarify that conversion of syscall result is lossless. --- src/linux_android.rs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/linux_android.rs b/src/linux_android.rs index 7c1fede4..9bd3696d 100644 --- a/src/linux_android.rs +++ b/src/linux_android.rs @@ -8,12 +8,20 @@ pub fn getrandom_inner(dest: &mut [MaybeUninit]) -> Result<(), Error> { // Also used by linux_android_with_fallback to check if the syscall is available. pub fn getrandom_syscall(buf: &mut [MaybeUninit]) -> libc::ssize_t { - unsafe { + let res: libc::c_long = unsafe { libc::syscall( libc::SYS_getrandom, buf.as_mut_ptr().cast::(), buf.len(), 0, - ) as libc::ssize_t - } + ) + }; + + // c_long to ssize_t conversion is lossless. + const _: () = + assert!(core::mem::size_of::() == core::mem::size_of::()); + #[allow(clippy::cast_possible_truncation)] + let res = res as libc::ssize_t; + + res } From 9f7ed673056ac474921cd98c15ed85214ea8e66e Mon Sep 17 00:00:00 2001 From: Brian Smith Date: Sat, 1 Jun 2024 12:15:27 -0700 Subject: [PATCH 4/7] wasm32/js: Clarify truncating conversions. usize and u32 both implement `From` so use u16 for the length. --- src/js.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/js.rs b/src/js.rs index bec31ee5..92e198aa 100644 --- a/src/js.rs +++ b/src/js.rs @@ -9,7 +9,7 @@ use wasm_bindgen::{prelude::wasm_bindgen, JsCast, JsValue}; // Size of our temporary Uint8Array buffer used with WebCrypto methods // Maximum is 65536 bytes see https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues -const WEB_CRYPTO_BUFFER_SIZE: usize = 256; +const WEB_CRYPTO_BUFFER_SIZE: u16 = 256; // Node.js's crypto.randomFillSync requires the size to be less than 2**31. const NODE_MAX_BUFFER_SIZE: usize = (1 << 31) - 1; @@ -50,9 +50,10 @@ pub(crate) fn getrandom_inner(dest: &mut [MaybeUninit]) -> Result<(), Error> RngSource::Web(crypto, buf) => { // getRandomValues does not work with all types of WASM memory, // so we initially write to browser memory to avoid exceptions. - for chunk in dest.chunks_mut(WEB_CRYPTO_BUFFER_SIZE) { + for chunk in dest.chunks_mut(WEB_CRYPTO_BUFFER_SIZE.into()) { // The chunk can be smaller than buf's length, so we call to // JS to create a smaller view of buf without allocation. + #[allow(clippy::cast_possible_truncation)] let sub_buf = buf.subarray(0, chunk.len() as u32); if crypto.get_random_values(&sub_buf).is_err() { @@ -95,7 +96,7 @@ fn getrandom_init() -> Result { }, }; - let buf = Uint8Array::new_with_length(WEB_CRYPTO_BUFFER_SIZE as u32); + let buf = Uint8Array::new_with_length(WEB_CRYPTO_BUFFER_SIZE.into()); Ok(RngSource::Web(crypto, buf)) } From 33051f56b2c0a70341e0d8984eaedcec7253572c Mon Sep 17 00:00:00 2001 From: Brian Smith Date: Sun, 2 Jun 2024 12:09:44 -0700 Subject: [PATCH 5/7] windows7: Silence false positive truncation warning. --- src/windows7.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/windows7.rs b/src/windows7.rs index 6714f66b..3a9a1f90 100644 --- a/src/windows7.rs +++ b/src/windows7.rs @@ -27,7 +27,9 @@ pub fn getrandom_inner(dest: &mut [MaybeUninit]) -> Result<(), Error> { // Prevent overflow of u32 let chunk_size = usize::try_from(i32::MAX).expect("Windows does not support 16-bit targets"); for chunk in dest.chunks_mut(chunk_size) { - let ret = unsafe { RtlGenRandom(chunk.as_mut_ptr().cast::(), chunk.len() as u32) }; + #[allow(clippy::cast_possible_truncation)] + let chunk_len = chunk.len() as u32; + let ret = unsafe { RtlGenRandom(chunk.as_mut_ptr().cast::(), chunk_len) }; if ret != TRUE { return Err(Error::WINDOWS_RTL_GEN_RANDOM); } From f35d57875a24c7c8058463218d15c4e2ac593f71 Mon Sep 17 00:00:00 2001 From: Brian Smith Date: Thu, 20 Jun 2024 20:32:35 -0700 Subject: [PATCH 6/7] hermit: Clarify isize -> usize conversion. --- src/hermit.rs | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/hermit.rs b/src/hermit.rs index c869372a..2af13f17 100644 --- a/src/hermit.rs +++ b/src/hermit.rs @@ -9,18 +9,14 @@ extern "C" { pub fn getrandom_inner(mut dest: &mut [MaybeUninit]) -> Result<(), Error> { while !dest.is_empty() { let res = unsafe { sys_read_entropy(dest.as_mut_ptr().cast::(), dest.len(), 0) }; - // Positive `isize`s can be safely casted to `usize` - if res > 0 && (res as usize) <= dest.len() { - dest = &mut dest[res as usize..]; - } else { - let err = if res < 0 { - u32::try_from(res.unsigned_abs()) + match usize::try_from(res) { + Ok(res) if res > 0 => dest = dest.get_mut(res..).ok_or(Error::UNEXPECTED)?, + _ => { + let err = u32::try_from(res.unsigned_abs()) .ok() - .map_or(Error::UNEXPECTED, Error::from_os_error) - } else { - Error::UNEXPECTED - }; - return Err(err); + .map_or(Error::UNEXPECTED, Error::from_os_error); + return Err(err); + } } } Ok(()) From 8aa2e41b582ccf09ffaff3e8433b3bd27fc88438 Mon Sep 17 00:00:00 2001 From: Brian Smith Date: Fri, 31 May 2024 16:39:11 -0700 Subject: [PATCH 7/7] Enforce important cast-related lints. --- src/lib.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index f5e13c36..b8315174 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -208,6 +208,24 @@ #![no_std] #![warn(rust_2018_idioms, unused_lifetimes, missing_docs)] #![cfg_attr(docsrs, feature(doc_auto_cfg))] +#![deny( + clippy::cast_lossless, + clippy::cast_possible_truncation, + clippy::cast_possible_wrap, + clippy::cast_precision_loss, + clippy::cast_ptr_alignment, + clippy::cast_sign_loss, + clippy::char_lit_as_u8, + clippy::checked_conversions, + clippy::fn_to_numeric_cast, + clippy::fn_to_numeric_cast_with_truncation, + clippy::ptr_as_ptr, + clippy::unnecessary_cast, + clippy::useless_conversion +)] +// `clippy::cast_ref_to_mut` was replaced by `invalid_reference_casting` in 1.73. +#![allow(renamed_and_removed_lints)] +#![deny(clippy::cast_ref_to_mut)] #[macro_use] extern crate cfg_if;