Skip to content

ZipArchive does not pick up ZIP64 comment #436

@GPSnoopy

Description

@GPSnoopy

The method ZipArchive::zip64_comment() returns None, even if the zip archive contains a ZIP64 footer.

Using zip version 5.1.1:

use std::fs::File;

fn main() {
    let file = File::create("zip64_comment.zip").unwrap();
    let mut writer = zip::ZipWriter::new(file);
    writer.set_comment("Hello World! (Zip)");
    writer.set_zip64_comment(Some("Hello World! (Zip64)"));
    writer.finish().unwrap();

    let file = File::open("zip64_comment.zip").unwrap();
    let archive = zip::ZipArchive::new(file).unwrap();

    println!("Zip comment: {:?}", archive.comment());
    println!("Zip64 comment: {:?}", archive.zip64_comment());
}

prints (even though a manual inspection confirms that the file contains a ZIP64 header)

Zip comment: [72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33, 32, 40, 90, 105, 112, 41]
Zip64 comment: None

I strongly suspect part of the problem is that the regular ZIP footer contains no indication that there might be a ZIP64 footer. The method Zip32CentralDictoryEnd::may_be_zip64() only checks the number of files and central directory offset limits. With my limited knowledge, I think that the regular ZIP comment length should be set as 0xFFFF, such that a ZIP64 footer can be inferred by the may_be_zip64() method.

pub fn may_be_zip64(&self) -> bool {
    self.number_of_files == u16::MAX || self.central_directory_offset == u32::MAX
}

Indeed, the following works:

use std::fs::File;
use std::io::Write;

fn main() {
    let file = File::create("zip64_comment.zip").unwrap();
    let mut writer = zip::ZipWriter::new(file);
    writer.set_comment("Hello World! (Zip)");
    writer.set_zip64_comment(Some("Hello World! (Zip64)"));

    for i in 0..u16::MAX {
        let name = format!("file_{:08}.txt", i);
        writer
            .start_file(name, zip::write::SimpleFileOptions::default())
            .unwrap();
        writer.write_all(b"Hello World!").unwrap();
    }

    writer.finish().unwrap();

    let file = File::open("zip64_comment.zip").unwrap();
    let archive = zip::ZipArchive::new(file).unwrap();

    println!("Zip comment: {:?}", archive.comment());
    println!("Zip64 comment: {:?}", archive.zip64_comment());
}

and prints:

Zip comment: [72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33, 32, 40, 90, 105, 112, 41]
Zip64 comment: Some([72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33, 32, 40, 90, 105, 112, 54, 52, 41])

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions