From 1a6b54ac34c9b03ab1eab069d464c5475fa2adeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kat=20March=C3=A1n?= Date: Fri, 29 Sep 2023 13:58:57 -0700 Subject: [PATCH] fix(unsafe): use safe version of method that verifies data. No perf impact noticeable --- crates/nassun/src/error.rs | 5 +++++ crates/nassun/src/package.rs | 30 ++++++++++++++---------------- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/crates/nassun/src/error.rs b/crates/nassun/src/error.rs index 0709ad82..5c91c1a8 100644 --- a/crates/nassun/src/error.rs +++ b/crates/nassun/src/error.rs @@ -165,6 +165,11 @@ pub enum NassunError { #[diagnostic(code(nassun::cache::serialize), url(docsrs))] SerializeCacheError(String), + /// An error happened while deserializing cache metadata. + #[error("Failed to deserialize cache metadata: {0}")] + #[diagnostic(code(nassun::cache::deserialize), url(docsrs))] + DeserializeCacheError(String), + /// A miscellaneous, usually internal error. This is used mainly to wrap /// either manual InternalErrors, or those using external errors that /// don't implement std::error::Error. diff --git a/crates/nassun/src/package.rs b/crates/nassun/src/package.rs index 9221b9ca..0e3e1811 100644 --- a/crates/nassun/src/package.rs +++ b/crates/nassun/src/package.rs @@ -246,14 +246,13 @@ impl Package { let name = self.name().to_owned(); async_std::task::spawn_blocking(move || { let mut created = std::collections::HashSet::new(); - let index = unsafe { - rkyv::util::archived_root::( - entry - .raw_metadata - .as_ref() - .ok_or_else(|| NassunError::CacheMissingIndexError(name))?, - ) - }; + let index = rkyv::check_archived_root::( + entry + .raw_metadata + .as_ref() + .ok_or_else(|| NassunError::CacheMissingIndexError(name))?, + ) + .map_err(|e| NassunError::DeserializeCacheError(e.to_string()))?; prefer_copy = index.should_copy || prefer_copy; for (path, (sri, mode)) in index.files.iter() { let sri: Integrity = sri.parse()?; @@ -299,14 +298,13 @@ impl fmt::Debug for Package { #[cfg(not(target_arch = "wasm32"))] fn clean_from_cache(cache: &Path, sri: &Integrity, entry: cacache::Metadata) -> Result<()> { - let index = unsafe { - rkyv::util::archived_root::( - entry - .raw_metadata - .as_ref() - .ok_or_else(|| NassunError::CacheMissingIndexError("".into()))?, - ) - }; + let index = rkyv::check_archived_root::( + entry + .raw_metadata + .as_ref() + .ok_or_else(|| NassunError::CacheMissingIndexError("".into()))?, + ) + .map_err(|e| NassunError::DeserializeCacheError(e.to_string()))?; for (sri, _) in index.files.values() { let sri: Integrity = sri.as_str().parse()?; match cacache::remove_hash_sync(cache, &sri) {