Merge branch 'master' into support-extra-field
This commit is contained in:
commit
e42c021448
2 changed files with 38 additions and 18 deletions
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "zip"
|
||||
version = "0.5.8"
|
||||
version = "0.5.9"
|
||||
authors = ["Mathijs van de Nes <git@mathijs.vd-nes.nl>"]
|
||||
license = "MIT"
|
||||
repository = "https://github.com/mvdnes/zip-rs.git"
|
||||
|
|
54
src/read.rs
54
src/read.rs
|
@ -137,6 +137,27 @@ pub struct ZipFile<'a> {
|
|||
reader: ZipFileReader<'a>,
|
||||
}
|
||||
|
||||
fn find_content<'a>(
|
||||
data: &mut ZipFileData,
|
||||
reader: &'a mut (impl Read + Seek),
|
||||
) -> ZipResult<io::Take<&'a mut dyn Read>> {
|
||||
// Parse local header
|
||||
reader.seek(io::SeekFrom::Start(data.header_start))?;
|
||||
let signature = reader.read_u32::<LittleEndian>()?;
|
||||
if signature != spec::LOCAL_FILE_HEADER_SIGNATURE {
|
||||
return Err(ZipError::InvalidArchive("Invalid local file header"));
|
||||
}
|
||||
|
||||
reader.seek(io::SeekFrom::Current(22))?;
|
||||
let file_name_length = reader.read_u16::<LittleEndian>()? as u64;
|
||||
let extra_field_length = reader.read_u16::<LittleEndian>()? as u64;
|
||||
let magic_and_header = 4 + 22 + 2 + 2;
|
||||
data.data_start = data.header_start + magic_and_header + file_name_length + extra_field_length;
|
||||
|
||||
reader.seek(io::SeekFrom::Start(data.data_start))?;
|
||||
Ok((reader as &mut dyn Read).take(data.compressed_size))
|
||||
}
|
||||
|
||||
fn make_crypto_reader<'a>(
|
||||
compression_method: crate::compression::CompressionMethod,
|
||||
crc32: u32,
|
||||
|
@ -434,6 +455,21 @@ impl<R: Read + io::Seek> ZipArchive<R> {
|
|||
.unwrap())
|
||||
}
|
||||
|
||||
/// Get a contained file by index without decompressing it
|
||||
pub fn by_index_raw<'a>(&'a mut self, file_number: usize) -> ZipResult<ZipFile<'a>> {
|
||||
let reader = &mut self.reader;
|
||||
self.files
|
||||
.get_mut(file_number)
|
||||
.ok_or(ZipError::FileNotFound)
|
||||
.and_then(move |data| {
|
||||
Ok(ZipFile {
|
||||
crypto_reader: None,
|
||||
reader: ZipFileReader::Raw(find_content(data, reader)?),
|
||||
data: Cow::Borrowed(data),
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
fn by_index_with_optional_password<'a>(
|
||||
&'a mut self,
|
||||
file_number: usize,
|
||||
|
@ -453,23 +489,7 @@ impl<R: Read + io::Seek> ZipArchive<R> {
|
|||
(Some(_), false) => password = None, //Password supplied, but none needed! Discard.
|
||||
_ => {}
|
||||
}
|
||||
|
||||
// Parse local header
|
||||
self.reader.seek(io::SeekFrom::Start(data.header_start))?;
|
||||
let signature = self.reader.read_u32::<LittleEndian>()?;
|
||||
if signature != spec::LOCAL_FILE_HEADER_SIGNATURE {
|
||||
return Err(ZipError::InvalidArchive("Invalid local file header"));
|
||||
}
|
||||
|
||||
self.reader.seek(io::SeekFrom::Current(22))?;
|
||||
let file_name_length = self.reader.read_u16::<LittleEndian>()? as u64;
|
||||
let extra_field_length = self.reader.read_u16::<LittleEndian>()? as u64;
|
||||
let magic_and_header = 4 + 22 + 2 + 2;
|
||||
data.data_start =
|
||||
data.header_start + magic_and_header + file_name_length + extra_field_length;
|
||||
|
||||
self.reader.seek(io::SeekFrom::Start(data.data_start))?;
|
||||
let limit_reader = (self.reader.by_ref() as &mut dyn Read).take(data.compressed_size);
|
||||
let limit_reader = find_content(data, &mut self.reader)?;
|
||||
|
||||
match make_crypto_reader(data.compression_method, data.crc32, limit_reader, password) {
|
||||
Ok(Ok(crypto_reader)) => Ok(Ok(ZipFile {
|
||||
|
|
Loading…
Add table
Reference in a new issue