aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/zip/driver.rs55
-rw-r--r--tests/files/blank0
-rw-r--r--tests/files/empty.zipbin22 -> 0 bytes
-rw-r--r--tests/zip.rs39
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 @@
1use archivator::zip::ZipError; 1use archivator::zip::ZipError;
2use archivator::{Archive, Zip}; 2use archivator::{Archive, Zip};
3use std::io::{Read, Seek, SeekFrom}; 3use std::io::{Cursor, Read, Seek, SeekFrom};
4 4
5#[test] 5#[test]
6fn test_zip_aes() { 6fn test_zip_aes() {
@@ -90,14 +90,11 @@ fn test_zip_weak() {
90 } 90 }
91} 91}
92 92
93const 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]
94fn test_zip() { 96fn 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
161const NOT_FOUND: Cursor<&[u8]> = Cursor::new(b"");
162const 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);
165const 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");
166const 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]
165fn test_bad_zip() { 169fn 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}