diff options
| author | Igor Tolmachev <me@igorek.dev> | 2024-07-16 20:08:01 +0900 |
|---|---|---|
| committer | Igor Tolmachev <me@igorek.dev> | 2024-07-16 20:08:01 +0900 |
| commit | 9c0e544e79a4f7874dab449674a11d899bf61963 (patch) | |
| tree | 89ce5177ede27b3966f9589e012887e8614a7b38 /src | |
| parent | cc18a545a87ca616f05114d174690e5cc9614669 (diff) | |
| download | archivator-9c0e544e79a4f7874dab449674a11d899bf61963.tar.gz archivator-9c0e544e79a4f7874dab449674a11d899bf61963.zip | |
Add tests and fix bugs
Diffstat (limited to 'src')
| -rw-r--r-- | src/error.rs | 9 | ||||
| -rw-r--r-- | src/utils/read.rs | 4 | ||||
| -rw-r--r-- | src/zip/driver.rs | 20 | ||||
| -rw-r--r-- | src/zip/encryption.rs | 2 | ||||
| -rw-r--r-- | src/zip/error.rs | 6 |
5 files changed, 25 insertions, 16 deletions
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<E: Error> From<io::Error> for ArchiveError<E> { | |||
| 17 | } | 17 | } |
| 18 | } | 18 | } |
| 19 | 19 | ||
| 20 | impl<E: Error + PartialEq> PartialEq<E> for ArchiveError<E> { | ||
| 21 | fn eq(&self, other: &E) -> bool { | ||
| 22 | match self { | ||
| 23 | Self::Archivator { error, .. } => error == other, | ||
| 24 | _ => false, | ||
| 25 | } | ||
| 26 | } | ||
| 27 | } | ||
| 28 | |||
| 20 | impl<E: Error> Display for ArchiveError<E> { | 29 | impl<E: Error> Display for ArchiveError<E> { |
| 21 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | 30 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| 22 | match self { | 31 | 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<R: Read> ReadUtils for R { | |||
| 10 | #[inline] | 10 | #[inline] |
| 11 | fn read_arr<const S: usize>(&mut self) -> Result<[u8; S], std::io::Error> { | 11 | fn read_arr<const S: usize>(&mut self) -> Result<[u8; S], std::io::Error> { |
| 12 | let mut arr = [0; S]; | 12 | let mut arr = [0; S]; |
| 13 | self.read(&mut arr)?; | 13 | self.read_exact(&mut arr)?; |
| 14 | Ok(arr) | 14 | Ok(arr) |
| 15 | } | 15 | } |
| 16 | 16 | ||
| 17 | #[inline] | 17 | #[inline] |
| 18 | fn read_vec(&mut self, size: usize) -> Result<Vec<u8>, std::io::Error> { | 18 | fn read_vec(&mut self, size: usize) -> Result<Vec<u8>, std::io::Error> { |
| 19 | let mut vec = vec![0; size]; | 19 | let mut vec = vec![0; size]; |
| 20 | self.read(&mut vec)?; | 20 | self.read_exact(&mut vec)?; |
| 21 | Ok(vec) | 21 | Ok(vec) |
| 22 | } | 22 | } |
| 23 | } | 23 | } |
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<Io: Read + Seek> ArchiveRead for Zip<Io> { | |||
| 68 | let limit = 65557.min(io.seek(SeekFrom::End(0))?) as i64; | 68 | let limit = 65557.min(io.seek(SeekFrom::End(0))?) as i64; |
| 69 | let start = io.seek(SeekFrom::End(-limit))?; | 69 | let start = io.seek(SeekFrom::End(-limit))?; |
| 70 | let pos = start | 70 | let pos = start |
| 71 | + io.read_vec(limit as usize - 18)? | 71 | + io.read_vec( |
| 72 | .windows(4) | 72 | (limit as usize) |
| 73 | .rposition(|v| u32::from_le_bytes(v.try_into().unwrap()) == 0x06054b50) | 73 | .checked_sub(18) |
| 74 | .ok_or(ZipError::EOCDRNotFound)? as u64; | 74 | .ok_or(ZipError::EocdrNotFound)?, |
| 75 | )? | ||
| 76 | .windows(4) | ||
| 77 | .rposition(|v| u32::from_le_bytes(v.try_into().unwrap()) == 0x06054b50) | ||
| 78 | .ok_or(ZipError::EocdrNotFound)? as u64; | ||
| 75 | 79 | ||
| 76 | // Read eocdr | 80 | // Read eocdr |
| 77 | io.seek(SeekFrom::Start(pos + 4))?; | 81 | io.seek(SeekFrom::Start(pos + 4))?; |
| 78 | let buf = io.read_arr::<18>()?; | 82 | let buf = io.read_arr::<18>()?; |
| 79 | let eocdr: Eocdr = deserialize(&buf).unwrap(); | 83 | let eocdr: Eocdr = deserialize(&buf).unwrap(); |
| 80 | let comment = { | 84 | let comment = String::from_cp437(io.read_vec(eocdr.comment_len as usize)?); |
| 81 | let mut buf: Vec<u8> = vec![0; eocdr.comment_len as usize]; | ||
| 82 | io.read(&mut buf)?; | ||
| 83 | String::from_cp437(buf) | ||
| 84 | }; | ||
| 85 | 85 | ||
| 86 | // Try to find eocdr64locator | 86 | // Try to find eocdr64locator |
| 87 | io.seek(SeekFrom::Start(pos - 20))?; | 87 | io.seek(SeekFrom::Start(pos.saturating_sub(20)))?; |
| 88 | let buf = io.read_arr::<20>()?; | 88 | let buf = io.read_arr::<20>()?; |
| 89 | let (cd_pointer, cd_size, cd_records) = | 89 | let (cd_pointer, cd_size, cd_records) = |
| 90 | // If locator found then read eocdr64 | 90 | // 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<Io: Read> WeakDecoder<Io> { | |||
| 72 | 72 | ||
| 73 | fn decode_byte(&mut self, byte: u8) -> u8 { | 73 | fn decode_byte(&mut self, byte: u8) -> u8 { |
| 74 | let key = self.key2 | 2; | 74 | let key = self.key2 | 2; |
| 75 | let byte = byte ^ ((key * (key ^ 1)) >> 8) as u8; | 75 | let byte = byte ^ ((key.wrapping_mul(key ^ 1)) >> 8) as u8; |
| 76 | self.update_keys(byte); | 76 | self.update_keys(byte); |
| 77 | byte | 77 | byte |
| 78 | } | 78 | } |
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; | |||
| 4 | 4 | ||
| 5 | pub type ZipResult<T> = ArchiveResult<T, ZipError>; | 5 | pub type ZipResult<T> = ArchiveResult<T, ZipError>; |
| 6 | 6 | ||
| 7 | #[derive(Debug)] | 7 | #[derive(Debug, PartialEq, Eq)] |
| 8 | pub enum ZipError { | 8 | pub enum ZipError { |
| 9 | EOCDRNotFound, | 9 | EocdrNotFound, |
| 10 | InvalidEOCDR64Signature, | 10 | InvalidEOCDR64Signature, |
| 11 | InvalidFileHeaderSignature, | 11 | InvalidFileHeaderSignature, |
| 12 | InvalidCDRSignature, | 12 | InvalidCDRSignature, |
| @@ -38,7 +38,7 @@ impl From<ZipError> for ArchiveError<ZipError> { | |||
| 38 | impl Display for ZipError { | 38 | impl Display for ZipError { |
| 39 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | 39 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| 40 | match self { | 40 | match self { |
| 41 | Self::EOCDRNotFound => write!(f, "End of central directory record not found"), | 41 | Self::EocdrNotFound => write!(f, "End of central directory record not found"), |
| 42 | Self::InvalidEOCDR64Signature => { | 42 | Self::InvalidEOCDR64Signature => { |
| 43 | write!( | 43 | write!( |
| 44 | f, | 44 | f, |
