Skip to content

Commit 679c52c

Browse files
authored
Merge pull request rust-random#10 from dhardy/ci
Add CI config and implement on WASM
2 parents 7f68c78 + ac13e04 commit 679c52c

19 files changed

+628
-17
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
/target
22
**/*.rs.bk
33
Cargo.lock
4+
*.ts
5+
*.js
6+
*.wasm

.travis.yml

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
language: rust
2+
sudo: false
3+
4+
matrix:
5+
include:
6+
- rust: 1.28.0
7+
env: DESCRIPTION="Linux, 1.28.0"
8+
os: linux
9+
10+
- rust: 1.28.0
11+
env: DESCRIPTION="OSX, 1.22.0"
12+
os: osx
13+
14+
- rust: stable
15+
env: DESCRIPTION="Linux, stable"
16+
17+
- rust: stable
18+
env: DESCRIPTION="OSX+iOS, stable"
19+
os: osx
20+
install:
21+
- rustup target add aarch64-apple-ios
22+
23+
- rust: beta
24+
env: DESCRIPTION="Linux, beta"
25+
26+
- rust: nightly
27+
os: linux
28+
env: DESCRIPTION="Linux, nightly, docs"
29+
install:
30+
- cargo --list | egrep "^\s*deadlinks$" -q || cargo install cargo-deadlinks
31+
- cargo deadlinks -V
32+
script:
33+
- cargo test
34+
- cargo test --benches
35+
- cargo test --examples
36+
# remove cached documentation, otherwise files from previous PRs can get included
37+
- rm -rf target/doc
38+
- cargo doc --no-deps --all --all-features
39+
- cargo deadlinks --dir target/doc
40+
41+
- rust: nightly
42+
os: osx
43+
env: DESCRIPTION="OSX, nightly, docs"
44+
install:
45+
- cargo --list | egrep "^\s*deadlinks$" -q || cargo install cargo-deadlinks
46+
- cargo deadlinks -V
47+
script:
48+
- cargo test
49+
- cargo test --benches
50+
- cargo test --examples
51+
# remove cached documentation, otherwise files from previous PRs can get included
52+
- rm -rf target/doc
53+
- cargo doc --no-deps --all --all-features
54+
- cargo deadlinks --dir target/doc
55+
56+
- rust: nightly
57+
env: DESCRIPTION="WASM via emscripten, stdweb and wasm-bindgen"
58+
install:
59+
- rustup target add wasm32-unknown-unknown
60+
- rustup target add wasm32-unknown-emscripten
61+
- nvm install 9
62+
- ./utils/ci/install_cargo_web.sh
63+
- cargo web prepare-emscripten
64+
- cargo web -V
65+
- cargo list | grep install-update || cargo install -f cargo-update
66+
- cargo install-update -i cargo-update wasm-bindgen-cli wasm-pack
67+
addons:
68+
chrome: stable
69+
script:
70+
# Testing wasm32-unknown-emscripten fails because of rust-lang/rust#49877
71+
# However, we can still build and link all tests to make sure that works.
72+
# This is actually useful as it finds stuff such as rust-random/rand#669
73+
- EMCC_CFLAGS="-s ERROR_ON_UNDEFINED_SYMBOLS=0" cargo web test --target wasm32-unknown-emscripten --no-run
74+
#- cargo web test --target wasm32-unknown-emscripten
75+
#- cargo web test --nodejs --target wasm32-unknown-emscripten
76+
#- cargo build --target wasm32-unknown-unknown # without any features
77+
- cargo build --target wasm32-unknown-unknown --features=wasm-bindgen
78+
- cargo web test --target wasm32-unknown-unknown --features=stdweb
79+
- cargo build --manifest-path tests/wasm_bindgen/Cargo.toml --target wasm32-unknown-unknown
80+
- wasm-bindgen --nodejs target/wasm32-unknown-unknown/debug/getrandom_wasm_bindgen_test.wasm --out-dir tests/wasm_bindgen/js
81+
- node tests/wasm_bindgen/js/index.js
82+
- wasm-pack test --node tests/wasm_bindgen
83+
84+
- rust: nightly
85+
env: DESCRIPTION="cross-platform build only"
86+
install:
87+
- rustup target add x86_64-sun-solaris
88+
- rustup target add x86_64-unknown-cloudabi
89+
- rustup target add x86_64-unknown-freebsd
90+
#- rustup target add x86_64-unknown-fuchsia
91+
- rustup target add x86_64-unknown-netbsd
92+
- rustup target add x86_64-unknown-redox
93+
script:
94+
- cargo build --target=x86_64-sun-solaris --all-features
95+
- cargo build --target=x86_64-unknown-cloudabi --all-features
96+
- cargo build --target=x86_64-unknown-freebsd --all-features
97+
#- cargo build --target=x86_64-unknown-fuchsia --all-features
98+
- cargo build --target=x86_64-unknown-netbsd --all-features
99+
- cargo build --target=x86_64-unknown-redox --all-features
100+
101+
# Trust cross-built/emulated targets. We must repeat all non-default values.
102+
- rust: stable
103+
sudo: required
104+
dist: trusty
105+
services: docker
106+
env: DESCRIPTION="Linux (MIPS, big-endian)" TARGET=mips-unknown-linux-gnu
107+
install:
108+
- sh utils/ci/install.sh
109+
- source ~/.cargo/env || true
110+
script:
111+
- bash utils/ci/script.sh
112+
113+
- rust: stable
114+
sudo: required
115+
dist: trusty
116+
services: docker
117+
env: DESCRIPTION="Android (ARMv7)" TARGET=armv7-linux-androideabi
118+
install:
119+
- sh utils/ci/install.sh
120+
- source ~/.cargo/env || true
121+
script:
122+
- bash utils/ci/script.sh
123+
124+
before_install:
125+
- set -e
126+
- rustup self update
127+
128+
script:
129+
- cargo test
130+
- cargo test --examples
131+
132+
after_script: set +e
133+
134+
cache:
135+
cargo: true
136+
directories:
137+
- .local/share/cargo-web
138+
139+
before_cache:
140+
# Travis can't cache files that are not readable by "others"
141+
- chmod -R a+r $HOME/.cargo
142+
143+
notifications:
144+
email:
145+
on_success: never

Cargo.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,20 @@ description = "A small cross-platform library to securely get random data (entro
99
travis-ci = { repository = "rust-random/getrandom" }
1010
appveyor = { repository = "rust-random/getrandom" }
1111

12+
[workspace]
13+
members = [
14+
"tests/wasm_bindgen",
15+
]
16+
1217
[target.'cfg(unix)'.dependencies]
1318
libc = "0.2"
1419

1520
[target.'cfg(windows)'.dependencies]
1621
winapi = { version = "0.3", features = ["minwindef", "ntsecapi", "winnt"] }
1722

23+
[target.'cfg(target_os = "cloudabi")'.dependencies]
24+
cloudabi = "0.0.3"
25+
1826
[target.'cfg(fuchsia)'.dependencies]
1927
fuchsia-cprng = "0.1"
2028

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ one of the following features must be enabled:
4444
- [`wasm-bindgen`](https://crates.io/crates/wasm_bindgen)
4545
- [`stdweb`](https://crates.io/crates/stdweb)
4646

47+
## Versions
48+
49+
This crate requires Rustc version 1.28.0 or later due to usage of `NonZeroU32`.
50+
4751

4852
# License
4953

appveyor.yml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
environment:
2+
3+
# At the time this was added AppVeyor was having troubles with checking
4+
# revocation of SSL certificates of sites like static.rust-lang.org and what
5+
# we think is crates.io. The libcurl HTTP client by default checks for
6+
# revocation on Windows and according to a mailing list [1] this can be
7+
# disabled.
8+
#
9+
# The `CARGO_HTTP_CHECK_REVOKE` env var here tells cargo to disable SSL
10+
# revocation checking on Windows in libcurl. Note, though, that rustup, which
11+
# we're using to download Rust here, also uses libcurl as the default backend.
12+
# Unlike Cargo, however, rustup doesn't have a mechanism to disable revocation
13+
# checking. To get rustup working we set `RUSTUP_USE_HYPER` which forces it to
14+
# use the Hyper instead of libcurl backend. Both Hyper and libcurl use
15+
# schannel on Windows but it appears that Hyper configures it slightly
16+
# differently such that revocation checking isn't turned on by default.
17+
#
18+
# [1]: https://curl.haxx.se/mail/lib-2016-03/0202.html
19+
RUSTUP_USE_HYPER: 1
20+
CARGO_HTTP_CHECK_REVOKE: false
21+
22+
matrix:
23+
- TARGET: x86_64-pc-windows-msvc
24+
- TARGET: i686-pc-windows-msvc
25+
install:
26+
- appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe
27+
- rustup-init.exe -y --default-host %TARGET%
28+
- set PATH=%PATH%;C:\Users\appveyor\.cargo\bin
29+
- rustc -V
30+
- cargo -V
31+
32+
build: false
33+
34+
test_script:
35+
- cargo test
36+
- cargo test --examples

src/cloudabi.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,20 @@
55
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
66
// option. This file may not be copied, modified, or distributed
77
// except according to those terms.
8-
use error::Error;
98

10-
extern "C" {
11-
fn cloudabi_sys_random_get(buf: *mut u8, len: usize) -> u16;
12-
}
9+
//! Implementation for CloudABI
10+
11+
extern crate cloudabi;
12+
13+
use core::num::NonZeroU32;
14+
use error::Error;
1315

1416
pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> {
15-
let errno = unsafe { cloudabi_sys_random_get(dest.as_ptr(), dest.len()) };
16-
if errno == 0 {
17+
let errno = unsafe { cloudabi::random_get(dest) };
18+
if errno == cloudabi::errno::SUCCESS {
1719
Ok(())
1820
} else {
19-
Err(Error(unsafe {
20-
NonZeroU32::new_unchecked(errno as u32)
21-
}))
21+
let code = NonZeroU32::new(errno as u32).unwrap();
22+
Err(Error::from(code))
2223
}
2324
}

src/error.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,12 @@ impl fmt::Display for Error {
5050
}
5151
}
5252

53+
impl From<NonZeroU32> for Error {
54+
fn from(code: NonZeroU32) -> Self {
55+
Error(code)
56+
}
57+
}
58+
5359
#[cfg(not(target_env = "sgx"))]
5460
impl From<io::Error> for Error {
5561
fn from(err: io::Error) -> Self {

src/lib.rs

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,11 +91,26 @@
9191
//! [15]: https://nodejs.org/api/crypto.html#crypto_crypto_randombytes_size_callback
9292
//! [16]: #support-for-webassembly-and-amsjs
9393
94+
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk.png",
95+
html_favicon_url = "https://www.rust-lang.org/favicon.ico",
96+
html_root_url = "https://rust-random.github.io/rand/")]
97+
9498
#![no_std]
9599

100+
#![cfg_attr(feature = "stdweb", recursion_limit="128")]
101+
96102
#[cfg(not(target_env = "sgx"))]
97103
#[macro_use] extern crate std;
98104

105+
// We have to do it here because we load macros
106+
#[cfg(all(target_arch = "wasm32", not(target_os = "emscripten"),
107+
feature = "wasm-bindgen"))]
108+
extern crate wasm_bindgen;
109+
#[cfg(all(target_arch = "wasm32", not(target_os = "emscripten"),
110+
not(feature = "wasm-bindgen"),
111+
feature = "stdweb"))]
112+
#[macro_use] extern crate stdweb;
113+
99114
#[cfg(any(
100115
target_os = "android",
101116
target_os = "netbsd",
@@ -104,8 +119,8 @@
104119
target_os = "redox",
105120
target_os = "dragonfly",
106121
target_os = "haiku",
107-
target_os = "emscripten",
108122
target_os = "linux",
123+
target_arch = "wasm32",
109124
))]
110125
mod utils;
111126
mod error;
@@ -209,3 +224,58 @@ mod_use!(
209224
pub fn getrandom(dest: &mut [u8]) -> Result<(), Error> {
210225
getrandom_inner(dest)
211226
}
227+
228+
// Due to rustwasm/wasm-bindgen#201 this can't be defined in the inner os
229+
// modules, so hack around it for now and place it at the root.
230+
#[cfg(all(feature = "wasm-bindgen", target_arch = "wasm32"))]
231+
#[doc(hidden)]
232+
#[allow(missing_debug_implementations)]
233+
pub mod __wbg_shims {
234+
235+
// `extern { type Foo; }` isn't supported on 1.22 syntactically, so use a
236+
// macro to work around that.
237+
macro_rules! rust_122_compat {
238+
($($t:tt)*) => ($($t)*)
239+
}
240+
241+
rust_122_compat! {
242+
extern crate wasm_bindgen;
243+
244+
pub use wasm_bindgen::prelude::*;
245+
246+
#[wasm_bindgen]
247+
extern "C" {
248+
pub type Function;
249+
#[wasm_bindgen(constructor)]
250+
pub fn new(s: &str) -> Function;
251+
#[wasm_bindgen(method)]
252+
pub fn call(this: &Function, self_: &JsValue) -> JsValue;
253+
254+
pub type This;
255+
#[wasm_bindgen(method, getter, structural, js_name = self)]
256+
pub fn self_(me: &This) -> JsValue;
257+
#[wasm_bindgen(method, getter, structural)]
258+
pub fn crypto(me: &This) -> JsValue;
259+
260+
#[derive(Clone, Debug)]
261+
pub type BrowserCrypto;
262+
263+
// TODO: these `structural` annotations here ideally wouldn't be here to
264+
// avoid a JS shim, but for now with feature detection they're
265+
// unavoidable.
266+
#[wasm_bindgen(method, js_name = getRandomValues, structural, getter)]
267+
pub fn get_random_values_fn(me: &BrowserCrypto) -> JsValue;
268+
#[wasm_bindgen(method, js_name = getRandomValues, structural)]
269+
pub fn get_random_values(me: &BrowserCrypto, buf: &mut [u8]);
270+
271+
#[wasm_bindgen(js_name = require)]
272+
pub fn node_require(s: &str) -> NodeCrypto;
273+
274+
#[derive(Clone, Debug)]
275+
pub type NodeCrypto;
276+
277+
#[wasm_bindgen(method, js_name = randomFillSync, structural)]
278+
pub fn random_fill_sync(me: &NodeCrypto, buf: &mut [u8]);
279+
}
280+
}
281+
}

src/linux_android.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ use std::fs::File;
1515
use std::io;
1616
use std::io::Read;
1717
use std::cell::RefCell;
18-
use std::sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, Ordering};
18+
use std::sync::atomic::{AtomicBool, Ordering};
1919

20-
static RNG_INIT: AtomicBool = ATOMIC_BOOL_INIT;
20+
static RNG_INIT: AtomicBool = AtomicBool::new(false);
2121

2222
enum RngSource {
2323
GetRandom,
@@ -32,7 +32,7 @@ fn syscall_getrandom(dest: &mut [u8]) -> Result<(), io::Error> {
3232
let ret = unsafe {
3333
libc::syscall(libc::SYS_getrandom, dest.as_mut_ptr(), dest.len(), 0)
3434
};
35-
if ret == -1 || ret != dest.len() as i64 {
35+
if ret < 0 || (ret as usize) != dest.len() {
3636
return Err(io::Error::last_os_error());
3737
}
3838
Ok(())
@@ -67,7 +67,7 @@ fn is_getrandom_available() -> bool {
6767
use std::sync::{Once, ONCE_INIT};
6868

6969
static CHECKER: Once = ONCE_INIT;
70-
static AVAILABLE: AtomicBool = ATOMIC_BOOL_INIT;
70+
static AVAILABLE: AtomicBool = AtomicBool::new(false);
7171

7272
CHECKER.call_once(|| {
7373
let mut buf: [u8; 0] = [];

0 commit comments

Comments
 (0)