Skip to content

Commit 0784e86

Browse files
committed
Remove buffer zeroing from Node.js implementation
We can use [`Uint8Array::view_mut_raw`](https://rustwasm.github.io/wasm-bindgen/api/js_sys/struct.Uint8Array.html#method.view_mut_raw) which was [added](rustwasm/wasm-bindgen#1850) in version `0.2.54` of `wasm-bindgen`. This method was introduced to deal with uninitialized memory, see the Safety comment for more info. Signed-off-by: Joe Richey <joerichey@google.com>
1 parent 710b24d commit 0784e86

File tree

1 file changed

+14
-7
lines changed

1 file changed

+14
-7
lines changed

src/js.rs

+14-7
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
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 crate::{util::uninit_slice_fill_zero, Error};
8+
use crate::Error;
99

1010
extern crate std;
1111
use std::{mem::MaybeUninit, thread_local};
@@ -36,12 +36,19 @@ pub(crate) fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error>
3636

3737
match source {
3838
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-
4339
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() {
4552
return Err(Error::NODE_RANDOM_FILL_SYNC);
4653
}
4754
}
@@ -130,7 +137,7 @@ extern "C" {
130137
type NodeCrypto;
131138
// crypto.randomFillSync()
132139
#[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>;
134141

135142
// Ideally, we would just use `fn require(s: &str)` here. However, doing
136143
// this causes a Webpack warning. So we instead return the function itself

0 commit comments

Comments
 (0)