diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/zip/driver.rs | 55 |
1 files changed, 30 insertions, 25 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); |
