tools/zip: only add zip64 field when necessary

if neither offset nor size exceeds 32bit, do not add the
zip64 extension field

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
This commit is contained in:
Dominik Csapak 2021-03-15 12:21:17 +01:00 committed by Dietmar Maurer
parent 84d3284609
commit 7914e62b10

View File

@ -301,10 +301,26 @@ impl ZipEntry {
let filename_len = filename.len(); let filename_len = filename.len();
let header_size = size_of::<CentralDirectoryFileHeader>(); let header_size = size_of::<CentralDirectoryFileHeader>();
let zip_field_size = size_of::<Zip64FieldWithOffset>(); let zip_field_size = size_of::<Zip64FieldWithOffset>();
let size: usize = header_size + filename_len + zip_field_size; let mut size: usize = header_size + filename_len;
let (date, time) = epoch_to_dos(self.mtime); let (date, time) = epoch_to_dos(self.mtime);
let (compressed_size, uncompressed_size, offset, need_zip64) = if self.compressed_size
>= (u32::MAX as u64)
|| self.uncompressed_size >= (u32::MAX as u64)
|| self.offset >= (u32::MAX as u64)
{
size += zip_field_size;
(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, true)
} else {
(
self.compressed_size as u32,
self.uncompressed_size as u32,
self.offset as u32,
false,
)
};
write_struct( write_struct(
&mut buf, &mut buf,
CentralDirectoryFileHeader { CentralDirectoryFileHeader {
@ -316,33 +332,35 @@ impl ZipEntry {
time, time,
date, date,
crc32: self.crc32, crc32: self.crc32,
compressed_size: 0xFFFFFFFF, compressed_size,
uncompressed_size: 0xFFFFFFFF, uncompressed_size,
filename_len: filename_len as u16, filename_len: filename_len as u16,
extra_field_len: zip_field_size as u16, extra_field_len: if need_zip64 { zip_field_size as u16 } else { 0 },
comment_len: 0, comment_len: 0,
start_disk: 0, start_disk: 0,
internal_flags: 0, internal_flags: 0,
external_flags: (self.mode as u32) << 16 | (!self.is_file as u32) << 4, external_flags: (self.mode as u32) << 16 | (!self.is_file as u32) << 4,
offset: 0xFFFFFFFF, offset,
}, },
) )
.await?; .await?;
buf.write_all(filename).await?; buf.write_all(filename).await?;
write_struct( if need_zip64 {
&mut buf, write_struct(
Zip64FieldWithOffset { &mut buf,
field_type: 1, Zip64FieldWithOffset {
field_size: 3 * 8 + 4, field_type: 1,
uncompressed_size: self.uncompressed_size, field_size: 3 * 8 + 4,
compressed_size: self.compressed_size, uncompressed_size: self.uncompressed_size,
offset: self.offset, compressed_size: self.compressed_size,
start_disk: 0, offset: self.offset,
}, start_disk: 0,
) },
.await?; )
.await?;
}
Ok(size) Ok(size)
} }