diff --git a/src/read.rs b/src/read.rs index 91602d17..efbd34cb 100644 --- a/src/read.rs +++ b/src/read.rs @@ -1215,8 +1215,10 @@ pub(crate) fn parse_extra_field(file: &mut ZipFileData) -> ZipResult<()> { let mut reader = io::Cursor::new(extra_field); /* TODO: codify this structure into Zip64ExtraFieldBlock fields! */ - while (reader.position() as usize) < len { - parse_single_extra_field(file, &mut reader)?; + let mut position = reader.position(); + while (position as usize) < len { + parse_single_extra_field(file, &mut reader, position)?; + position = reader.position(); } Ok(()) } @@ -1224,6 +1226,7 @@ pub(crate) fn parse_extra_field(file: &mut ZipFileData) -> ZipResult<()> { pub(crate) fn parse_single_extra_field( file: &mut ZipFileData, reader: &mut R, + bytes_already_read: u64, ) -> ZipResult<()> { let kind = reader.read_u16_le()?; let len = reader.read_u16_le()?; @@ -1271,6 +1274,7 @@ pub(crate) fn parse_single_extra_field( _ => return Err(ZipError::InvalidArchive("Invalid AES encryption strength")), }; file.compression_method = compression_method; + file.aes_extra_data_start = bytes_already_read; } 0x5455 => { // extended timestamp diff --git a/src/write.rs b/src/write.rs index a8c7d113..38dfd419 100644 --- a/src/write.rs +++ b/src/write.rs @@ -4,8 +4,7 @@ use crate::aes::AesWriter; use crate::compression::CompressionMethod; use crate::read::{ - find_content, parse_extra_field, parse_single_extra_field, Config, ZipArchive, ZipFile, - ZipFileReader, + find_content, parse_single_extra_field, Config, ZipArchive, ZipFile, ZipFileReader, }; use crate::result::{ZipError, ZipResult}; use crate::spec::{self, FixedSizeBlock, Magic}; @@ -351,7 +350,7 @@ impl ExtendedFileOptions { } data.seek(SeekFrom::Current(-2))?; } - parse_single_extra_field(&mut ZipFileData::default(), &mut data)?; + parse_single_extra_field(&mut ZipFileData::default(), &mut data, 0)?; } Ok(()) } @@ -874,6 +873,7 @@ impl ZipWriter { if let Some(EncryptWith::Aes { mode, .. }) = options.encrypt_with { let aes_dummy_extra_data = vec![0x02, 0x00, 0x41, 0x45, mode as u8, 0x00, 0x00].into_boxed_slice(); + aes_extra_data_start = extensions.extra_data.len() as u64; extensions.add_extra_data(0x9901, aes_dummy_extra_data, false)?; } { @@ -898,7 +898,6 @@ impl ZipWriter { aes_mode, &extensions.extra_data, ); - parse_extra_field(&mut file)?; file.version_made_by = file.version_made_by.max(file.version_needed() as u8); let index = self.insert_file_data(file)?; let file = &mut self.files[index]; @@ -943,6 +942,10 @@ impl ZipWriter { extensions.add_extra_data(0xa11e, pad_body.into_boxed_slice(), false)?; } } + extensions.validate_extra_data()?; + if extensions.central_extra_data.len() > 0 { + file.central_extra_field = Some(extensions.central_extra_data); + } writer.write_all(&extensions.extra_data)?; extra_data_end = writer.stream_position()?; debug_assert_eq!(extra_data_end % (options.alignment.max(1) as u64), 0);