From 86d9d208842c271fd32bdce957402e8143ac686e Mon Sep 17 00:00:00 2001 From: Mathijs van de Nes Date: Sun, 17 Jun 2018 15:23:19 +0200 Subject: [PATCH] Calculate data_start after parse_extra_field Some extra fields may alter offsets, e.g. Zip64. --- src/read.rs | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/read.rs b/src/read.rs index e6e982be..13b8e8df 100644 --- a/src/read.rs +++ b/src/read.rs @@ -344,23 +344,6 @@ fn central_header_to_zip_file(reader: &mut R, archive_offset: false => file_comment_raw.from_cp437(), }; - // Remember end of central header - let return_position = try!(reader.seek(io::SeekFrom::Current(0))); - - // Parse local header - try!(reader.seek(io::SeekFrom::Start(offset))); - let signature = try!(reader.read_u32::()); - if signature != spec::LOCAL_FILE_HEADER_SIGNATURE - { - return Err(ZipError::InvalidArchive("Invalid local file header")) - } - - try!(reader.seek(io::SeekFrom::Current(22))); - let file_name_length = try!(reader.read_u16::()) as u64; - let extra_field_length = try!(reader.read_u16::()) as u64; - let magic_and_header = 4 + 22 + 2 + 2; - let data_start = offset + magic_and_header + file_name_length + extra_field_length; - // Construct the result let mut result = ZipFileData { @@ -376,7 +359,7 @@ fn central_header_to_zip_file(reader: &mut R, archive_offset: file_name_raw: file_name_raw, file_comment: file_comment, header_start: offset, - data_start: data_start, + data_start: 0, external_attributes: external_file_attributes, }; @@ -385,6 +368,23 @@ fn central_header_to_zip_file(reader: &mut R, archive_offset: Err(e) => try!(Err(e)), } + // Remember end of central header + let return_position = try!(reader.seek(io::SeekFrom::Current(0))); + + // Parse local header + try!(reader.seek(io::SeekFrom::Start(result.header_start))); + let signature = try!(reader.read_u32::()); + if signature != spec::LOCAL_FILE_HEADER_SIGNATURE + { + return Err(ZipError::InvalidArchive("Invalid local file header")) + } + + try!(reader.seek(io::SeekFrom::Current(22))); + let file_name_length = try!(reader.read_u16::()) as u64; + let extra_field_length = try!(reader.read_u16::()) 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 try!(reader.seek(io::SeekFrom::Start(return_position)));