From 9c0e544e79a4f7874dab449674a11d899bf61963 Mon Sep 17 00:00:00 2001 From: Igor Tolmachev Date: Tue, 16 Jul 2024 20:08:01 +0900 Subject: Add tests and fix bugs --- src/error.rs | 9 +++++++++ src/utils/read.rs | 4 ++-- src/zip/driver.rs | 20 ++++++++++---------- src/zip/encryption.rs | 2 +- src/zip/error.rs | 6 +++--- 5 files changed, 25 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/error.rs b/src/error.rs index 97a4e62..518b0e9 100644 --- a/src/error.rs +++ b/src/error.rs @@ -17,6 +17,15 @@ impl From for ArchiveError { } } +impl PartialEq for ArchiveError { + fn eq(&self, other: &E) -> bool { + match self { + Self::Archivator { error, .. } => error == other, + _ => false, + } + } +} + impl Display for ArchiveError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { diff --git a/src/utils/read.rs b/src/utils/read.rs index 185758a..491c89c 100644 --- a/src/utils/read.rs +++ b/src/utils/read.rs @@ -10,14 +10,14 @@ impl ReadUtils for R { #[inline] fn read_arr(&mut self) -> Result<[u8; S], std::io::Error> { let mut arr = [0; S]; - self.read(&mut arr)?; + self.read_exact(&mut arr)?; Ok(arr) } #[inline] fn read_vec(&mut self, size: usize) -> Result, std::io::Error> { let mut vec = vec![0; size]; - self.read(&mut vec)?; + self.read_exact(&mut vec)?; Ok(vec) } } diff --git a/src/zip/driver.rs b/src/zip/driver.rs index 62da39f..631c4ed 100644 --- a/src/zip/driver.rs +++ b/src/zip/driver.rs @@ -68,23 +68,23 @@ impl ArchiveRead for Zip { let limit = 65557.min(io.seek(SeekFrom::End(0))?) as i64; let start = io.seek(SeekFrom::End(-limit))?; let pos = start - + io.read_vec(limit as usize - 18)? - .windows(4) - .rposition(|v| u32::from_le_bytes(v.try_into().unwrap()) == 0x06054b50) - .ok_or(ZipError::EOCDRNotFound)? as u64; + + io.read_vec( + (limit as usize) + .checked_sub(18) + .ok_or(ZipError::EocdrNotFound)?, + )? + .windows(4) + .rposition(|v| u32::from_le_bytes(v.try_into().unwrap()) == 0x06054b50) + .ok_or(ZipError::EocdrNotFound)? as u64; // Read eocdr io.seek(SeekFrom::Start(pos + 4))?; let buf = io.read_arr::<18>()?; let eocdr: Eocdr = deserialize(&buf).unwrap(); - let comment = { - let mut buf: Vec = vec![0; eocdr.comment_len as usize]; - io.read(&mut buf)?; - String::from_cp437(buf) - }; + let comment = String::from_cp437(io.read_vec(eocdr.comment_len as usize)?); // Try to find eocdr64locator - io.seek(SeekFrom::Start(pos - 20))?; + io.seek(SeekFrom::Start(pos.saturating_sub(20)))?; let buf = io.read_arr::<20>()?; let (cd_pointer, cd_size, cd_records) = // If locator found then read eocdr64 diff --git a/src/zip/encryption.rs b/src/zip/encryption.rs index 28a6bdb..76824a1 100644 --- a/src/zip/encryption.rs +++ b/src/zip/encryption.rs @@ -72,7 +72,7 @@ impl WeakDecoder { fn decode_byte(&mut self, byte: u8) -> u8 { let key = self.key2 | 2; - let byte = byte ^ ((key * (key ^ 1)) >> 8) as u8; + let byte = byte ^ ((key.wrapping_mul(key ^ 1)) >> 8) as u8; self.update_keys(byte); byte } diff --git a/src/zip/error.rs b/src/zip/error.rs index a4b8c2b..525a67b 100644 --- a/src/zip/error.rs +++ b/src/zip/error.rs @@ -4,9 +4,9 @@ use std::fmt::Display; pub type ZipResult = ArchiveResult; -#[derive(Debug)] +#[derive(Debug, PartialEq, Eq)] pub enum ZipError { - EOCDRNotFound, + EocdrNotFound, InvalidEOCDR64Signature, InvalidFileHeaderSignature, InvalidCDRSignature, @@ -38,7 +38,7 @@ impl From for ArchiveError { impl Display for ZipError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - Self::EOCDRNotFound => write!(f, "End of central directory record not found"), + Self::EocdrNotFound => write!(f, "End of central directory record not found"), Self::InvalidEOCDR64Signature => { write!( f, -- cgit v1.2.3