Defer parsing of local file header
This commit is contained in:
parent
493424e93d
commit
9e8747872b
1 changed files with 16 additions and 23 deletions
39
src/read.rs
39
src/read.rs
|
@ -282,15 +282,28 @@ impl<R: Read+io::Seek> ZipArchive<R>
|
||||||
pub fn by_index<'a>(&'a mut self, file_number: usize) -> ZipResult<ZipFile<'a>>
|
pub fn by_index<'a>(&'a mut self, file_number: usize) -> ZipResult<ZipFile<'a>>
|
||||||
{
|
{
|
||||||
if file_number >= self.files.len() { return Err(ZipError::FileNotFound); }
|
if file_number >= self.files.len() { return Err(ZipError::FileNotFound); }
|
||||||
let ref data = self.files[file_number];
|
let ref mut data = self.files[file_number];
|
||||||
let pos = data.data_start;
|
|
||||||
|
|
||||||
if data.encrypted
|
if data.encrypted
|
||||||
{
|
{
|
||||||
return unsupported_zip_error("Encrypted files are not supported")
|
return unsupported_zip_error("Encrypted files are not supported")
|
||||||
}
|
}
|
||||||
|
|
||||||
self.reader.seek(io::SeekFrom::Start(pos))?;
|
// 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 Read).take(data.compressed_size);
|
let limit_reader = (self.reader.by_ref() as &mut Read).take(data.compressed_size);
|
||||||
|
|
||||||
Ok(ZipFile { reader: make_reader(data.compression_method, data.crc32, limit_reader)?, data: Cow::Borrowed(data) })
|
Ok(ZipFile { reader: make_reader(data.compression_method, data.crc32, limit_reader)?, data: Cow::Borrowed(data) })
|
||||||
|
@ -374,26 +387,6 @@ fn central_header_to_zip_file<R: Read+io::Seek>(reader: &mut R, archive_offset:
|
||||||
// Account for shifted zip offsets.
|
// Account for shifted zip offsets.
|
||||||
result.header_start += archive_offset;
|
result.header_start += archive_offset;
|
||||||
|
|
||||||
// Remember end of central header
|
|
||||||
let return_position = reader.seek(io::SeekFrom::Current(0))?;
|
|
||||||
|
|
||||||
// Parse local header
|
|
||||||
reader.seek(io::SeekFrom::Start(result.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;
|
|
||||||
result.data_start = result.header_start + magic_and_header + file_name_length + extra_field_length;
|
|
||||||
|
|
||||||
// Go back after the central header
|
|
||||||
reader.seek(io::SeekFrom::Start(return_position))?;
|
|
||||||
|
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue