test: Fix a bug involving ZIP64 field parsing
This commit is contained in:
parent
499bd65f71
commit
c4bd7a61a5
2 changed files with 18 additions and 7 deletions
17
src/read.rs
17
src/read.rs
|
@ -20,6 +20,7 @@ use std::ffi::OsString;
|
|||
use std::fs::create_dir_all;
|
||||
use std::io::{self, copy, prelude::*, sink, SeekFrom};
|
||||
use std::mem;
|
||||
use std::mem::size_of;
|
||||
use std::ops::Deref;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::{Arc, OnceLock};
|
||||
|
@ -94,7 +95,7 @@ use crate::aes::PWD_VERIFY_LENGTH;
|
|||
use crate::extra_fields::UnicodeExtraField;
|
||||
#[cfg(feature = "lzma")]
|
||||
use crate::read::lzma::LzmaDecoder;
|
||||
use crate::result::ZipError::{InvalidPassword, UnsupportedArchive};
|
||||
use crate::result::ZipError::{InvalidArchive, InvalidPassword, UnsupportedArchive};
|
||||
use crate::spec::is_dir;
|
||||
use crate::types::ffi::S_IFLNK;
|
||||
use crate::unstable::{path_to_string, LittleEndianReadExt};
|
||||
|
@ -1233,17 +1234,25 @@ pub(crate) fn parse_single_extra_field<R: Read>(
|
|||
match kind {
|
||||
// Zip64 extended information extra field
|
||||
0x0001 => {
|
||||
if file.uncompressed_size == spec::ZIP64_BYTES_THR {
|
||||
let mut consumed_len = 0;
|
||||
if len >= 24 || file.uncompressed_size == spec::ZIP64_BYTES_THR {
|
||||
file.large_file = true;
|
||||
file.uncompressed_size = reader.read_u64_le()?;
|
||||
consumed_len += size_of::<u64>();
|
||||
}
|
||||
if file.compressed_size == spec::ZIP64_BYTES_THR {
|
||||
if len >= 24 || file.compressed_size == spec::ZIP64_BYTES_THR {
|
||||
file.large_file = true;
|
||||
file.compressed_size = reader.read_u64_le()?;
|
||||
consumed_len += size_of::<u64>();
|
||||
}
|
||||
if file.header_start == spec::ZIP64_BYTES_THR {
|
||||
if len >= 24 || file.header_start == spec::ZIP64_BYTES_THR {
|
||||
file.header_start = reader.read_u64_le()?;
|
||||
consumed_len += size_of::<u64>();
|
||||
}
|
||||
let Some(leftover_len) = (len as usize).checked_sub(consumed_len) else {
|
||||
return Err(InvalidArchive("ZIP64 extra-data field is the wrong length"));
|
||||
};
|
||||
reader.read_exact(&mut vec![0u8; leftover_len])?;
|
||||
}
|
||||
0x9901 => {
|
||||
// AES
|
||||
|
|
|
@ -325,11 +325,12 @@ impl ExtendedFileOptions {
|
|||
)));
|
||||
}
|
||||
let mut data = Cursor::new(data);
|
||||
while data.position() < len {
|
||||
let mut pos = data.position();
|
||||
while pos < len {
|
||||
if len - data.position() < 4 {
|
||||
return Err(ZipError::Io(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
"Extra-data field doesn't have room for tag and length",
|
||||
"Extra-data field doesn't have room for ID and length",
|
||||
)));
|
||||
}
|
||||
#[cfg(not(feature = "unreserved"))]
|
||||
|
@ -350,7 +351,8 @@ impl ExtendedFileOptions {
|
|||
}
|
||||
data.seek(SeekFrom::Current(-2))?;
|
||||
}
|
||||
parse_single_extra_field(&mut ZipFileData::default(), &mut data, 0)?;
|
||||
parse_single_extra_field(&mut ZipFileData::default(), &mut data, pos)?;
|
||||
pos = data.position();
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue