use Key enum to reduce cfg attributes used

This commit is contained in:
spuds 2023-08-27 19:46:36 +01:00
parent 7004e1c203
commit 50f54837ca
No known key found for this signature in database
GPG key ID: 0B6CA6068E827C8F
4 changed files with 50 additions and 62 deletions

View file

@ -3,13 +3,13 @@ use byteorder::{ReadBytesExt, WriteBytesExt, LE};
use std::io; use std::io;
#[derive(Debug, PartialEq, Clone, Copy)] #[derive(Debug, PartialEq, Clone, Copy)]
pub enum EntryLocation { pub(crate) enum EntryLocation {
Data, Data,
Index, Index,
} }
#[derive(Debug)] #[derive(Debug)]
pub struct Block { pub(crate) struct Block {
pub start: u64, pub start: u64,
pub end: u64, pub end: u64,
} }
@ -35,7 +35,7 @@ fn align(offset: u64) -> u64 {
} }
#[derive(Debug)] #[derive(Debug)]
pub struct Entry { pub(crate) struct Entry {
pub offset: u64, pub offset: u64,
pub compressed: u64, pub compressed: u64,
pub uncompressed: u64, pub uncompressed: u64,
@ -311,7 +311,7 @@ impl Entry {
reader: &mut R, reader: &mut R,
version: Version, version: Version,
compression: &[Compression], compression: &[Compression],
#[cfg(feature = "encryption")] key: Option<&aes::Aes256>, key: &super::Key,
buf: &mut W, buf: &mut W,
) -> Result<(), super::Error> { ) -> Result<(), super::Error> {
reader.seek(io::SeekFrom::Start(self.offset))?; reader.seek(io::SeekFrom::Start(self.offset))?;
@ -328,7 +328,7 @@ impl Entry {
return Err(super::Error::Encryption); return Err(super::Error::Encryption);
#[cfg(feature = "encryption")] #[cfg(feature = "encryption")]
{ {
let Some(key) = key else { let super::Key::Some(key) = key else {
return Err(super::Error::Encrypted); return Err(super::Error::Encrypted);
}; };
use aes::cipher::BlockDecrypt; use aes::cipher::BlockDecrypt;
@ -423,6 +423,7 @@ impl Entry {
*/ */
#[allow(non_snake_case)] #[allow(non_snake_case)]
#[allow(clippy::type_complexity)]
let OodleLZ_Decompress: libloading::Symbol< let OodleLZ_Decompress: libloading::Symbol<
extern "C" fn( extern "C" fn(
compBuf: *mut u8, compBuf: *mut u8,

View file

@ -122,3 +122,21 @@ pub enum Compression {
Oodle, Oodle,
Zstd, Zstd,
} }
#[allow(clippy::large_enum_variant)]
#[derive(Debug)]
pub(crate) enum Key {
#[cfg(feature = "encryption")]
Some(aes::Aes256),
None,
}
impl From<Option<aes::Aes256>> for Key {
fn from(value: Option<aes::Aes256>) -> Self {
match value {
#[cfg(feature = "encryption")]
Some(key) => Self::Some(key),
_ => Self::None,
}
}
}

View file

@ -1,7 +1,5 @@
use super::ext::{ReadExt, WriteExt}; use super::ext::{ReadExt, WriteExt};
use super::{Version, VersionMajor}; use super::{Version, VersionMajor};
#[cfg(feature = "encryption")]
use aes::Aes256;
use byteorder::{ReadBytesExt, WriteBytesExt, LE}; use byteorder::{ReadBytesExt, WriteBytesExt, LE};
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::io::{self, Read, Seek, Write}; use std::io::{self, Read, Seek, Write};
@ -9,20 +7,18 @@ use std::io::{self, Read, Seek, Write};
#[derive(Debug)] #[derive(Debug)]
pub struct PakReader { pub struct PakReader {
pak: Pak, pak: Pak,
#[cfg(feature = "encryption")] key: super::Key,
key: Option<aes::Aes256>,
} }
#[derive(Debug)] #[derive(Debug)]
pub struct PakWriter<W: Write + Seek> { pub struct PakWriter<W: Write + Seek> {
pak: Pak, pak: Pak,
writer: W, writer: W,
#[cfg(feature = "encryption")] key: super::Key,
key: Option<aes::Aes256>,
} }
#[derive(Debug)] #[derive(Debug)]
pub struct Pak { pub(crate) struct Pak {
version: Version, version: Version,
mount_point: String, mount_point: String,
index_offset: Option<u64>, index_offset: Option<u64>,
@ -47,7 +43,7 @@ impl Pak {
} }
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct Index { pub(crate) struct Index {
path_hash_seed: Option<u64>, path_hash_seed: Option<u64>,
entries: BTreeMap<String, super::entry::Entry>, entries: BTreeMap<String, super::entry::Entry>,
} }
@ -74,8 +70,8 @@ impl Index {
} }
#[cfg(feature = "encryption")] #[cfg(feature = "encryption")]
fn decrypt(key: Option<&aes::Aes256>, bytes: &mut [u8]) -> Result<(), super::Error> { fn decrypt(key: &super::Key, bytes: &mut [u8]) -> Result<(), super::Error> {
if let Some(key) = key { if let super::Key::Some(key) = key {
use aes::cipher::BlockDecrypt; use aes::cipher::BlockDecrypt;
for chunk in bytes.chunks_mut(16) { for chunk in bytes.chunks_mut(16) {
key.decrypt_block(aes::Block::from_mut_slice(chunk)) key.decrypt_block(aes::Block::from_mut_slice(chunk))
@ -89,7 +85,7 @@ fn decrypt(key: Option<&aes::Aes256>, bytes: &mut [u8]) -> Result<(), super::Err
impl PakReader { impl PakReader {
#[cfg(not(feature = "encryption"))] #[cfg(not(feature = "encryption"))]
pub fn new_any<R: Read + Seek>(reader: &mut R) -> Result<Self, super::Error> { pub fn new_any<R: Read + Seek>(reader: &mut R) -> Result<Self, super::Error> {
Self::new_any_inner(reader) Self::new_any_inner(reader, super::Key::None)
} }
#[cfg(feature = "encryption")] #[cfg(feature = "encryption")]
@ -97,30 +93,19 @@ impl PakReader {
reader: &mut R, reader: &mut R,
key: Option<aes::Aes256>, key: Option<aes::Aes256>,
) -> Result<Self, super::Error> { ) -> Result<Self, super::Error> {
Self::new_any_inner(reader, key) Self::new_any_inner(reader, key.into())
} }
fn new_any_inner<R: Read + Seek>( fn new_any_inner<R: Read + Seek>(
reader: &mut R, reader: &mut R,
#[cfg(feature = "encryption")] key: Option<aes::Aes256>, key: super::Key,
) -> Result<Self, super::Error> { ) -> Result<Self, super::Error> {
use std::fmt::Write; use std::fmt::Write;
let mut log = "\n".to_owned(); let mut log = "\n".to_owned();
for ver in Version::iter() { for ver in Version::iter() {
match Pak::read( match Pak::read(&mut *reader, ver, &key) {
&mut *reader, Ok(pak) => return Ok(Self { pak, key }),
ver,
#[cfg(feature = "encryption")]
key.as_ref(),
) {
Ok(pak) => {
return Ok(Self {
pak,
#[cfg(feature = "encryption")]
key,
})
}
Err(err) => writeln!(log, "trying version {} failed: {}", ver, err)?, Err(err) => writeln!(log, "trying version {} failed: {}", ver, err)?,
} }
} }
@ -141,25 +126,15 @@ impl PakReader {
version: super::Version, version: super::Version,
key: Option<aes::Aes256>, key: Option<aes::Aes256>,
) -> Result<Self, super::Error> { ) -> Result<Self, super::Error> {
Self::new_inner(reader, version, key) Self::new_inner(reader, version, key.into())
} }
fn new_inner<R: Read + Seek>( fn new_inner<R: Read + Seek>(
reader: &mut R, reader: &mut R,
version: super::Version, version: super::Version,
#[cfg(feature = "encryption")] key: Option<aes::Aes256>, key: super::Key,
) -> Result<Self, super::Error> { ) -> Result<Self, super::Error> {
Pak::read( Pak::read(reader, version, &key).map(|pak| Self { pak, key })
reader,
version,
#[cfg(feature = "encryption")]
key.as_ref(),
)
.map(|pak| Self {
pak,
#[cfg(feature = "encryption")]
key,
})
} }
pub fn version(&self) -> super::Version { pub fn version(&self) -> super::Version {
@ -195,8 +170,7 @@ impl PakReader {
reader, reader,
self.pak.version, self.pak.version,
&self.pak.compression, &self.pak.compression,
#[cfg(feature = "encryption")] &self.key,
self.key.as_ref(),
writer, writer,
), ),
None => Err(super::Error::MissingEntry(path.to_owned())), None => Err(super::Error::MissingEntry(path.to_owned())),
@ -214,7 +188,6 @@ impl PakReader {
writer.seek(io::SeekFrom::Start(self.pak.index_offset.unwrap()))?; writer.seek(io::SeekFrom::Start(self.pak.index_offset.unwrap()))?;
Ok(PakWriter { Ok(PakWriter {
pak: self.pak, pak: self.pak,
#[cfg(feature = "encryption")]
key: self.key, key: self.key,
writer, writer,
}) })
@ -232,6 +205,7 @@ impl<W: Write + Seek> PakWriter<W> {
PakWriter { PakWriter {
pak: Pak::new(version, mount_point, path_hash_seed), pak: Pak::new(version, mount_point, path_hash_seed),
writer, writer,
key: super::Key::None,
} }
} }
@ -246,13 +220,13 @@ impl<W: Write + Seek> PakWriter<W> {
PakWriter { PakWriter {
pak: Pak::new(version, mount_point, path_hash_seed), pak: Pak::new(version, mount_point, path_hash_seed),
writer, writer,
key, key: key.into(),
} }
} }
fn new_inner( fn new_inner(
writer: W, writer: W,
#[cfg(feature = "encryption")] key: Option<aes::Aes256>, key: super::Key,
version: Version, version: Version,
mount_point: String, mount_point: String,
path_hash_seed: Option<u64>, path_hash_seed: Option<u64>,
@ -260,7 +234,6 @@ impl<W: Write + Seek> PakWriter<W> {
PakWriter { PakWriter {
pak: Pak::new(version, mount_point, path_hash_seed), pak: Pak::new(version, mount_point, path_hash_seed),
writer, writer,
#[cfg(feature = "encryption")]
key, key,
} }
} }
@ -305,11 +278,7 @@ impl<W: Write + Seek> PakWriter<W> {
} }
pub fn write_index(mut self) -> Result<W, super::Error> { pub fn write_index(mut self) -> Result<W, super::Error> {
self.pak.write( self.pak.write(&mut self.writer, &self.key)?;
&mut self.writer,
#[cfg(feature = "encryption")]
self.key,
)?;
Ok(self.writer) Ok(self.writer)
} }
} }
@ -318,7 +287,7 @@ impl Pak {
fn read<R: Read + Seek>( fn read<R: Read + Seek>(
reader: &mut R, reader: &mut R,
version: super::Version, version: super::Version,
#[cfg(feature = "encryption")] key: Option<&aes::Aes256>, key: &super::Key,
) -> Result<Self, super::Error> { ) -> Result<Self, super::Error> {
// read footer to get index, encryption & compression info // read footer to get index, encryption & compression info
reader.seek(io::SeekFrom::End(-version.size()))?; reader.seek(io::SeekFrom::End(-version.size()))?;
@ -468,7 +437,7 @@ impl Pak {
fn write<W: Write + Seek>( fn write<W: Write + Seek>(
&self, &self,
writer: &mut W, writer: &mut W,
#[cfg(feature = "encryption")] _key: Option<aes::Aes256>, _key: &super::Key,
) -> Result<(), super::Error> { ) -> Result<(), super::Error> {
let index_offset = writer.stream_position()?; let index_offset = writer.stream_position()?;
@ -696,7 +665,7 @@ fn pad_zeros_to_alignment(v: &mut Vec<u8>, alignment: usize) {
} }
#[cfg(feature = "encryption")] #[cfg(feature = "encryption")]
fn encrypt(key: Aes256, bytes: &mut [u8]) { fn encrypt(key: aes::Aes256, bytes: &mut [u8]) {
use aes::cipher::BlockEncrypt; use aes::cipher::BlockEncrypt;
for chunk in bytes.chunks_mut(16) { for chunk in bytes.chunks_mut(16) {
key.encrypt_block(aes::Block::from_mut_slice(chunk)) key.encrypt_block(aes::Block::from_mut_slice(chunk))

View file

@ -96,7 +96,7 @@ fn test_read(version: repak::Version, _file_name: &str, bytes: &[u8]) {
let len = inner_reader.seek(SeekFrom::End(0)).unwrap(); let len = inner_reader.seek(SeekFrom::End(0)).unwrap();
let mut reader = ReadCounter::new_size(inner_reader, len as usize); let mut reader = ReadCounter::new_size(inner_reader, len as usize);
let pak = repak::PakReader::new_any(&mut reader, Some(key)).unwrap(); let pak = repak::PakReader::new_any_with_key(&mut reader, Some(key)).unwrap();
assert_eq!(pak.mount_point(), "../mount/point/root/"); assert_eq!(pak.mount_point(), "../mount/point/root/");
assert_eq!(pak.version(), version); assert_eq!(pak.version(), version);
@ -159,10 +159,10 @@ fn test_write(_version: repak::Version, _file_name: &str, bytes: &[u8]) {
.unwrap(); .unwrap();
let mut reader = std::io::Cursor::new(bytes); let mut reader = std::io::Cursor::new(bytes);
let pak_reader = repak::PakReader::new_any(&mut reader, Some(key)).unwrap(); let pak_reader = repak::PakReader::new_any_with_key(&mut reader, Some(key)).unwrap();
let writer = Cursor::new(vec![]); let writer = Cursor::new(vec![]);
let mut pak_writer = repak::PakWriter::new( let mut pak_writer = repak::PakWriter::new_with_key(
writer, writer,
None, None,
pak_reader.version(), pak_reader.version(),
@ -191,7 +191,7 @@ fn test_rewrite_index(_version: repak::Version, _file_name: &str, bytes: &[u8])
.unwrap(); .unwrap();
let mut buf = std::io::Cursor::new(bytes.to_vec()); let mut buf = std::io::Cursor::new(bytes.to_vec());
let pak_reader = repak::PakReader::new_any(&mut buf, Some(key)).unwrap(); let pak_reader = repak::PakReader::new_any_with_key(&mut buf, Some(key)).unwrap();
let rewrite = pak_reader let rewrite = pak_reader
.into_pakwriter(buf) .into_pakwriter(buf)