diff options
| -rw-r--r-- | src/zip/driver.rs | 55 | ||||
| -rw-r--r-- | tests/files/blank | 0 | ||||
| -rw-r--r-- | tests/files/empty.zip | bin | 22 -> 0 bytes | |||
| -rw-r--r-- | tests/zip.rs | 39 |
4 files changed, 60 insertions, 34 deletions
diff --git a/src/zip/driver.rs b/src/zip/driver.rs index 81629dd..7758479 100644 --- a/src/zip/driver.rs +++ b/src/zip/driver.rs | |||
| @@ -98,33 +98,38 @@ impl<Io: Read + Seek> ArchiveRead for Zip<Io> { | |||
| 98 | // Try to find eocdr64locator | 98 | // Try to find eocdr64locator |
| 99 | io.seek(SeekFrom::Start(pos.saturating_sub(20)))?; | 99 | io.seek(SeekFrom::Start(pos.saturating_sub(20)))?; |
| 100 | let buf = io.read_arr::<20>()?; | 100 | let buf = io.read_arr::<20>()?; |
| 101 | let (cd_pointer, cd_size, cd_records) = | 101 | let (cd_pointer, cd_size, cd_records) = if buf[..4] == EOCDR64_LOCATOR_SIGNATURE { |
| 102 | // If locator found then read eocdr64 | 102 | // Locator found |
| 103 | if buf[0..4] == EOCDR64_LOCATOR_SIGNATURE { | 103 | let eocdr64locator: Eocdr64Locator = deserialize(&buf[4..]).unwrap(); |
| 104 | let eocdr64locator: Eocdr64Locator = deserialize(&buf[4..]).unwrap(); | ||
| 105 | |||
| 106 | io.seek(SeekFrom::Start(eocdr64locator.eocdr64_pointer))?; | ||
| 107 | let buf = io.read_arr::<56>()?; | ||
| 108 | if buf[0..4] != EOCDR64_SIGNATURE { | ||
| 109 | return Err(ZipError::InvalidSignature("Eocdr64")); | ||
| 110 | } | ||
| 111 | let eocdr64: Eocdr64 = deserialize(&buf[4..]).unwrap(); | ||
| 112 | if eocdr64.cd_pointer + eocdr64.cd_size > eocdr64locator.eocdr64_pointer { | ||
| 113 | return Err(ZipError::Overlapping("Central directory records", "Zip64 end of central directory record")); | ||
| 114 | } | ||
| 115 | 104 | ||
| 116 | (eocdr64.cd_pointer, eocdr64.cd_size, eocdr64.cd_records) | 105 | io.seek(SeekFrom::Start(eocdr64locator.eocdr64_pointer))?; |
| 117 | } else { | 106 | if io.read_arr()? != EOCDR64_SIGNATURE { |
| 118 | if (eocdr.cd_pointer + eocdr.cd_size) as u64 > pos { | 107 | return Err(ZipError::InvalidSignature("Eocdr64")); |
| 119 | return Err(ZipError::Overlapping("Central directory records", "End of central directory record")); | 108 | } |
| 120 | } | ||
| 121 | 109 | ||
| 122 | ( | 110 | let eocdr64: Eocdr64 = deserialize(&io.read_arr::<52>()?).unwrap(); |
| 123 | eocdr.cd_pointer as u64, | 111 | if eocdr64.cd_pointer + eocdr64.cd_size > eocdr64locator.eocdr64_pointer { |
| 124 | eocdr.cd_size as u64, | 112 | return Err(ZipError::Overlapping( |
| 125 | eocdr.cd_records as u64, | 113 | "Central directory records", |
| 126 | ) | 114 | "Zip64 end of central directory record", |
| 127 | }; | 115 | )); |
| 116 | } | ||
| 117 | |||
| 118 | (eocdr64.cd_pointer, eocdr64.cd_size, eocdr64.cd_records) | ||
| 119 | } else { | ||
| 120 | if (eocdr.cd_pointer + eocdr.cd_size) as u64 > pos { | ||
| 121 | return Err(ZipError::Overlapping( | ||
| 122 | "Central directory records", | ||
| 123 | "End of central directory record", | ||
| 124 | )); | ||
| 125 | } | ||
| 126 | |||
| 127 | ( | ||
| 128 | eocdr.cd_pointer as u64, | ||
| 129 | eocdr.cd_size as u64, | ||
| 130 | eocdr.cd_records as u64, | ||
| 131 | ) | ||
| 132 | }; | ||
| 128 | 133 | ||
| 129 | // Read cd records | 134 | // Read cd records |
| 130 | let mut indexes = Map::with_capacity(cd_records as usize); | 135 | let mut indexes = Map::with_capacity(cd_records as usize); |
diff --git a/tests/files/blank b/tests/files/blank deleted file mode 100644 index e69de29..0000000 --- a/tests/files/blank +++ /dev/null | |||
diff --git a/tests/files/empty.zip b/tests/files/empty.zip deleted file mode 100644 index 15cb0ec..0000000 --- a/tests/files/empty.zip +++ /dev/null | |||
| Binary files differ | |||
diff --git a/tests/zip.rs b/tests/zip.rs index e2b5c20..1422bb3 100644 --- a/tests/zip.rs +++ b/tests/zip.rs | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | use archivator::zip::ZipError; | 1 | use archivator::zip::ZipError; |
| 2 | use archivator::{Archive, Zip}; | 2 | use archivator::{Archive, Zip}; |
| 3 | use std::io::{Read, Seek, SeekFrom}; | 3 | use std::io::{Cursor, Read, Seek, SeekFrom}; |
| 4 | 4 | ||
| 5 | #[test] | 5 | #[test] |
| 6 | fn test_zip_aes() { | 6 | fn test_zip_aes() { |
| @@ -90,14 +90,11 @@ fn test_zip_weak() { | |||
| 90 | } | 90 | } |
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | const EMPTY: Cursor<&[u8]> = Cursor::new(b"PK\x05\x06\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"); | ||
| 94 | |||
| 93 | #[test] | 95 | #[test] |
| 94 | fn test_zip() { | 96 | fn test_zip() { |
| 95 | assert_eq!( | 97 | assert_eq!(Archive::<Zip<_>>::read(EMPTY).unwrap().len(), 0); |
| 96 | Archive::<Zip>::read_from_file("tests/files/empty.zip") | ||
| 97 | .unwrap() | ||
| 98 | .len(), | ||
| 99 | 0 | ||
| 100 | ); | ||
| 101 | 98 | ||
| 102 | let mut archive = Archive::<Zip>::read_from_file("tests/files/archive.zip").unwrap(); | 99 | let mut archive = Archive::<Zip>::read_from_file("tests/files/archive.zip").unwrap(); |
| 103 | 100 | ||
| @@ -161,8 +158,32 @@ fn test_zip() { | |||
| 161 | } | 158 | } |
| 162 | } | 159 | } |
| 163 | 160 | ||
| 161 | const NOT_FOUND: Cursor<&[u8]> = Cursor::new(b""); | ||
| 162 | const INVALID: Cursor<&[u8]> = Cursor::new( | ||
| 163 | b"PK\x06\x07\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0PK\x05\x06\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\0", | ||
| 164 | ); | ||
| 165 | const OVERLAP: Cursor<&[u8]> = Cursor::new(b"PK\x05\x06\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\0"); | ||
| 166 | const OVERLAP64: Cursor<&[u8]> = Cursor::new(b"PK\x06\x06\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0PK\x06\x07\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0PK\x05\x06\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\0"); | ||
| 167 | |||
| 164 | #[test] | 168 | #[test] |
| 165 | fn test_bad_zip() { | 169 | fn test_bad_zip() { |
| 166 | assert!(Archive::<Zip>::read_from_file("tests/files/blank") | 170 | assert!( |
| 167 | .is_err_and(|e| e == ZipError::StructNotFound("Eocdr"))); | 171 | Archive::<Zip<_>>::read(NOT_FOUND).is_err_and(|e| e == ZipError::StructNotFound("Eocdr")) |
| 172 | ); | ||
| 173 | |||
| 174 | assert!( | ||
| 175 | Archive::<Zip<_>>::read(INVALID).is_err_and(|e| e == ZipError::InvalidSignature("Eocdr64")) | ||
| 176 | ); | ||
| 177 | |||
| 178 | assert!(Archive::<Zip<_>>::read(OVERLAP).is_err_and(|e| e | ||
| 179 | == ZipError::Overlapping( | ||
| 180 | "Central directory records", | ||
| 181 | "End of central directory record" | ||
| 182 | ))); | ||
| 183 | |||
| 184 | assert!(Archive::<Zip<_>>::read(OVERLAP64).is_err_and(|e| e | ||
| 185 | == ZipError::Overlapping( | ||
| 186 | "Central directory records", | ||
| 187 | "Zip64 end of central directory record" | ||
| 188 | ))); | ||
| 168 | } | 189 | } |
