diff --git a/Cargo.lock b/Cargo.lock index c008ce3..3220615 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -169,6 +169,12 @@ dependencies = [ "windows-link", ] +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + [[package]] name = "benchmarks" version = "0.1.0" @@ -3776,6 +3782,7 @@ dependencies = [ name = "ytbn_graphing_software" version = "0.1.0" dependencies = [ + "base64", "benchmarks", "bincode", "cfg-if", diff --git a/Cargo.toml b/Cargo.toml index b602597..a005e90 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -56,6 +56,7 @@ itertools = "0.10" static_assertions = "1.1" bincode = "1.3" serde = "1" +base64 = "0.21" [dev-dependencies] benchmarks = { path = "./benchmarks" } diff --git a/src/math_app.rs b/src/math_app.rs index ed16f5d..08e8758 100644 --- a/src/math_app.rs +++ b/src/math_app.rs @@ -150,10 +150,9 @@ impl MathApp { let data = get_localstorage().get_item(DATA_NAME).ok()??; let (commit, cached_data) = crate::misc::hashed_storage_read(&data)?; - if commit == unsafe { std::mem::transmute::<&str, crate::misc::HashBytes>(build::SHORT_COMMIT) } { tracing::info!("Reading decompression cache. Bytes: {}", cached_data.len()); - return Some(cached_data.to_vec()); + return Some(cached_data); } else { None } @@ -161,14 +160,8 @@ impl MathApp { fn load_functions() -> Option { let data = get_localstorage().get_item(FUNC_NAME).ok()??; - if crate::misc::HASH_LENGTH >= data.len() { - return None; - } - - // TODO: stabilize FunctionManager serialize so it can persist across builds let (commit, func_data) = crate::misc::hashed_storage_read(&data)?; - if commit == unsafe { std::mem::transmute::<&str, &[u8]>(build::SHORT_COMMIT) } { tracing::info!("Reading previous function data"); let function_manager: FunctionManager = bincode::deserialize(&func_data).ok()?; diff --git a/src/misc.rs b/src/misc.rs index 3f8bd89..b9fa289 100644 --- a/src/misc.rs +++ b/src/misc.rs @@ -1,3 +1,4 @@ +use base64::{engine::general_purpose, Engine as _}; use egui_plot::{Line, PlotPoint, PlotPoints, Points}; use emath::Pos2; use getrandom::getrandom; @@ -165,24 +166,27 @@ pub type HashBytes = [u8; HASH_LENGTH]; #[allow(dead_code)] pub fn hashed_storage_create(hashbytes: HashBytes, data: &[u8]) -> String { - unsafe { std::mem::transmute::, String>([hashbytes.to_vec(), data.to_vec()].concat()) } + let combined_data = [hashbytes.to_vec(), data.to_vec()].concat(); + general_purpose::STANDARD.encode(combined_data) } #[allow(dead_code)] -pub fn hashed_storage_read(data: &str) -> Option<(HashBytes, &[u8])> { +pub fn hashed_storage_read(data: &str) -> Option<(HashBytes, Vec)> { + // Decode base64 data + let decoded_bytes = general_purpose::STANDARD.decode(data).ok()?; + // Make sure data is long enough to decode - if HASH_LENGTH >= data.len() { + if HASH_LENGTH > decoded_bytes.len() { return None; } - // Transmute data into slice - let decoded_1: &[u8] = unsafe { std::mem::transmute::<&str, &[u8]>(data) }; + // Split hash and data + let (hash_bytes, data_bytes) = decoded_bytes.split_at(HASH_LENGTH); - // Return hash and decoded data - Some(( - unsafe { *(decoded_1[..HASH_LENGTH].as_ptr() as *const HashBytes) }, - &decoded_1[HASH_LENGTH..], - )) + // Convert hash bytes to HashBytes + let hash: HashBytes = hash_bytes.try_into().ok()?; + + Some((hash, data_bytes.to_vec())) } /// Creates and returns random u64