|  | 
| 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