|
5 | 5 | // <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your |
6 | 6 | // option. This file may not be copied, modified, or distributed |
7 | 7 | // except according to those terms. |
8 | | -use crate::{util::uninit_slice_fill_zero, Error}; |
| 8 | +use crate::Error; |
9 | 9 |
|
10 | 10 | extern crate std; |
11 | 11 | use std::{mem::MaybeUninit, thread_local}; |
@@ -36,12 +36,19 @@ pub(crate) fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> |
36 | 36 |
|
37 | 37 | match source { |
38 | 38 | RngSource::Node(n) => { |
39 | | - // XXX(perf): `random_fill_sync` requires a `&mut [u8]` so we |
40 | | - // have to ensure the memory in `dest` is initialized. |
41 | | - let dest = uninit_slice_fill_zero(dest); |
42 | | - |
43 | 39 | for chunk in dest.chunks_mut(NODE_MAX_BUFFER_SIZE) { |
44 | | - if n.random_fill_sync(chunk).is_err() { |
| 40 | + // SAFETY: chunk is never used directly, the memory is only |
| 41 | + // modified via the Uint8Array view, which is passed |
| 42 | + // directly to JavaScript. Also, crypto.randomFillSync does |
| 43 | + // not resize the buffer. We know the length is less than |
| 44 | + // u32::MAX because of the chunking above. |
| 45 | + // Note that this uses the fact that JavaScript doesn't |
| 46 | + // have a notion of "uninitialized memory", this is purely |
| 47 | + // a Rust/C/C++ concept. |
| 48 | + let res = n.random_fill_sync(unsafe { |
| 49 | + Uint8Array::view_mut_raw(chunk.as_mut_ptr() as *mut u8, chunk.len()) |
| 50 | + }); |
| 51 | + if res.is_err() { |
45 | 52 | return Err(Error::NODE_RANDOM_FILL_SYNC); |
46 | 53 | } |
47 | 54 | } |
@@ -130,7 +137,7 @@ extern "C" { |
130 | 137 | type NodeCrypto; |
131 | 138 | // crypto.randomFillSync() |
132 | 139 | #[wasm_bindgen(method, js_name = randomFillSync, catch)] |
133 | | - fn random_fill_sync(this: &NodeCrypto, buf: &mut [u8]) -> Result<(), JsValue>; |
| 140 | + fn random_fill_sync(this: &NodeCrypto, buf: Uint8Array) -> Result<(), JsValue>; |
134 | 141 |
|
135 | 142 | // Ideally, we would just use `fn require(s: &str)` here. However, doing |
136 | 143 | // this causes a Webpack warning. So we instead return the function itself |
|
0 commit comments