Skip to content

No way to correctly use zstd.Decompress with tar.pipeToFileSystem #24735

@squeek502

Description

@squeek502

Zig Version

0.15.0-dev.1380+e98aeeb73

Steps to Reproduce and Observed Behavior

Test program (needs compressed_mingw_includes.tar.zst):

const std = @import("std");

pub fn main() !void {
    var debug_allocator: std.heap.DebugAllocator(.{}) = .{};
    defer std.debug.assert(debug_allocator.deinit() == .ok);
    const allocator = debug_allocator.allocator();

    const compressed_input = @embedFile("compressed_mingw_includes.tar.zst");
    const buffer_size = std.compress.zstd.default_window_len + std.compress.zstd.block_size_max;
    const window_buffer = try allocator.create([buffer_size]u8);
    defer allocator.destroy(window_buffer);

    var input_reader: std.Io.Reader = .fixed(compressed_input);
    var decompress: std.compress.zstd.Decompress = .init(&input_reader, window_buffer, .{});

    try std.fs.cwd().deleteTree("out");

    var out_dir = try std.fs.cwd().makeOpenPath("out", .{});
    defer out_dir.close();

    try std.tar.pipeToFileSystem(out_dir, &decompress.reader, .{ .mode_mode = .ignore });
}

This will hit error.OutputBufferUndersize, since tar.pipeToFileSystem uses a writer with a hardcoded buffer of length 1024, which is not enough for zstd.

var file_contents_buffer: [1024]u8 = undefined;

With some debug printing added to show why the error is being returned:

8388608 + 131072 = 8519680 > 8519680
8388608 + 131072 = 8519680 > 1024
error: ReadFailed
/home/ryan/Programming/zig/zig/lib/std/compress/zstd/Decompress.zig:260:75: 0x116894a in readInFrame (std.zig)
                    if (window_len + frame_block_size_max > w.buffer.len) return error.OutputBufferUndersize;
                                                                          ^
/home/ryan/Programming/zig/zig/lib/std/compress/zstd/Decompress.zig:182:21: 0x116ab90 in stream (std.zig)
                    return error.ReadFailed;
                    ^
/home/ryan/Programming/zig/zig/lib/std/Io/Reader.zig:180:15: 0x1084db2 in stream (std.zig)
    const n = try r.vtable.stream(r, w, limit);
              ^
/home/ryan/Programming/zig/zig/lib/std/Io/Reader.zig:223:41: 0x1172792 in streamExact64 (std.zig)
    while (remaining != 0) remaining -= try r.stream(w, .limited64(remaining));
                                        ^
/home/ryan/Programming/zig/zig/lib/std/tar.zig:477:9: 0x1160c60 in streamRemaining (std.zig)
        try it.reader.streamExact64(w, file.size);
        ^
/home/ryan/Programming/zig/zig/lib/std/tar.zig:615:21: 0x1156eba in pipeToFileSystem (std.zig)
                    try it.streamRemaining(file, &file_writer.interface);
                    ^
/home/ryan/Programming/zig/tmp/tarzst/test.zig:21:5: 0x1158410 in main (test.zig)
    try std.tar.pipeToFileSystem(out_dir, &decompress.reader, .{ .mode_mode = .ignore });
    ^

Expected Behavior

Able to use zstd.Decompress with tar.pipeToFileSystem

Metadata

Metadata

Assignees

Labels

bugObserved behavior contradicts documented or intended behaviorregressionIt worked in a previous version of Zig, but stopped working.standard libraryThis issue involves writing Zig code for the standard library.

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions