Skip to content

Commit

Permalink
Remove impl From<NonZeroU32> for Error and Error::code (#507)
Browse files Browse the repository at this point in the history
Also adds `Error::{new_custom, new_internal}` methods and changes return
type of `__getrandom_custom` to `Result<(), getrandom::Error>`.
  • Loading branch information
newpavlov authored Oct 9, 2024
1 parent 0f787bc commit 387248f
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 46 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Breaking Changes
- Update MSRV to 1.60 [#472]
- Remove support of the `wasm32-wasi` target (use `wasm32-wasip1` or `wasm32-wasip2` instead) [#499]
- Remove `impl From<NonZeroU32> for Error` and `Error::code` method [#507]

### Changed
- Switch to `futex` on Linux and to `nanosleep`-based wait loop on other targets
in the `use_file` backend [#490]

### Added
- `wasm32-wasip1` and `wasm32-wasip2` support [#499]
- `Error::new_custom` method [#507]

[#472]: https://github.com/rust-random/getrandom/pull/472
[#490]: https://github.com/rust-random/getrandom/pull/490
[#499]: https://github.com/rust-random/getrandom/pull/499
[#507]: https://github.com/rust-random/getrandom/pull/507

## [0.2.15] - 2024-05-06
### Added
Expand Down
10 changes: 3 additions & 7 deletions src/custom.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
//! An implementation which calls out to an externally defined function.
use crate::Error;
use core::{mem::MaybeUninit, num::NonZeroU32};
use core::mem::MaybeUninit;

pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
extern "Rust" {
fn __getrandom_custom(dest: *mut u8, len: usize) -> u32;
}
let ret = unsafe { __getrandom_custom(dest.as_mut_ptr().cast(), dest.len()) };
match NonZeroU32::new(ret) {
None => Ok(()),
Some(code) => Err(Error::from(code)),
fn __getrandom_custom(dest: *mut u8, len: usize) -> Result<(), Error>;
}
unsafe { __getrandom_custom(dest.as_mut_ptr().cast(), dest.len()) }
}
59 changes: 26 additions & 33 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,44 +20,38 @@ use core::{fmt, num::NonZeroU32};
#[derive(Copy, Clone, Eq, PartialEq)]
pub struct Error(NonZeroU32);

const fn internal_error(n: u16) -> Error {
// SAFETY: code > 0 as INTERNAL_START > 0 and adding n won't overflow a u32.
let code = Error::INTERNAL_START + (n as u32);
Error(unsafe { NonZeroU32::new_unchecked(code) })
}

impl Error {
/// This target/platform is not supported by `getrandom`.
pub const UNSUPPORTED: Error = internal_error(0);
pub const UNSUPPORTED: Error = Self::new_internal(0);
/// The platform-specific `errno` returned a non-positive value.
pub const ERRNO_NOT_POSITIVE: Error = internal_error(1);
pub const ERRNO_NOT_POSITIVE: Error = Self::new_internal(1);
/// Encountered an unexpected situation which should not happen in practice.
pub const UNEXPECTED: Error = internal_error(2);
pub const UNEXPECTED: Error = Self::new_internal(2);
/// Call to [`CCRandomGenerateBytes`](https://opensource.apple.com/source/CommonCrypto/CommonCrypto-60074/include/CommonRandom.h.auto.html) failed
/// on iOS, tvOS, or waatchOS.
// TODO: Update this constant name in the next breaking release.
pub const IOS_SEC_RANDOM: Error = internal_error(3);
pub const IOS_SEC_RANDOM: Error = Self::new_internal(3);
/// Call to Windows [`RtlGenRandom`](https://docs.microsoft.com/en-us/windows/win32/api/ntsecapi/nf-ntsecapi-rtlgenrandom) failed.
pub const WINDOWS_RTL_GEN_RANDOM: Error = internal_error(4);
pub const WINDOWS_RTL_GEN_RANDOM: Error = Self::new_internal(4);
/// RDRAND instruction failed due to a hardware issue.
pub const FAILED_RDRAND: Error = internal_error(5);
pub const FAILED_RDRAND: Error = Self::new_internal(5);
/// RDRAND instruction unsupported on this target.
pub const NO_RDRAND: Error = internal_error(6);
pub const NO_RDRAND: Error = Self::new_internal(6);
/// The environment does not support the Web Crypto API.
pub const WEB_CRYPTO: Error = internal_error(7);
pub const WEB_CRYPTO: Error = Self::new_internal(7);
/// Calling Web Crypto API `crypto.getRandomValues` failed.
pub const WEB_GET_RANDOM_VALUES: Error = internal_error(8);
pub const WEB_GET_RANDOM_VALUES: Error = Self::new_internal(8);
/// On VxWorks, call to `randSecure` failed (random number generator is not yet initialized).
pub const VXWORKS_RAND_SECURE: Error = internal_error(11);
pub const VXWORKS_RAND_SECURE: Error = Self::new_internal(11);
/// Node.js does not have the `crypto` CommonJS module.
pub const NODE_CRYPTO: Error = internal_error(12);
pub const NODE_CRYPTO: Error = Self::new_internal(12);
/// Calling Node.js function `crypto.randomFillSync` failed.
pub const NODE_RANDOM_FILL_SYNC: Error = internal_error(13);
pub const NODE_RANDOM_FILL_SYNC: Error = Self::new_internal(13);
/// Called from an ES module on Node.js. This is unsupported, see:
/// <https://docs.rs/getrandom#nodejs-es-module-support>.
pub const NODE_ES_MODULE: Error = internal_error(14);
pub const NODE_ES_MODULE: Error = Self::new_internal(14);
/// Calling Windows ProcessPrng failed.
pub const WINDOWS_PROCESS_PRNG: Error = internal_error(15);
pub const WINDOWS_PROCESS_PRNG: Error = Self::new_internal(15);

/// Codes below this point represent OS Errors (i.e. positive i32 values).
/// Codes at or above this point, but below [`Error::CUSTOM_START`] are
Expand Down Expand Up @@ -108,13 +102,18 @@ impl Error {
}
}

/// Extract the bare error code.
///
/// This code can either come from the underlying OS, or be a custom error.
/// Use [`Error::raw_os_error()`] to disambiguate.
#[inline]
pub const fn code(self) -> NonZeroU32 {
self.0
/// Creates a new instance of an `Error` from a particular custom error code.
pub const fn new_custom(n: u16) -> Error {
// SAFETY: code > 0 as CUSTOM_START > 0 and adding n won't overflow a u32.
let code = Error::CUSTOM_START + (n as u32);
Error(unsafe { NonZeroU32::new_unchecked(code) })
}

/// Creates a new instance of an `Error` from a particular internal error code.
const fn new_internal(n: u16) -> Error {
// SAFETY: code > 0 as INTERNAL_START > 0 and adding n won't overflow a u32.
let code = Error::INTERNAL_START + (n as u32);
Error(unsafe { NonZeroU32::new_unchecked(code) })
}
}

Expand Down Expand Up @@ -153,12 +152,6 @@ impl fmt::Display for Error {
}
}

impl From<NonZeroU32> for Error {
fn from(code: NonZeroU32) -> Self {
Self(code)
}
}

fn internal_desc(error: Error) -> Option<&'static str> {
match error {
Error::UNSUPPORTED => Some("getrandom: this target is not supported"),
Expand Down
10 changes: 7 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,10 @@
//! signature:
//!
//! ```
//! use getrandom::Error;
//!
//! #[no_mangle]
//! unsafe fn __getrandom_custom(dest: *mut u8, len: usize) -> u32 {
//! unsafe extern "Rust" fn __getrandom_custom(dest: *mut u8, len: usize) -> Result<(), Error> {
//! todo!()
//! }
//! ```
Expand All @@ -126,9 +128,11 @@
//! it gets pulled nevertheless by one of your dependencies, then you can
//! use the following custom backend which always returns "unsupported" error:
//! ```
//! use getrandom::Error;
//!
//! #[no_mangle]
//! unsafe fn __getrandom_custom(dest: *mut u8, len: usize) -> u32 {
//! getrandom::Error::UNSUPPORTED.code().get()
//! unsafe extern "Rust" fn __getrandom_custom(dest: *mut u8, len: usize) -> Result<(), Error> {
//! Err(Error::UNSUPPORTED)
//! }
//! ```
//!
Expand Down
8 changes: 5 additions & 3 deletions tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,8 @@ fn test_multithreading() {

#[cfg(getrandom_backend = "custom")]
mod custom {
use getrandom::Error;

struct Xoshiro128PlusPlus {
s: [u32; 4],
}
Expand Down Expand Up @@ -204,13 +206,13 @@ mod custom {
//
// WARNING: this custom implementation is for testing purposes ONLY!
#[no_mangle]
unsafe fn __getrandom_custom(dest: *mut u8, len: usize) -> u32 {
unsafe extern "Rust" fn __getrandom_custom(dest: *mut u8, len: usize) -> Result<(), Error> {
use std::time::{SystemTime, UNIX_EPOCH};

assert_ne!(len, 0);

if len == 142 {
return getrandom::Error::CUSTOM_START + 142;
return Err(Error::new_custom(142));
}

let dest_u32 = dest.cast::<u32>();
Expand All @@ -227,7 +229,7 @@ mod custom {
core::ptr::write_unaligned(dest.add(i), val as u8);
}
}
0
Ok(())
}

// Test that enabling the custom feature indeed uses the custom implementation
Expand Down

0 comments on commit 387248f

Please sign in to comment.