Fix bad merge: revert deletion of zip64 extra field
This commit is contained in:
parent
00537ae34e
commit
e334f15f12
1 changed files with 65 additions and 0 deletions
65
src/write.rs
65
src/write.rs
|
@ -860,6 +860,71 @@ impl<W: Write + Seek> ZipWriter<W> {
|
||||||
if file.large_file {
|
if file.large_file {
|
||||||
write_local_zip64_extra_field(writer, file)?;
|
write_local_zip64_extra_field(writer, file)?;
|
||||||
}
|
}
|
||||||
|
if let Some(extra_field) = &file.extra_field {
|
||||||
|
file.extra_data_start = Some(writer.stream_position()?);
|
||||||
|
writer.write_all(extra_field)?;
|
||||||
|
}
|
||||||
|
let mut header_end = writer.stream_position()?;
|
||||||
|
if options.alignment > 1 {
|
||||||
|
let align = options.alignment as u64;
|
||||||
|
let unaligned_header_bytes = header_end % align;
|
||||||
|
if unaligned_header_bytes != 0 {
|
||||||
|
let pad_length = (align - unaligned_header_bytes) as usize;
|
||||||
|
let Some(new_extra_field_length) =
|
||||||
|
(pad_length as u16).checked_add(extra_field_length)
|
||||||
|
else {
|
||||||
|
let _ = self.abort_file();
|
||||||
|
return Err(InvalidArchive(
|
||||||
|
"Extra data field would be larger than allowed after aligning",
|
||||||
|
));
|
||||||
|
};
|
||||||
|
if pad_length >= 4 {
|
||||||
|
// Add an extra field to the extra_data
|
||||||
|
let pad_body = vec![0; pad_length - 4];
|
||||||
|
writer.write_all(b"za").map_err(ZipError::from)?; // 0x617a
|
||||||
|
writer
|
||||||
|
.write_u16_le(pad_body.len() as u16)
|
||||||
|
.map_err(ZipError::from)?;
|
||||||
|
writer.write_all(&pad_body).map_err(ZipError::from)?;
|
||||||
|
} else {
|
||||||
|
// extra_data padding is too small for an extra field header, so pad with
|
||||||
|
// zeroes
|
||||||
|
let pad = vec![0; pad_length];
|
||||||
|
writer.write_all(&pad).map_err(ZipError::from)?;
|
||||||
|
}
|
||||||
|
header_end = writer.stream_position()?;
|
||||||
|
|
||||||
|
// Update extra field length in local file header.
|
||||||
|
writer.seek(SeekFrom::Start(file.header_start + 28))?;
|
||||||
|
writer.write_u16_le(new_extra_field_length)?;
|
||||||
|
writer.seek(SeekFrom::Start(header_end))?;
|
||||||
|
debug_assert_eq!(header_end % align, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
match options.encrypt_with {
|
||||||
|
#[cfg(feature = "aes-crypto")]
|
||||||
|
Some(EncryptWith::Aes { mode, password }) => {
|
||||||
|
let aeswriter = AesWriter::new(
|
||||||
|
mem::replace(&mut self.inner, GenericZipWriter::Closed).unwrap(),
|
||||||
|
mode,
|
||||||
|
password.as_bytes(),
|
||||||
|
)?;
|
||||||
|
self.inner = GenericZipWriter::Storer(MaybeEncrypted::Aes(aeswriter));
|
||||||
|
}
|
||||||
|
Some(EncryptWith::ZipCrypto(keys, ..)) => {
|
||||||
|
let mut zipwriter = crate::zipcrypto::ZipCryptoWriter {
|
||||||
|
writer: mem::replace(&mut self.inner, Closed).unwrap(),
|
||||||
|
buffer: vec![],
|
||||||
|
keys,
|
||||||
|
};
|
||||||
|
let crypto_header = [0u8; 12];
|
||||||
|
|
||||||
|
zipwriter.write_all(&crypto_header)?;
|
||||||
|
header_end = zipwriter.writer.stream_position()?;
|
||||||
|
self.inner = Storer(MaybeEncrypted::ZipCrypto(zipwriter));
|
||||||
|
}
|
||||||
|
None => {}
|
||||||
|
}
|
||||||
self.stats.start = header_end;
|
self.stats.start = header_end;
|
||||||
debug_assert!(file.data_start.get().is_none());
|
debug_assert!(file.data_start.get().is_none());
|
||||||
file.data_start.get_or_init(|| header_end);
|
file.data_start.get_or_init(|| header_end);
|
||||||
|
|
Loading…
Add table
Reference in a new issue