mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-12 03:05:44 +00:00
Merge pull request #6645 from dotCooCoo/fix/js-random-seed-web
Scripts: Math.random gets a new seed on every web page load
This commit is contained in:
Generated
+1
@@ -6589,6 +6589,7 @@ name = "vectorcraft-js"
|
||||
version = "0.24.0"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"getrandom 0.4.3",
|
||||
"proptest",
|
||||
"unicode-general-category",
|
||||
]
|
||||
|
||||
@@ -12,6 +12,12 @@ workspace = true
|
||||
[dependencies]
|
||||
chrono = { workspace = true }
|
||||
unicode-general-category = "1"
|
||||
# The seed of Math.random (interp.rs).
|
||||
getrandom = "0.4"
|
||||
|
||||
[target.'cfg(all(target_arch = "wasm32", target_os = "unknown"))'.dependencies]
|
||||
# The browser's crypto.getRandomValues.
|
||||
getrandom = { version = "0.4", features = ["wasm_js"] }
|
||||
|
||||
[dev-dependencies]
|
||||
proptest = { workspace = true }
|
||||
|
||||
@@ -605,6 +605,17 @@ fn math_functions_follow_the_special_cases() {
|
||||
truth("var n = 0; Math.max({valueOf: function () { n++; return NaN; }}, {valueOf: function () { n++; return 1; }}); n === 2");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn math_random_is_seeded_from_the_os_random_source() {
|
||||
// On wasm32-unknown-unknown `RandomState`'s keys come from memory addresses, which are the
|
||||
// same on every page load: the seed must come from the OS (the browser's crypto) instead.
|
||||
let src = include_str!("interp.rs");
|
||||
let Some(start) = src.find("fn random_seed()") else { panic!("interp.rs has no random_seed") };
|
||||
let body = &src[start..];
|
||||
let body = &body[..body.find("\n}").unwrap_or(body.len())];
|
||||
assert!(body.contains("getrandom::u64()"), "Math.random isn't seeded from the OS random source");
|
||||
}
|
||||
|
||||
// ---- JSON ----
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -307,13 +307,16 @@ fn index_keys_bytes(len: usize) -> usize {
|
||||
total
|
||||
}
|
||||
|
||||
/// A seed for `Math.random` that differs from realm to realm, from the standard library's
|
||||
/// randomly keyed hasher; never zero.
|
||||
/// A seed for `Math.random` that differs from realm to realm and from run to run, from the OS
|
||||
/// random source (the browser's crypto on the web), or the standard library's randomly keyed
|
||||
/// hasher when that fails; never zero.
|
||||
fn random_seed() -> u64 {
|
||||
use std::hash::{BuildHasher, Hasher};
|
||||
let mut h = std::collections::hash_map::RandomState::new().build_hasher();
|
||||
h.write_u64(0x9e37_79b9_7f4a_7c15);
|
||||
h.finish() | 1
|
||||
getrandom::u64().unwrap_or_else(|_| {
|
||||
let mut h = std::collections::hash_map::RandomState::new().build_hasher();
|
||||
h.write_u64(0x9e37_79b9_7f4a_7c15);
|
||||
h.finish()
|
||||
}) | 1
|
||||
}
|
||||
|
||||
/// The estimated bytes of a binding or property named by `len` code units.
|
||||
|
||||
Reference in New Issue
Block a user