From 1b2c08694365671aaba5d23deb8eade47a43bcfd Mon Sep 17 00:00:00 2001 From: Horia Culea Date: Mon, 3 Jun 2024 13:00:36 +0200 Subject: [PATCH 1/6] Add support for injecting unix millisecond time function for non-JS WASM targets --- Cargo.toml | 7 ++++--- src/feedback.rs | 2 +- src/lib.rs | 26 +++++++++++++++++++++++--- src/scoring.rs | 18 +++++++++++++++++- 4 files changed, 45 insertions(+), 8 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index e92540e..ce2c87f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,9 +20,9 @@ itertools = "0.13" lazy_static = "1.3" regex = "1" time = { version = "0.3" } +chrono = "0.4" -[target.'cfg(target_arch = "wasm32")'.dependencies] -getrandom = { version = "0.2", features = ["js"] } +[target.'cfg(all(target_arch = "wasm32", not(feature = "non-js")))'.dependencies] wasm-bindgen = "0.2" web-sys = { version = "0.3", features = ["Performance"] } @@ -39,7 +39,7 @@ serde_json = "1" criterion = "0.5" serde_json = "1" -[target.'cfg(target_arch = "wasm32")'.dev-dependencies] +[target.'cfg(all(target_arch = "wasm32", not(feature = "non-js")))'.dev-dependencies] criterion = { version = "0.5", default-features = false } wasm-bindgen-test = "0.3" @@ -47,6 +47,7 @@ wasm-bindgen-test = "0.3" default = ["builder"] ser = ["serde"] builder = ["derive_builder"] +non-js = [] [profile.test] opt-level = 2 diff --git a/src/feedback.rs b/src/feedback.rs index ebd4eca..6821837 100644 --- a/src/feedback.rs +++ b/src/feedback.rs @@ -292,7 +292,7 @@ fn get_dictionary_match_feedback( mod tests { use super::*; - #[cfg(target_arch = "wasm32")] + #[cfg(all(target_arch = "wasm32", not(feature = "non-js")))] use wasm_bindgen_test::wasm_bindgen_test; #[cfg_attr(not(target_arch = "wasm32"), test)] diff --git a/src/lib.rs b/src/lib.rs index c971f9f..2c22f51 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,6 @@ #![doc = include_str!("../README.md")] #![recursion_limit = "128"] #![warn(missing_docs)] -#![forbid(unsafe_code)] #[macro_use] #[cfg(feature = "builder")] @@ -18,7 +17,7 @@ extern crate quickcheck; pub use scoring::Score; use time_estimates::CrackTimes; -#[cfg(target_arch = "wasm32")] +#[cfg(all(target_arch = "wasm32", not(feature = "non-js")))] use wasm_bindgen::prelude::wasm_bindgen; pub use crate::matching::Match; @@ -42,7 +41,7 @@ where (result, calc_time) } -#[cfg(target_arch = "wasm32")] +#[cfg(all(target_arch = "wasm32", not(feature = "non-js")))] #[allow(non_upper_case_globals)] fn time_scoped(f: F) -> (R, Duration) where @@ -61,6 +60,27 @@ where (result, calc_time) } +#[cfg(all(target_arch = "wasm32", feature = "non-js"))] +fn time_scoped(f: F) -> (R, Duration) +where + F: FnOnce() -> R, +{ + #[link(wasm_import_module = "zxcvbn")] + extern "C" { + fn unix_time_milliseconds_imported() -> u64; + } + let start_time = unsafe { + unix_time_milliseconds_imported() + }; + let result = f(); + let end_time = unsafe { + unix_time_milliseconds_imported() + }; + + let duration = std::time::Duration::from_millis(end_time - start_time); + (result, duration) +} + /// Contains the results of an entropy calculation #[derive(Debug, Clone)] #[cfg_attr(feature = "ser", derive(serde::Serialize))] diff --git a/src/scoring.rs b/src/scoring.rs index 6a9e0fd..db516af 100644 --- a/src/scoring.rs +++ b/src/scoring.rs @@ -77,7 +77,7 @@ lazy_static! { pub(crate) static ref REFERENCE_YEAR: i32 = time::OffsetDateTime::now_utc().year(); } -#[cfg(target_arch = "wasm32")] +#[cfg(all(target_arch = "wasm32", not(feature = "non-js")))] lazy_static! { pub(crate) static ref REFERENCE_YEAR: i32 = web_sys::js_sys::Date::new_0() .get_full_year() @@ -85,6 +85,22 @@ lazy_static! { .unwrap(); } +#[cfg(all(target_arch = "wasm32", feature = "non-js"))] +lazy_static! { + pub(crate) static ref REFERENCE_YEAR: i32 = { + #[link(wasm_import_module = "zxcvbn")] + extern "C" { + fn unix_time_milliseconds_imported() -> u64; + } + let unix_millis = unsafe { + unix_time_milliseconds_imported() + }; + + use chrono::Datelike; + chrono::DateTime::::from(std::time::SystemTime::UNIX_EPOCH + std::time::Duration::from_millis(unix_millis)).year() + }; +} + const MIN_YEAR_SPACE: i32 = 20; const BRUTEFORCE_CARDINALITY: u64 = 10; const MIN_GUESSES_BEFORE_GROWING_SEQUENCE: u64 = 10_000; From ebd2748f60fc2caf44fc82ada7ad333d6eea425b Mon Sep 17 00:00:00 2001 From: Horia Culea Date: Mon, 3 Jun 2024 13:29:24 +0200 Subject: [PATCH 2/6] Cleanup dependencies in WASM targets --- Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ce2c87f..e05026e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,9 +20,9 @@ itertools = "0.13" lazy_static = "1.3" regex = "1" time = { version = "0.3" } -chrono = "0.4" -[target.'cfg(all(target_arch = "wasm32", not(feature = "non-js")))'.dependencies] +[target.'cfg(target_arch = "wasm32")'.dependencies] +chrono = "0.4.38" wasm-bindgen = "0.2" web-sys = { version = "0.3", features = ["Performance"] } From 1f39c26a8a4f2474ce7766b9749709f7314695cf Mon Sep 17 00:00:00 2001 From: Horia Culea Date: Mon, 3 Jun 2024 13:49:29 +0200 Subject: [PATCH 3/6] Rename feature for better conveying the intention --- Cargo.toml | 4 ++-- src/feedback.rs | 2 +- src/lib.rs | 6 +++--- src/scoring.rs | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index e05026e..0280955 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,7 +39,7 @@ serde_json = "1" criterion = "0.5" serde_json = "1" -[target.'cfg(all(target_arch = "wasm32", not(feature = "non-js")))'.dev-dependencies] +[target.'cfg(target_arch = "wasm32")'.dev-dependencies] criterion = { version = "0.5", default-features = false } wasm-bindgen-test = "0.3" @@ -47,7 +47,7 @@ wasm-bindgen-test = "0.3" default = ["builder"] ser = ["serde"] builder = ["derive_builder"] -non-js = [] +custom_wasm_env = [] [profile.test] opt-level = 2 diff --git a/src/feedback.rs b/src/feedback.rs index 6821837..4391aac 100644 --- a/src/feedback.rs +++ b/src/feedback.rs @@ -292,7 +292,7 @@ fn get_dictionary_match_feedback( mod tests { use super::*; - #[cfg(all(target_arch = "wasm32", not(feature = "non-js")))] + #[cfg(all(target_arch = "wasm32", not(feature = "custom_wasm_env")))] use wasm_bindgen_test::wasm_bindgen_test; #[cfg_attr(not(target_arch = "wasm32"), test)] diff --git a/src/lib.rs b/src/lib.rs index 2c22f51..a813735 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -17,7 +17,7 @@ extern crate quickcheck; pub use scoring::Score; use time_estimates::CrackTimes; -#[cfg(all(target_arch = "wasm32", not(feature = "non-js")))] +#[cfg(all(target_arch = "wasm32", not(feature = "custom_wasm_env")))] use wasm_bindgen::prelude::wasm_bindgen; pub use crate::matching::Match; @@ -41,7 +41,7 @@ where (result, calc_time) } -#[cfg(all(target_arch = "wasm32", not(feature = "non-js")))] +#[cfg(all(target_arch = "wasm32", not(feature = "custom_wasm_env")))] #[allow(non_upper_case_globals)] fn time_scoped(f: F) -> (R, Duration) where @@ -60,7 +60,7 @@ where (result, calc_time) } -#[cfg(all(target_arch = "wasm32", feature = "non-js"))] +#[cfg(all(target_arch = "wasm32", feature = "custom_wasm_env"))] fn time_scoped(f: F) -> (R, Duration) where F: FnOnce() -> R, diff --git a/src/scoring.rs b/src/scoring.rs index db516af..c5f18c2 100644 --- a/src/scoring.rs +++ b/src/scoring.rs @@ -77,7 +77,7 @@ lazy_static! { pub(crate) static ref REFERENCE_YEAR: i32 = time::OffsetDateTime::now_utc().year(); } -#[cfg(all(target_arch = "wasm32", not(feature = "non-js")))] +#[cfg(all(target_arch = "wasm32", not(feature = "custom_wasm_env")))] lazy_static! { pub(crate) static ref REFERENCE_YEAR: i32 = web_sys::js_sys::Date::new_0() .get_full_year() @@ -85,7 +85,7 @@ lazy_static! { .unwrap(); } -#[cfg(all(target_arch = "wasm32", feature = "non-js"))] +#[cfg(all(target_arch = "wasm32", feature = "custom_wasm_env"))] lazy_static! { pub(crate) static ref REFERENCE_YEAR: i32 = { #[link(wasm_import_module = "zxcvbn")] From 0b6a2ed0abce0a07fbdb5e08f831a9396564ef5c Mon Sep 17 00:00:00 2001 From: Horia Culea Date: Wed, 19 Jun 2024 09:43:13 +0200 Subject: [PATCH 4/6] Run cargo fmt and add getrandom as dev dependency --- Cargo.toml | 1 + src/lib.rs | 8 ++------ src/scoring.rs | 9 +++++---- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 0280955..c428742 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,6 +41,7 @@ serde_json = "1" [target.'cfg(target_arch = "wasm32")'.dev-dependencies] criterion = { version = "0.5", default-features = false } +getrandom = { version = "0.2", features = ["js"] } wasm-bindgen-test = "0.3" [features] diff --git a/src/lib.rs b/src/lib.rs index a813735..3fe8cd5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -69,13 +69,9 @@ where extern "C" { fn unix_time_milliseconds_imported() -> u64; } - let start_time = unsafe { - unix_time_milliseconds_imported() - }; + let start_time = unsafe { unix_time_milliseconds_imported() }; let result = f(); - let end_time = unsafe { - unix_time_milliseconds_imported() - }; + let end_time = unsafe { unix_time_milliseconds_imported() }; let duration = std::time::Duration::from_millis(end_time - start_time); (result, duration) diff --git a/src/scoring.rs b/src/scoring.rs index c5f18c2..c11c58d 100644 --- a/src/scoring.rs +++ b/src/scoring.rs @@ -92,12 +92,13 @@ lazy_static! { extern "C" { fn unix_time_milliseconds_imported() -> u64; } - let unix_millis = unsafe { - unix_time_milliseconds_imported() - }; + let unix_millis = unsafe { unix_time_milliseconds_imported() }; use chrono::Datelike; - chrono::DateTime::::from(std::time::SystemTime::UNIX_EPOCH + std::time::Duration::from_millis(unix_millis)).year() + chrono::DateTime::::from( + std::time::SystemTime::UNIX_EPOCH + std::time::Duration::from_millis(unix_millis), + ) + .year() }; } From 70f524c9c6002107eb2008fe6817acd55845b415 Mon Sep 17 00:00:00 2001 From: AndyTitu Date: Tue, 25 Jun 2024 13:49:00 +0200 Subject: [PATCH 5/6] Revert feature conditional cfg in tests --- src/feedback.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/feedback.rs b/src/feedback.rs index 4391aac..ebd4eca 100644 --- a/src/feedback.rs +++ b/src/feedback.rs @@ -292,7 +292,7 @@ fn get_dictionary_match_feedback( mod tests { use super::*; - #[cfg(all(target_arch = "wasm32", not(feature = "custom_wasm_env")))] + #[cfg(target_arch = "wasm32")] use wasm_bindgen_test::wasm_bindgen_test; #[cfg_attr(not(target_arch = "wasm32"), test)] From d7efabd096944bdc0b5e79f4d62dfb35117c0b3f Mon Sep 17 00:00:00 2001 From: AndyTitu Date: Fri, 5 Jul 2024 17:00:56 +0300 Subject: [PATCH 6/6] Make sure wasm-pack only runs features that are compatible with wasm-bindgen --- .github/workflows/zxcvbn.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/zxcvbn.yml b/.github/workflows/zxcvbn.yml index 8ab2748..129ec90 100644 --- a/.github/workflows/zxcvbn.yml +++ b/.github/workflows/zxcvbn.yml @@ -96,4 +96,6 @@ jobs: run: cargo build --target wasm32-unknown-unknown --tests --benches - name: Run tests (wasm, all features) - run: wasm-pack test --node --all-features + env: + ALL_WASM_BINDGEN_FEATURES: "default,ser,builder" + run: wasm-pack test --node --features $ALL_WASM_BINDGEN_FEATURES