Skip to content

Commit 8096bac

Browse files
josephlrnewpavlov
authored andcommitted
0.2: Error and Testing improvements (#120)
1 parent cf2d81b commit 8096bac

12 files changed

+79
-99
lines changed

.travis.yml

+16-26
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ matrix:
2121
- rustup target add aarch64-apple-ios
2222
script:
2323
- cargo test
24-
- cargo test --examples
2524
- cargo build --target aarch64-apple-ios
2625

2726
- name: "Linux, beta"
@@ -40,11 +39,11 @@ matrix:
4039
# Get latest geckodriver
4140
- export VERSION=$(curl -s https://api.github.com/repos/mozilla/geckodriver/releases/latest | jq -r ".tag_name")
4241
- wget -O geckodriver.tar.gz https://github.com/mozilla/geckodriver/releases/download/$VERSION/geckodriver-$VERSION-linux64.tar.gz
43-
- tar -xzf geckodriver.tar.gz
42+
- tar -xzf geckodriver.tar.gz -C $HOME
4443
# Get latest chromedirver
4544
- export VERSION=$(wget -q -O - https://chromedriver.storage.googleapis.com/LATEST_RELEASE)
4645
- wget -O chromedriver.zip https://chromedriver.storage.googleapis.com/$VERSION/chromedriver_linux64.zip
47-
- unzip chromedriver.zip
46+
- unzip chromedriver.zip -d $HOME
4847
# Get cargo-web
4948
- export VERSION=0.6.26 # Pin version for stability
5049
- wget -O cargo-web.gz https://github.com/koute/cargo-web/releases/download/$VERSION/cargo-web-x86_64-unknown-linux-gnu.gz
@@ -76,44 +75,34 @@ matrix:
7675
- cargo web test --target=wasm32-unknown-unknown --features=stdweb
7776
# wasm-bindgen tests (Node, Firefox, Chrome)
7877
- cargo test --target wasm32-unknown-unknown --features=wasm-bindgen
79-
- GECKODRIVER=$PWD/geckodriver cargo test --target wasm32-unknown-unknown --features=test-in-browser
80-
- CHROMEDRIVER=$PWD/chromedriver cargo test --target wasm32-unknown-unknown --features=test-in-browser
78+
- GECKODRIVER=$HOME/geckodriver cargo test --target wasm32-unknown-unknown --features=test-in-browser
79+
- CHROMEDRIVER=$HOME/chromedriver cargo test --target wasm32-unknown-unknown --features=test-in-browser
8180

82-
- name: "Linux, nightly, docs"
81+
- &nightly_and_docs
82+
name: "Linux, nightly, docs"
8383
rust: nightly
8484
os: linux
8585
install:
8686
- cargo --list | egrep "^\s*deadlinks$" -q || cargo install cargo-deadlinks
8787
- cargo deadlinks -V
8888
script:
89+
# Check that our tests pass in the default configuration
8990
- cargo test
9091
- cargo test --benches
91-
- cargo test --examples
92+
# Check that setting various features does not break the build
93+
- cargo build --features=std
94+
- cargo build --features=log
9295
# remove cached documentation, otherwise files from previous PRs can get included
9396
- rm -rf target/doc
94-
- cargo doc --no-deps --all --features=std,log
97+
- cargo doc --no-deps --features=std
9598
- cargo deadlinks --dir target/doc
9699
# also test minimum dependency versions are usable
97100
- cargo generate-lockfile -Z minimal-versions
98-
- cargo test
101+
- cargo test --features=std,log
99102

100-
- name: "OSX, nightly, docs"
101-
rust: nightly
103+
- <<: *nightly_and_docs
104+
name: "OSX, nightly, docs"
102105
os: osx
103-
install:
104-
- cargo --list | egrep "^\s*deadlinks$" -q || cargo install cargo-deadlinks
105-
- cargo deadlinks -V
106-
script:
107-
- cargo test
108-
- cargo test --benches
109-
- cargo test --examples
110-
# remove cached documentation, otherwise files from previous PRs can get included
111-
- rm -rf target/doc
112-
- cargo doc --no-deps --all --features=std,log
113-
- cargo deadlinks --dir target/doc
114-
# also test minimum dependency versions are usable
115-
- cargo generate-lockfile -Z minimal-versions
116-
- cargo test
117106

118107
- name: "cross-platform build only"
119108
rust: nightly
@@ -139,6 +128,7 @@ matrix:
139128
- cargo xbuild --target=x86_64-unknown-uefi
140129
- cargo xbuild --target=x86_64-unknown-hermit
141130
- cargo xbuild --target=x86_64-unknown-l4re-uclibc
131+
- cargo xbuild --target=x86_64-uwp-windows-gnu
142132
- cargo xbuild --target=x86_64-wrs-vxworks
143133
# also test minimum dependency versions are usable
144134
- cargo generate-lockfile -Z minimal-versions
@@ -153,6 +143,7 @@ matrix:
153143
- cargo xbuild --target=x86_64-unknown-hermit
154144
- cargo xbuild --target=x86_64-unknown-l4re-uclibc
155145
- cargo xbuild --target=x86_64-uwp-windows-gnu
146+
- cargo xbuild --target=x86_64-wrs-vxworks
156147

157148
# Trust cross-built/emulated targets. We must repeat all non-default values.
158149
- name: "Linux (MIPS, big-endian)"
@@ -199,7 +190,6 @@ before_script:
199190

200191
script:
201192
- cargo test
202-
- cargo test --examples
203193

204194
after_script: set +e
205195

Cargo.toml

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "getrandom"
3-
version = "0.1.12"
3+
version = "0.2.0"
44
edition = "2018"
55
authors = ["The Rand Project Developers"]
66
license = "MIT OR Apache-2.0"
@@ -41,3 +41,6 @@ std = []
4141
rustc-dep-of-std = ["compiler_builtins", "core"]
4242
# Unstable feature for testing
4343
test-in-browser = ["wasm-bindgen"]
44+
45+
[package.metadata.docs.rs]
46+
features = ["std"]

src/error.rs

+43-40
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,36 @@ use core::num::NonZeroU32;
1919
#[derive(Copy, Clone, Eq, PartialEq)]
2020
pub struct Error(NonZeroU32);
2121

22+
// TODO: Convert to a function when min_version >= 1.33
23+
macro_rules! internal_error {
24+
($n:expr) => {
25+
Error(unsafe { NonZeroU32::new_unchecked(Error::INTERNAL_START + $n as u16 as u32) })
26+
};
27+
}
28+
2229
impl Error {
23-
#[deprecated(since = "0.1.7")]
24-
/// Unknown error.
25-
pub const UNKNOWN: Error = UNSUPPORTED;
26-
#[deprecated(since = "0.1.7")]
27-
/// System entropy source is unavailable.
28-
pub const UNAVAILABLE: Error = UNSUPPORTED;
30+
/// This target/platform is not supported by `getrandom`.
31+
pub const UNSUPPORTED: Error = internal_error!(0);
32+
/// The platform-specific `errno` returned a non-positive value.
33+
pub const ERRNO_NOT_POSITIVE: Error = internal_error!(1);
34+
/// Call to iOS [`SecRandomCopyBytes`](https://developer.apple.com/documentation/security/1399291-secrandomcopybytes) failed.
35+
pub const IOS_SEC_RANDOM: Error = internal_error!(3);
36+
/// Call to Windows [`RtlGenRandom`](https://docs.microsoft.com/en-us/windows/win32/api/ntsecapi/nf-ntsecapi-rtlgenrandom) failed.
37+
pub const WINDOWS_RTL_GEN_RANDOM: Error = internal_error!(4);
38+
/// RDRAND instruction failed due to a hardware issue.
39+
pub const FAILED_RDRAND: Error = internal_error!(5);
40+
/// RDRAND instruction unsupported on this target.
41+
pub const NO_RDRAND: Error = internal_error!(6);
42+
/// Using `wasm-bindgen`, browser does not support `self.crypto`.
43+
pub const BINDGEN_CRYPTO_UNDEF: Error = internal_error!(7);
44+
/// Using `wasm-bindgen`, browser does not support `crypto.getRandomValues`.
45+
pub const BINDGEN_GRV_UNDEF: Error = internal_error!(8);
46+
/// Using `stdweb`, no cryptographic RNG is available.
47+
pub const STDWEB_NO_RNG: Error = internal_error!(9);
48+
/// Using `stdweb`, invoking a cryptographic RNG failed.
49+
pub const STDWEB_RNG_FAILED: Error = internal_error!(10);
50+
/// On VxWorks, call to `randSecure` failed (random number generator is not yet initialized).
51+
pub const VXWORKS_RAND_SECURE: Error = internal_error!(11);
2952

3053
/// Codes below this point represent OS Errors (i.e. positive i32 values).
3154
/// Codes at or above this point, but below [`Error::CUSTOM_START`] are
@@ -38,9 +61,11 @@ impl Error {
3861

3962
/// Extract the raw OS error code (if this error came from the OS)
4063
///
41-
/// This method is identical to `std::io::Error::raw_os_error()`, except
64+
/// This method is identical to [`std::io::Error::raw_os_error()`][1], except
4265
/// that it works in `no_std` contexts. If this method returns `None`, the
4366
/// error value can still be formatted via the `Display` implementation.
67+
///
68+
/// [1]: https://doc.rust-lang.org/std/io/struct.Error.html#method.raw_os_error
4469
#[inline]
4570
pub fn raw_os_error(self) -> Option<i32> {
4671
if self.0.get() < Self::INTERNAL_START {
@@ -126,41 +151,19 @@ impl From<NonZeroU32> for Error {
126151
}
127152
}
128153

129-
// TODO: Convert to a function when min_version >= 1.33
130-
macro_rules! internal_error {
131-
($n:expr) => {
132-
Error(unsafe { NonZeroU32::new_unchecked(Error::INTERNAL_START + $n as u16 as u32) })
133-
};
134-
}
135-
136-
/// Internal Error constants
137-
pub(crate) const UNSUPPORTED: Error = internal_error!(0);
138-
pub(crate) const ERRNO_NOT_POSITIVE: Error = internal_error!(1);
139-
pub(crate) const UNKNOWN_IO_ERROR: Error = internal_error!(2);
140-
pub(crate) const SEC_RANDOM_FAILED: Error = internal_error!(3);
141-
pub(crate) const RTL_GEN_RANDOM_FAILED: Error = internal_error!(4);
142-
pub(crate) const FAILED_RDRAND: Error = internal_error!(5);
143-
pub(crate) const NO_RDRAND: Error = internal_error!(6);
144-
pub(crate) const BINDGEN_CRYPTO_UNDEF: Error = internal_error!(7);
145-
pub(crate) const BINDGEN_GRV_UNDEF: Error = internal_error!(8);
146-
pub(crate) const STDWEB_NO_RNG: Error = internal_error!(9);
147-
pub(crate) const STDWEB_RNG_FAILED: Error = internal_error!(10);
148-
pub(crate) const RAND_SECURE_FATAL: Error = internal_error!(11);
149-
150154
fn internal_desc(error: Error) -> Option<&'static str> {
151155
match error {
152-
UNSUPPORTED => Some("getrandom: this target is not supported"),
153-
ERRNO_NOT_POSITIVE => Some("errno: did not return a positive value"),
154-
UNKNOWN_IO_ERROR => Some("Unknown std::io::Error"),
155-
SEC_RANDOM_FAILED => Some("SecRandomCopyBytes: call failed"),
156-
RTL_GEN_RANDOM_FAILED => Some("RtlGenRandom: call failed"),
157-
FAILED_RDRAND => Some("RDRAND: failed multiple times: CPU issue likely"),
158-
NO_RDRAND => Some("RDRAND: instruction not supported"),
159-
BINDGEN_CRYPTO_UNDEF => Some("wasm-bindgen: self.crypto is undefined"),
160-
BINDGEN_GRV_UNDEF => Some("wasm-bindgen: crypto.getRandomValues is undefined"),
161-
STDWEB_NO_RNG => Some("stdweb: no randomness source available"),
162-
STDWEB_RNG_FAILED => Some("stdweb: failed to get randomness"),
163-
RAND_SECURE_FATAL => Some("randSecure: random number generator module is not initialized"),
156+
Error::UNSUPPORTED => Some("getrandom: this target is not supported"),
157+
Error::ERRNO_NOT_POSITIVE => Some("errno: did not return a positive value"),
158+
Error::IOS_SEC_RANDOM => Some("SecRandomCopyBytes: iOS Secuirty framework failure"),
159+
Error::WINDOWS_RTL_GEN_RANDOM => Some("RtlGenRandom: Windows system function failure"),
160+
Error::FAILED_RDRAND => Some("RDRAND: failed multiple times: CPU issue likely"),
161+
Error::NO_RDRAND => Some("RDRAND: instruction not supported"),
162+
Error::BINDGEN_CRYPTO_UNDEF => Some("wasm-bindgen: self.crypto is undefined"),
163+
Error::BINDGEN_GRV_UNDEF => Some("wasm-bindgen: crypto.getRandomValues is undefined"),
164+
Error::STDWEB_NO_RNG => Some("stdweb: no randomness source available"),
165+
Error::STDWEB_RNG_FAILED => Some("stdweb: failed to get randomness"),
166+
Error::VXWORKS_RAND_SECURE => Some("randSecure: VxWorks RNG module is not initialized"),
164167
_ => None,
165168
}
166169
}

src/error_impls.rs

+1-13
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,10 @@
77
// except according to those terms.
88
extern crate std;
99

10-
use crate::{error::UNKNOWN_IO_ERROR, Error};
10+
use crate::Error;
1111
use core::convert::From;
12-
use core::num::NonZeroU32;
1312
use std::io;
1413

15-
impl From<io::Error> for Error {
16-
fn from(err: io::Error) -> Self {
17-
if let Some(errno) = err.raw_os_error() {
18-
if let Some(code) = NonZeroU32::new(errno as u32) {
19-
return Error::from(code);
20-
}
21-
}
22-
UNKNOWN_IO_ERROR
23-
}
24-
}
25-
2614
impl From<Error> for io::Error {
2715
fn from(err: Error) -> Self {
2816
match err.raw_os_error() {

src/ios.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
// except according to those terms.
88

99
//! Implementation for iOS
10-
use crate::{error::SEC_RANDOM_FAILED, Error};
10+
use crate::Error;
1111

1212
// TODO: Make extern once extern_types feature is stabilized. See:
1313
// https://github.com/rust-lang/rust/issues/43467
@@ -24,7 +24,7 @@ extern "C" {
2424
pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> {
2525
let ret = unsafe { SecRandomCopyBytes(kSecRandomDefault, dest.len(), dest.as_mut_ptr()) };
2626
if ret == -1 {
27-
Err(SEC_RANDOM_FAILED)
27+
Err(Error::IOS_SEC_RANDOM)
2828
} else {
2929
Ok(())
3030
}

src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ cfg_if! {
243243
/// In general, `getrandom` will be fast enough for interactive usage, though
244244
/// significantly slower than a user-space CSPRNG; for the latter consider
245245
/// [`rand::thread_rng`](https://docs.rs/rand/*/rand/fn.thread_rng.html).
246-
pub fn getrandom(dest: &mut [u8]) -> Result<(), error::Error> {
246+
pub fn getrandom(dest: &mut [u8]) -> Result<(), Error> {
247247
if dest.is_empty() {
248248
return Ok(());
249249
}

src/rdrand.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
// except according to those terms.
88

99
//! Implementation for SGX using RDRAND instruction
10-
use crate::error::{FAILED_RDRAND, NO_RDRAND};
1110
#[cfg(not(target_feature = "rdrand"))]
1211
use crate::util::LazyBool;
1312
use crate::Error;
@@ -37,7 +36,7 @@ unsafe fn rdrand() -> Result<[u8; WORD_SIZE], Error> {
3736
// Keep looping in case this was a false positive.
3837
}
3938
}
40-
Err(FAILED_RDRAND)
39+
Err(Error::FAILED_RDRAND)
4140
}
4241

4342
// "rdrand" target feature requires "+rdrnd" flag, see https://github.com/rust-lang/rust/issues/49653.
@@ -64,7 +63,7 @@ fn is_rdrand_supported() -> bool {
6463

6564
pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> {
6665
if !is_rdrand_supported() {
67-
return Err(NO_RDRAND);
66+
return Err(Error::NO_RDRAND);
6867
}
6968

7069
// SAFETY: After this point, rdrand is supported, so calling the rdrand

src/util_libc.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
// option. This file may not be copied, modified, or distributed
77
// except according to those terms.
88
#![allow(dead_code)]
9-
use crate::error::ERRNO_NOT_POSITIVE;
109
use crate::util::LazyUsize;
1110
use crate::Error;
1211
use core::num::NonZeroU32;
@@ -34,7 +33,7 @@ pub fn last_os_error() -> Error {
3433
if errno > 0 {
3534
Error::from(NonZeroU32::new(errno as u32).unwrap())
3635
} else {
37-
ERRNO_NOT_POSITIVE
36+
Error::ERRNO_NOT_POSITIVE
3837
}
3938
}
4039

src/vxworks.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,16 @@
77
// except according to those terms.
88

99
//! Implementation for VxWorks
10-
use crate::error::{Error, RAND_SECURE_FATAL};
1110
use crate::util_libc::last_os_error;
11+
use crate::Error;
1212
use core::sync::atomic::{AtomicBool, Ordering::Relaxed};
1313

1414
pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> {
1515
static RNG_INIT: AtomicBool = AtomicBool::new(false);
1616
while !RNG_INIT.load(Relaxed) {
1717
let ret = unsafe { libc::randSecure() };
1818
if ret < 0 {
19-
return Err(RAND_SECURE_FATAL);
19+
return Err(Error::VXWORKS_RAND_SECURE);
2020
} else if ret > 0 {
2121
RNG_INIT.store(true, Relaxed);
2222
break;

src/wasm32_bindgen.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ use std::thread_local;
1515

1616
use wasm_bindgen::prelude::*;
1717

18-
use crate::error::{BINDGEN_CRYPTO_UNDEF, BINDGEN_GRV_UNDEF};
1918
use crate::Error;
2019

2120
#[derive(Clone, Debug)]
@@ -66,13 +65,13 @@ fn getrandom_init() -> Result<RngSource, Error> {
6665

6766
let crypto = self_.crypto();
6867
if crypto.is_undefined() {
69-
return Err(BINDGEN_CRYPTO_UNDEF);
68+
return Err(Error::BINDGEN_CRYPTO_UNDEF);
7069
}
7170

7271
// Test if `crypto.getRandomValues` is undefined as well
7372
let crypto: BrowserCrypto = crypto.into();
7473
if crypto.get_random_values_fn().is_undefined() {
75-
return Err(BINDGEN_GRV_UNDEF);
74+
return Err(Error::BINDGEN_GRV_UNDEF);
7675
}
7776

7877
return Ok(RngSource::Browser(crypto));

src/wasm32_stdweb.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,13 @@
1010
extern crate std;
1111

1212
use core::mem;
13+
use std::sync::Once;
1314

1415
use stdweb::js;
1516
use stdweb::unstable::TryInto;
1617
use stdweb::web::error::Error as WebError;
1718

18-
use crate::error::{STDWEB_NO_RNG, STDWEB_RNG_FAILED};
1919
use crate::Error;
20-
use std::sync::Once;
2120

2221
#[derive(Clone, Copy, Debug)]
2322
enum RngSource {
@@ -71,7 +70,7 @@ fn getrandom_init() -> Result<RngSource, Error> {
7170
} else {
7271
let _err: WebError = js! { return @{ result }.error }.try_into().unwrap();
7372
error!("getrandom unavailable: {}", _err);
74-
Err(STDWEB_NO_RNG)
73+
Err(Error::STDWEB_NO_RNG)
7574
}
7675
}
7776

@@ -107,7 +106,7 @@ fn getrandom_fill(source: RngSource, dest: &mut [u8]) -> Result<(), Error> {
107106
if js! { return @{ result.as_ref() }.success } != true {
108107
let _err: WebError = js! { return @{ result }.error }.try_into().unwrap();
109108
error!("getrandom failed: {}", _err);
110-
return Err(STDWEB_RNG_FAILED);
109+
return Err(Error::STDWEB_RNG_FAILED);
111110
}
112111
}
113112
Ok(())

0 commit comments

Comments
 (0)