Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

std.zip.Iterator.Entry.extract fails for some zip files #22329

Open
kartikynwa opened this issue Dec 27, 2024 · 0 comments
Open

std.zip.Iterator.Entry.extract fails for some zip files #22329

kartikynwa opened this issue Dec 27, 2024 · 0 comments
Labels
bug Observed behavior contradicts documented or intended behavior

Comments

@kartikynwa
Copy link

Zig Version

0.14.0-dev.2370+5c6b25d9b

Steps to Reproduce and Observed Behavior

1. Prepare the zip files

mkdir ziptest && cd ziptest
head --bytes=100 /dev/urandom > file.txt

# xbps-query -p pkgver zip
# zip-3.0_6
zip compressed_1.zip file.txt
#  adding: file.txt (stored 0%)
zip -fz compressed_2.zip file.txt
#  adding: file.txt (stored 0%)
rm file.txt

2. Prepare the zig code to extract said files

cat <<EOF > extract.zig
const std = @import("std");
const zip = std.zip;

pub fn main() !void {
    var args = std.process.args();
    _ = args.next();
    const zip_path: []const u8 = args.next().?;

    const zip_file = try std.fs.cwd().openFile(zip_path, .{});
    defer zip_file.close();
    const zip_stream = zip_file.seekableStream();

    try std.zip.extract(std.fs.cwd(), zip_stream, .{});

    std.debug.print("Extracted successfully: {s}\n", .{zip_path});
}
EOF

3. Extract the zip files

zig run extract.zig -- compressed_1.zip && rm file.txt
# Extracted successfully: compressed_1.zip
# removed 'file.txt'
zig run extract.zig -- compressed_1.zip && rm file.txt
# error: ZipMismatchCompLen
# /home/ks/stuff/zig/zig-linux-x86_64-0.14.0-dev/lib/std/zip.zig:471:25: 0x1058d46 in extract (extract)
#                         return error.ZipMismatchCompLen;
#                         ^
# /home/ks/stuff/zig/zig-linux-x86_64-0.14.0-dev/lib/std/zip.zig:588:23: 0x105a47a in extract__anon_1914 (extract)
#         const crc32 = try entry.extract(seekable_stream, options, &filename_buf, dest);
#                       ^
# /home/ks/stuff/zig/ziptest/extract.zig:13:5: 0x105aa06 in main (extract)
#     try std.zip.extract(std.fs.cwd(), zip_stream, .{});
#     ^

Expected Behavior

The file compressed_2.zip should be extracted successfully. compressed_2.zip is a perfectly valid zip file that passes integrity checks like:

unzip -t compressed_2.zip
# Archive:  compressed_2.zip
#     testing: file.txt                 OK
# No errors detected in compressed data of compressed_2.zip.

This is happening because the file is created using the -fz flag. I am unsure of zip lore but it causes issue with this part of the zip library's code:

zig/lib/std/zip.zig

Lines 469 to 474 in 30169d1

if (local_header.compressed_size != 0 and
local_header.compressed_size != self.compressed_size)
return error.ZipMismatchCompLen;
if (local_header.uncompressed_size != 0 and
local_header.uncompressed_size != self.uncompressed_size)
return error.ZipMismatchUncompLen;

For this particular zip file both local_header.compressed_size and local_header.uncompressed_size are 0xffffffff. The zip spec says something about when these fields are to be 0xffffffff but it goes over my head. Sorry about that.

@kartikynwa kartikynwa added the bug Observed behavior contradicts documented or intended behavior label Dec 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Observed behavior contradicts documented or intended behavior
Projects
None yet
Development

No branches or pull requests

1 participant