feat: patch chrono
This commit is contained in:
@@ -24,10 +24,10 @@ libc = { version = "0.2.139", default-features = false }
|
||||
wasi = { version = "0.11", default-features = false }
|
||||
|
||||
[target.'cfg(all(any(target_arch = "wasm32", target_arch = "wasm64"), target_os = "unknown"))'.dependencies]
|
||||
wasm-bindgen = { version = "0.2.62", default-features = false, optional = true }
|
||||
js-sys = { version = "0.3", optional = true }
|
||||
#wasm-bindgen = { version = "0.2.62", default-features = false, optional = true }
|
||||
#js-sys = { version = "0.3", optional = true }
|
||||
[target.'cfg(all(any(target_arch = "wasm32", target_arch = "wasm64"), target_os = "unknown"))'.dev-dependencies]
|
||||
wasm-bindgen-test = "0.3.18"
|
||||
#wasm-bindgen-test = "0.3.18"
|
||||
|
||||
[features]
|
||||
# Implement std-only traits for getrandom::Error
|
||||
@@ -35,7 +35,8 @@ std = []
|
||||
# Feature to enable fallback RDRAND-based implementation on x86/x86_64
|
||||
rdrand = []
|
||||
# Feature to enable JavaScript bindings on wasm*-unknown-unknown
|
||||
js = ["wasm-bindgen", "js-sys"]
|
||||
#js = ["wasm-bindgen", "js-sys"]
|
||||
js = []
|
||||
# Feature to enable custom RNG implementations
|
||||
custom = []
|
||||
# Unstable feature to support being a libstd dependency
|
||||
|
||||
306
javascript-engine/external/getrandom/src/js.rs
vendored
306
javascript-engine/external/getrandom/src/js.rs
vendored
@@ -5,157 +5,157 @@
|
||||
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
use crate::Error;
|
||||
// use crate::Error;
|
||||
//
|
||||
// extern crate std;
|
||||
// use std::{mem::MaybeUninit, thread_local};
|
||||
//
|
||||
// // use js_sys::{global, Function, Uint8Array};
|
||||
// // use wasm_bindgen::{prelude::wasm_bindgen, JsCast, JsValue};
|
||||
//
|
||||
// // Size of our temporary Uint8Array buffer used with WebCrypto methods
|
||||
// // Maximum is 65536 bytes see https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues
|
||||
// const WEB_CRYPTO_BUFFER_SIZE: usize = 256;
|
||||
// // Node.js's crypto.randomFillSync requires the size to be less than 2**31.
|
||||
// const NODE_MAX_BUFFER_SIZE: usize = (1 << 31) - 1;
|
||||
//
|
||||
// enum RngSource {
|
||||
// Node(NodeCrypto),
|
||||
// Web(WebCrypto, Uint8Array),
|
||||
// }
|
||||
//
|
||||
// // JsValues are always per-thread, so we initialize RngSource for each thread.
|
||||
// // See: https://github.com/rustwasm/wasm-bindgen/pull/955
|
||||
// thread_local!(
|
||||
// static RNG_SOURCE: Result<RngSource, Error> = getrandom_init();
|
||||
// );
|
||||
//
|
||||
// pub(crate) fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
|
||||
// RNG_SOURCE.with(|result| {
|
||||
// let source = result.as_ref().map_err(|&e| e)?;
|
||||
//
|
||||
// match source {
|
||||
// RngSource::Node(n) => {
|
||||
// for chunk in dest.chunks_mut(NODE_MAX_BUFFER_SIZE) {
|
||||
// // SAFETY: chunk is never used directly, the memory is only
|
||||
// // modified via the Uint8Array view, which is passed
|
||||
// // directly to JavaScript. Also, crypto.randomFillSync does
|
||||
// // not resize the buffer. We know the length is less than
|
||||
// // u32::MAX because of the chunking above.
|
||||
// // Note that this uses the fact that JavaScript doesn't
|
||||
// // have a notion of "uninitialized memory", this is purely
|
||||
// // a Rust/C/C++ concept.
|
||||
// let res = n.random_fill_sync(unsafe {
|
||||
// Uint8Array::view_mut_raw(chunk.as_mut_ptr() as *mut u8, chunk.len())
|
||||
// });
|
||||
// if res.is_err() {
|
||||
// return Err(Error::NODE_RANDOM_FILL_SYNC);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// RngSource::Web(crypto, buf) => {
|
||||
// // getRandomValues does not work with all types of WASM memory,
|
||||
// // so we initially write to browser memory to avoid exceptions.
|
||||
// for chunk in dest.chunks_mut(WEB_CRYPTO_BUFFER_SIZE) {
|
||||
// // The chunk can be smaller than buf's length, so we call to
|
||||
// // JS to create a smaller view of buf without allocation.
|
||||
// let sub_buf = buf.subarray(0, chunk.len() as u32);
|
||||
//
|
||||
// if crypto.get_random_values(&sub_buf).is_err() {
|
||||
// return Err(Error::WEB_GET_RANDOM_VALUES);
|
||||
// }
|
||||
//
|
||||
// // SAFETY: `sub_buf`'s length is the same length as `chunk`
|
||||
// unsafe { sub_buf.raw_copy_to_ptr(chunk.as_mut_ptr() as *mut u8) };
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
// Ok(())
|
||||
// })
|
||||
// }
|
||||
//
|
||||
// fn getrandom_init() -> Result<RngSource, Error> {
|
||||
// let global: Global = global().unchecked_into();
|
||||
//
|
||||
// // Get the Web Crypto interface if we are in a browser, Web Worker, Deno,
|
||||
// // or another environment that supports the Web Cryptography API. This
|
||||
// // also allows for user-provided polyfills in unsupported environments.
|
||||
// let crypto = match global.crypto() {
|
||||
// // Standard Web Crypto interface
|
||||
// c if c.is_object() => c,
|
||||
// // Node.js CommonJS Crypto module
|
||||
// _ if is_node(&global) => {
|
||||
// // If module.require isn't a valid function, we are in an ES module.
|
||||
// match Module::require_fn().and_then(JsCast::dyn_into::<Function>) {
|
||||
// Ok(require_fn) => match require_fn.call1(&global, &JsValue::from_str("crypto")) {
|
||||
// Ok(n) => return Ok(RngSource::Node(n.unchecked_into())),
|
||||
// Err(_) => return Err(Error::NODE_CRYPTO),
|
||||
// },
|
||||
// Err(_) => return Err(Error::NODE_ES_MODULE),
|
||||
// }
|
||||
// }
|
||||
// // IE 11 Workaround
|
||||
// _ => match global.ms_crypto() {
|
||||
// c if c.is_object() => c,
|
||||
// _ => return Err(Error::WEB_CRYPTO),
|
||||
// },
|
||||
// };
|
||||
//
|
||||
// let buf = Uint8Array::new_with_length(WEB_CRYPTO_BUFFER_SIZE as u32);
|
||||
// Ok(RngSource::Web(crypto, buf))
|
||||
// }
|
||||
//
|
||||
// // Taken from https://www.npmjs.com/package/browser-or-node
|
||||
// fn is_node(global: &Global) -> bool {
|
||||
// let process = global.process();
|
||||
// if process.is_object() {
|
||||
// let versions = process.versions();
|
||||
// if versions.is_object() {
|
||||
// return versions.node().is_string();
|
||||
// }
|
||||
// }
|
||||
// false
|
||||
// }
|
||||
|
||||
extern crate std;
|
||||
use std::{mem::MaybeUninit, thread_local};
|
||||
|
||||
use js_sys::{global, Function, Uint8Array};
|
||||
use wasm_bindgen::{prelude::wasm_bindgen, JsCast, JsValue};
|
||||
|
||||
// Size of our temporary Uint8Array buffer used with WebCrypto methods
|
||||
// Maximum is 65536 bytes see https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues
|
||||
const WEB_CRYPTO_BUFFER_SIZE: usize = 256;
|
||||
// Node.js's crypto.randomFillSync requires the size to be less than 2**31.
|
||||
const NODE_MAX_BUFFER_SIZE: usize = (1 << 31) - 1;
|
||||
|
||||
enum RngSource {
|
||||
Node(NodeCrypto),
|
||||
Web(WebCrypto, Uint8Array),
|
||||
}
|
||||
|
||||
// JsValues are always per-thread, so we initialize RngSource for each thread.
|
||||
// See: https://github.com/rustwasm/wasm-bindgen/pull/955
|
||||
thread_local!(
|
||||
static RNG_SOURCE: Result<RngSource, Error> = getrandom_init();
|
||||
);
|
||||
|
||||
pub(crate) fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
|
||||
RNG_SOURCE.with(|result| {
|
||||
let source = result.as_ref().map_err(|&e| e)?;
|
||||
|
||||
match source {
|
||||
RngSource::Node(n) => {
|
||||
for chunk in dest.chunks_mut(NODE_MAX_BUFFER_SIZE) {
|
||||
// SAFETY: chunk is never used directly, the memory is only
|
||||
// modified via the Uint8Array view, which is passed
|
||||
// directly to JavaScript. Also, crypto.randomFillSync does
|
||||
// not resize the buffer. We know the length is less than
|
||||
// u32::MAX because of the chunking above.
|
||||
// Note that this uses the fact that JavaScript doesn't
|
||||
// have a notion of "uninitialized memory", this is purely
|
||||
// a Rust/C/C++ concept.
|
||||
let res = n.random_fill_sync(unsafe {
|
||||
Uint8Array::view_mut_raw(chunk.as_mut_ptr() as *mut u8, chunk.len())
|
||||
});
|
||||
if res.is_err() {
|
||||
return Err(Error::NODE_RANDOM_FILL_SYNC);
|
||||
}
|
||||
}
|
||||
}
|
||||
RngSource::Web(crypto, buf) => {
|
||||
// getRandomValues does not work with all types of WASM memory,
|
||||
// so we initially write to browser memory to avoid exceptions.
|
||||
for chunk in dest.chunks_mut(WEB_CRYPTO_BUFFER_SIZE) {
|
||||
// The chunk can be smaller than buf's length, so we call to
|
||||
// JS to create a smaller view of buf without allocation.
|
||||
let sub_buf = buf.subarray(0, chunk.len() as u32);
|
||||
|
||||
if crypto.get_random_values(&sub_buf).is_err() {
|
||||
return Err(Error::WEB_GET_RANDOM_VALUES);
|
||||
}
|
||||
|
||||
// SAFETY: `sub_buf`'s length is the same length as `chunk`
|
||||
unsafe { sub_buf.raw_copy_to_ptr(chunk.as_mut_ptr() as *mut u8) };
|
||||
}
|
||||
}
|
||||
};
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
fn getrandom_init() -> Result<RngSource, Error> {
|
||||
let global: Global = global().unchecked_into();
|
||||
|
||||
// Get the Web Crypto interface if we are in a browser, Web Worker, Deno,
|
||||
// or another environment that supports the Web Cryptography API. This
|
||||
// also allows for user-provided polyfills in unsupported environments.
|
||||
let crypto = match global.crypto() {
|
||||
// Standard Web Crypto interface
|
||||
c if c.is_object() => c,
|
||||
// Node.js CommonJS Crypto module
|
||||
_ if is_node(&global) => {
|
||||
// If module.require isn't a valid function, we are in an ES module.
|
||||
match Module::require_fn().and_then(JsCast::dyn_into::<Function>) {
|
||||
Ok(require_fn) => match require_fn.call1(&global, &JsValue::from_str("crypto")) {
|
||||
Ok(n) => return Ok(RngSource::Node(n.unchecked_into())),
|
||||
Err(_) => return Err(Error::NODE_CRYPTO),
|
||||
},
|
||||
Err(_) => return Err(Error::NODE_ES_MODULE),
|
||||
}
|
||||
}
|
||||
// IE 11 Workaround
|
||||
_ => match global.ms_crypto() {
|
||||
c if c.is_object() => c,
|
||||
_ => return Err(Error::WEB_CRYPTO),
|
||||
},
|
||||
};
|
||||
|
||||
let buf = Uint8Array::new_with_length(WEB_CRYPTO_BUFFER_SIZE as u32);
|
||||
Ok(RngSource::Web(crypto, buf))
|
||||
}
|
||||
|
||||
// Taken from https://www.npmjs.com/package/browser-or-node
|
||||
fn is_node(global: &Global) -> bool {
|
||||
let process = global.process();
|
||||
if process.is_object() {
|
||||
let versions = process.versions();
|
||||
if versions.is_object() {
|
||||
return versions.node().is_string();
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
extern "C" {
|
||||
// Return type of js_sys::global()
|
||||
type Global;
|
||||
|
||||
// Web Crypto API: Crypto interface (https://www.w3.org/TR/WebCryptoAPI/)
|
||||
type WebCrypto;
|
||||
// Getters for the WebCrypto API
|
||||
#[wasm_bindgen(method, getter)]
|
||||
fn crypto(this: &Global) -> WebCrypto;
|
||||
#[wasm_bindgen(method, getter, js_name = msCrypto)]
|
||||
fn ms_crypto(this: &Global) -> WebCrypto;
|
||||
// Crypto.getRandomValues()
|
||||
#[wasm_bindgen(method, js_name = getRandomValues, catch)]
|
||||
fn get_random_values(this: &WebCrypto, buf: &Uint8Array) -> Result<(), JsValue>;
|
||||
|
||||
// Node JS crypto module (https://nodejs.org/api/crypto.html)
|
||||
type NodeCrypto;
|
||||
// crypto.randomFillSync()
|
||||
#[wasm_bindgen(method, js_name = randomFillSync, catch)]
|
||||
fn random_fill_sync(this: &NodeCrypto, buf: Uint8Array) -> Result<(), JsValue>;
|
||||
|
||||
// Ideally, we would just use `fn require(s: &str)` here. However, doing
|
||||
// this causes a Webpack warning. So we instead return the function itself
|
||||
// and manually invoke it using call1. This also lets us to check that the
|
||||
// function actually exists, allowing for better error messages. See:
|
||||
// https://github.com/rust-random/getrandom/issues/224
|
||||
// https://github.com/rust-random/getrandom/issues/256
|
||||
type Module;
|
||||
#[wasm_bindgen(getter, static_method_of = Module, js_class = module, js_name = require, catch)]
|
||||
fn require_fn() -> Result<JsValue, JsValue>;
|
||||
|
||||
// Node JS process Object (https://nodejs.org/api/process.html)
|
||||
#[wasm_bindgen(method, getter)]
|
||||
fn process(this: &Global) -> Process;
|
||||
type Process;
|
||||
#[wasm_bindgen(method, getter)]
|
||||
fn versions(this: &Process) -> Versions;
|
||||
type Versions;
|
||||
#[wasm_bindgen(method, getter)]
|
||||
fn node(this: &Versions) -> JsValue;
|
||||
}
|
||||
// #[wasm_bindgen]
|
||||
// extern "C" {
|
||||
// // Return type of js_sys::global()
|
||||
// type Global;
|
||||
//
|
||||
// // Web Crypto API: Crypto interface (https://www.w3.org/TR/WebCryptoAPI/)
|
||||
// type WebCrypto;
|
||||
// // Getters for the WebCrypto API
|
||||
// #[wasm_bindgen(method, getter)]
|
||||
// fn crypto(this: &Global) -> WebCrypto;
|
||||
// #[wasm_bindgen(method, getter, js_name = msCrypto)]
|
||||
// fn ms_crypto(this: &Global) -> WebCrypto;
|
||||
// // Crypto.getRandomValues()
|
||||
// #[wasm_bindgen(method, js_name = getRandomValues, catch)]
|
||||
// fn get_random_values(this: &WebCrypto, buf: &Uint8Array) -> Result<(), JsValue>;
|
||||
//
|
||||
// // Node JS crypto module (https://nodejs.org/api/crypto.html)
|
||||
// type NodeCrypto;
|
||||
// // crypto.randomFillSync()
|
||||
// #[wasm_bindgen(method, js_name = randomFillSync, catch)]
|
||||
// fn random_fill_sync(this: &NodeCrypto, buf: Uint8Array) -> Result<(), JsValue>;
|
||||
//
|
||||
// // Ideally, we would just use `fn require(s: &str)` here. However, doing
|
||||
// // this causes a Webpack warning. So we instead return the function itself
|
||||
// // and manually invoke it using call1. This also lets us to check that the
|
||||
// // function actually exists, allowing for better error messages. See:
|
||||
// // https://github.com/rust-random/getrandom/issues/224
|
||||
// // https://github.com/rust-random/getrandom/issues/256
|
||||
// type Module;
|
||||
// #[wasm_bindgen(getter, static_method_of = Module, js_class = module, js_name = require, catch)]
|
||||
// fn require_fn() -> Result<JsValue, JsValue>;
|
||||
//
|
||||
// // Node JS process Object (https://nodejs.org/api/process.html)
|
||||
// #[wasm_bindgen(method, getter)]
|
||||
// fn process(this: &Global) -> Process;
|
||||
// type Process;
|
||||
// #[wasm_bindgen(method, getter)]
|
||||
// fn versions(this: &Process) -> Versions;
|
||||
// type Versions;
|
||||
// #[wasm_bindgen(method, getter)]
|
||||
// fn node(this: &Versions) -> JsValue;
|
||||
// }
|
||||
|
||||
@@ -332,7 +332,13 @@ pub fn getrandom(dest: &mut [u8]) -> Result<(), Error> {
|
||||
#[inline]
|
||||
pub fn getrandom_uninit(dest: &mut [MaybeUninit<u8>]) -> Result<&mut [u8], Error> {
|
||||
if !dest.is_empty() {
|
||||
imp::getrandom_inner(dest)?;
|
||||
// imp::getrandom_inner(dest)?;
|
||||
// just init with XXX...XXX
|
||||
let len = dest.len();
|
||||
let ptr = dest.as_mut_ptr() as *mut u8;
|
||||
for i in 0..len {
|
||||
unsafe { *ptr.add(i) = 'X' as u8 };
|
||||
}
|
||||
}
|
||||
// SAFETY: `dest` has been fully initialized by `imp::getrandom_inner`
|
||||
// since it returned `Ok`.
|
||||
|
||||
Reference in New Issue
Block a user