[pbs-devel] [RFC PATCH proxmox-backup 2/3] tools/zip: only add zip64 field when necessary

Dominik Csapak d.csapak at proxmox.com
Mon Mar 15 12:21:17 CET 2021


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

Signed-off-by: Dominik Csapak <d.csapak at proxmox.com>
---
it does not harm normally, but can blow up the size of the zip a bit
if one has many small files

 src/tools/zip.rs | 52 ++++++++++++++++++++++++++++++++----------------
 1 file changed, 35 insertions(+), 17 deletions(-)

diff --git a/src/tools/zip.rs b/src/tools/zip.rs
index cca2e766..55f2a24a 100644
--- a/src/tools/zip.rs
+++ b/src/tools/zip.rs
@@ -301,10 +301,26 @@ impl ZipEntry {
         let filename_len = filename.len();
         let header_size = size_of::<CentralDirectoryFileHeader>();
         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 (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(
             &mut buf,
             CentralDirectoryFileHeader {
@@ -316,33 +332,35 @@ impl ZipEntry {
                 time,
                 date,
                 crc32: self.crc32,
-                compressed_size: 0xFFFFFFFF,
-                uncompressed_size: 0xFFFFFFFF,
+                compressed_size,
+                uncompressed_size,
                 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,
                 start_disk: 0,
                 internal_flags: 0,
                 external_flags: (self.mode as u32) << 16 | (!self.is_file as u32) << 4,
-                offset: 0xFFFFFFFF,
+                offset,
             },
         )
         .await?;
 
         buf.write_all(filename).await?;
 
-        write_struct(
-            &mut buf,
-            Zip64FieldWithOffset {
-                field_type: 1,
-                field_size: 3 * 8 + 4,
-                uncompressed_size: self.uncompressed_size,
-                compressed_size: self.compressed_size,
-                offset: self.offset,
-                start_disk: 0,
-            },
-        )
-        .await?;
+        if need_zip64 {
+            write_struct(
+                &mut buf,
+                Zip64FieldWithOffset {
+                    field_type: 1,
+                    field_size: 3 * 8 + 4,
+                    uncompressed_size: self.uncompressed_size,
+                    compressed_size: self.compressed_size,
+                    offset: self.offset,
+                    start_disk: 0,
+                },
+            )
+            .await?;
+        }
 
         Ok(size)
     }
-- 
2.20.1






More information about the pbs-devel mailing list