diff options
Diffstat (limited to 'vendor/zip/src/spec.rs')
-rw-r--r-- | vendor/zip/src/spec.rs | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/vendor/zip/src/spec.rs b/vendor/zip/src/spec.rs index 3ffcf7323..1d8cb0a64 100644 --- a/vendor/zip/src/spec.rs +++ b/vendor/zip/src/spec.rs @@ -23,6 +23,18 @@ pub struct CentralDirectoryEnd { } impl CentralDirectoryEnd { + // Per spec 4.4.1.4 - a CentralDirectoryEnd field might be insufficient to hold the + // required data. In this case the file SHOULD contain a ZIP64 format record + // and the field of this record will be set to -1 + pub(crate) fn record_too_small(&self) -> bool { + self.disk_number == 0xFFFF + || self.disk_with_central_directory == 0xFFFF + || self.number_of_files_on_this_disk == 0xFFFF + || self.number_of_files == 0xFFFF + || self.central_directory_size == 0xFFFFFFFF + || self.central_directory_offset == 0xFFFFFFFF + } + pub fn parse<T: Read>(reader: &mut T) -> ZipResult<CentralDirectoryEnd> { let magic = reader.read_u32::<LittleEndian>()?; if magic != CENTRAL_DIRECTORY_END_SIGNATURE { @@ -64,12 +76,12 @@ impl CentralDirectoryEnd { let mut pos = file_length - HEADER_SIZE; while pos >= search_upper_bound { - reader.seek(io::SeekFrom::Start(pos as u64))?; + reader.seek(io::SeekFrom::Start(pos))?; if reader.read_u32::<LittleEndian>()? == CENTRAL_DIRECTORY_END_SIGNATURE { reader.seek(io::SeekFrom::Current( BYTES_BETWEEN_MAGIC_AND_COMMENT_SIZE as i64, ))?; - let cde_start_pos = reader.seek(io::SeekFrom::Start(pos as u64))?; + let cde_start_pos = reader.seek(io::SeekFrom::Start(pos))?; return CentralDirectoryEnd::parse(reader).map(|cde| (cde, cde_start_pos)); } pos = match pos.checked_sub(1) { |