From c84be2776305d82b7a83db54cbbe1762f792ac4d Mon Sep 17 00:00:00 2001 From: Truman Kilen Date: Sat, 16 Dec 2023 18:47:31 -0600 Subject: [PATCH] Don't store oodle as a global --- oodle_loader/src/lib.rs | 6 +++--- repak/Cargo.toml | 3 ++- repak/src/entry.rs | 12 +++++++----- repak/src/lib.rs | 23 ++++++++++++----------- repak/src/pak.rs | 23 +++++++++++++---------- 5 files changed, 37 insertions(+), 30 deletions(-) diff --git a/oodle_loader/src/lib.rs b/oodle_loader/src/lib.rs index 58f2165..314848e 100644 --- a/oodle_loader/src/lib.rs +++ b/oodle_loader/src/lib.rs @@ -22,11 +22,11 @@ type OodleLZ_Decompress = unsafe extern "win64" fn( threadPhase: u32, ) -> i32; -pub fn decompress() -> OodleDecompress { +pub fn decompress() -> Result> { #[cfg(windows)] - return windows_oodle::decompress_wrapper_windows; + return Ok(windows_oodle::decompress_wrapper_windows); #[cfg(unix)] - return linux_oodle::oodle_loader_linux(); + return Ok(linux_oodle::oodle_loader_linux()); } fn call_decompress(comp_buf: &[u8], raw_buf: &mut [u8], decompress: OodleLZ_Decompress) -> i32 { diff --git a/repak/Cargo.toml b/repak/Cargo.toml index 45d5dd4..38fce10 100644 --- a/repak/Cargo.toml +++ b/repak/Cargo.toml @@ -10,6 +10,7 @@ edition.workspace = true default = ["compression", "encryption"] compression = ["dep:flate2", "dep:zstd"] oodle = [] +oodle_loader = ["dep:oodle_loader"] encryption = ["dep:aes"] [dependencies] @@ -17,10 +18,10 @@ byteorder = "1.4" aes = { workspace = true, optional = true } flate2 = { version = "1.0", optional = true } zstd = { version = "0.12", optional = true } +oodle_loader = { path = "../oodle_loader", optional = true} thiserror = "1.0" sha1 = { workspace = true } strum = { workspace = true } -once_cell = "1.18" [dev-dependencies] base64 = { workspace = true } diff --git a/repak/src/entry.rs b/repak/src/entry.rs index 2d7af3b..04e47f4 100644 --- a/repak/src/entry.rs +++ b/repak/src/entry.rs @@ -306,6 +306,7 @@ impl Entry { version: Version, compression: &[Compression], #[allow(unused)] key: &super::Key, + #[allow(unused)] oodle: &super::Oodle, buf: &mut W, ) -> Result<(), super::Error> { reader.seek(io::SeekFrom::Start(self.offset))?; @@ -375,10 +376,11 @@ impl Entry { } } #[cfg(feature = "oodle")] - Some(Compression::Oodle) => unsafe { - let Some(ref oodle) = super::OODLE else { - return Err(super::Error::OodleFailed); - }; + Some(Compression::Oodle) => { + let oodle = match oodle { + crate::Oodle::Some(getter) => getter().map_err(|_| super::Error::OodleFailed), + crate::Oodle::None => Err(super::Error::OodleFailed), + }?; let mut decompressed = vec![0; self.uncompressed as usize]; let mut compress_offset = 0; @@ -408,7 +410,7 @@ impl Entry { "Oodle decompression length mismatch" ); buf.write_all(&decompressed)?; - }, + } #[cfg(not(feature = "oodle"))] Some(Compression::Oodle) => return Err(super::Error::Oodle), #[cfg(not(feature = "compression"))] diff --git a/repak/src/lib.rs b/repak/src/lib.rs index 37ec9a5..159c06e 100644 --- a/repak/src/lib.rs +++ b/repak/src/lib.rs @@ -10,10 +10,13 @@ pub use {error::*, pak::*}; pub const MAGIC: u32 = 0x5A6F12E1; #[cfg(feature = "oodle")] -static mut OODLE: Option> = None; +mod oodle { + pub type OodleGetter = fn() -> Result>; + pub type OodleDecompress = fn(comp_buf: &[u8], raw_buf: &mut [u8]) -> i32; +} -#[cfg(feature = "oodle")] -type OodleDecompress = fn(comp_buf: &[u8], raw_buf: &mut [u8]) -> i32; +#[cfg(feature = "oodle_loader")] +pub use oodle_loader; #[derive( Clone, @@ -127,10 +130,11 @@ pub enum Compression { } #[allow(clippy::large_enum_variant)] -#[derive(Debug)] +#[derive(Debug, Default)] pub(crate) enum Key { #[cfg(feature = "encryption")] Some(aes::Aes256), + #[default] None, } @@ -141,13 +145,10 @@ impl From for Key { } } -#[cfg(feature = "oodle")] -pub(crate) enum Oodle<'func> { - Some(&'func OodleDecompress), - None, -} - -#[cfg(not(feature = "oodle"))] +#[derive(Debug, Default)] pub(crate) enum Oodle { + #[cfg(feature = "oodle")] + Some(oodle::OodleGetter), + #[default] None, } diff --git a/repak/src/pak.rs b/repak/src/pak.rs index ccbf49b..dac7b85 100644 --- a/repak/src/pak.rs +++ b/repak/src/pak.rs @@ -4,16 +4,15 @@ use byteorder::{ReadBytesExt, WriteBytesExt, LE}; use std::collections::BTreeMap; use std::io::{self, Read, Seek, Write}; -#[derive(Debug)] +#[derive(Debug, Default)] pub struct PakBuilder { key: super::Key, + oodle: super::Oodle, } impl PakBuilder { pub fn new() -> Self { - Self { - key: super::Key::None, - } + Self::default() } #[cfg(feature = "encryption")] pub fn key(mut self, key: aes::Aes256) -> Self { @@ -21,19 +20,19 @@ impl PakBuilder { self } #[cfg(feature = "oodle")] - pub fn oodle(self, oodle: fn() -> super::OodleDecompress) -> Self { - unsafe { super::OODLE = Some(once_cell::sync::Lazy::new(oodle)) } + pub fn oodle(mut self, oodle_getter: super::oodle::OodleGetter) -> Self { + self.oodle = super::Oodle::Some(oodle_getter); self } pub fn reader(self, reader: &mut R) -> Result { - PakReader::new_any_inner(reader, self.key) + PakReader::new_any_inner(reader, self.key, self.oodle) } pub fn reader_with_version( self, reader: &mut R, version: super::Version, ) -> Result { - PakReader::new_inner(reader, version, self.key) + PakReader::new_inner(reader, version, self.key, self.oodle) } pub fn writer( self, @@ -50,6 +49,7 @@ impl PakBuilder { pub struct PakReader { pak: Pak, key: super::Key, + oodle: super::Oodle, } #[derive(Debug)] @@ -128,13 +128,14 @@ impl PakReader { fn new_any_inner( reader: &mut R, key: super::Key, + oodle: super::Oodle, ) -> Result { use std::fmt::Write; let mut log = "\n".to_owned(); for ver in Version::iter() { match Pak::read(&mut *reader, ver, &key) { - Ok(pak) => return Ok(Self { pak, key }), + Ok(pak) => return Ok(Self { pak, key, oodle }), Err(err) => writeln!(log, "trying version {} failed: {}", ver, err)?, } } @@ -145,8 +146,9 @@ impl PakReader { reader: &mut R, version: super::Version, key: super::Key, + oodle: super::Oodle, ) -> Result { - Pak::read(reader, version, &key).map(|pak| Self { pak, key }) + Pak::read(reader, version, &key).map(|pak| Self { pak, key, oodle }) } pub fn version(&self) -> super::Version { @@ -183,6 +185,7 @@ impl PakReader { self.pak.version, &self.pak.compression, &self.key, + &self.oodle, writer, ), None => Err(super::Error::MissingEntry(path.to_owned())),