Skip to content

data_start is incorrect when reading an aligned file #33

Closed
@danielocfb

Description

@danielocfb

I tried upgrading to version 1.1 and it seems as if handling of alignment is broken.

use std::env;
use std::fs::read as read_file;
use std::fs::File;
use std::io::Write as _;
use std::path::Path;

use zip::write::SimpleFileOptions;
use zip::CompressionMethod;
use zip::ZipArchive;
use zip::ZipWriter;

fn main() {
    let page_size = 4096;
    let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
    let dst_dir = Path::new(&crate_dir);
    let dst_file = dst_dir.join("test.zip");

    {
        let dst_file = File::options()
            .create(true)
            .truncate(true)
            .read(false)
            .write(true)
            .open(&dst_file)
            .unwrap();

        let options = SimpleFileOptions::default()
            .compression_method(CompressionMethod::Stored)
            .with_alignment(page_size.try_into().unwrap());
        let mut zip = ZipWriter::new(dst_file);
        let contents = read_file("/usr/bin/sleep").unwrap();
        let () = zip.start_file("sleep", options).unwrap();
        let _count = zip.write(&contents).unwrap();
    }

    {
        let dst_file = File::open(dst_file).unwrap();
        let mut zip = ZipArchive::new(dst_file).unwrap();
        let file = zip.by_index(0).unwrap();
        assert_eq!(file.name(), "sleep");
        assert_eq!(file.data_start(), page_size);
    }
}

fails with:

thread 'main' panicked at src/main.rs:41:9:
assertion `left == right` failed
  left: 4092
 right: 4096
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Similar code on 0.6.4 works fine:

use std::env;
use std::fs::read as read_file;
use std::fs::File;
use std::io::Write as _;
use std::path::Path;

use zip::write::FileOptions;
use zip::CompressionMethod;
use zip::ZipArchive;
use zip::ZipWriter;

fn main() {
    let page_size = 4096;
    let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
    let dst_dir = Path::new(&crate_dir);
    let dst_file = dst_dir.join("test.zip");

    {
        let dst_file = File::options()
            .create(true)
            .truncate(true)
            .read(false)
            .write(true)
            .open(&dst_file)
            .unwrap();

        let options = FileOptions::default().compression_method(CompressionMethod::Stored);
        let mut zip = ZipWriter::new(dst_file);
        let contents = read_file("/usr/bin/sleep").unwrap();
        let _align = zip
            .start_file_aligned(
                "sleep",
                options,
                page_size.try_into().unwrap(),
            )
            .unwrap();
        let _count = zip.write(&contents).unwrap();
    }

    {
        let dst_file = File::open(dst_file).unwrap();
        let mut zip = ZipArchive::new(dst_file).unwrap();
        let file = zip.by_index(0).unwrap();
        assert_eq!(file.name(), "sleep");
        assert_eq!(file.data_start(), page_size);
    }
}

Am I misunderstanding what is being aligned?

Metadata

Metadata

Assignees

No one assigned

    Labels

    fix mergedFix is merged, but the issue will stay open until it's released.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions