Skip to content

zstd decompression regressions (fuzz test results) #24817

Description

@squeek502

Zig Version

master

Steps to Reproduce and Observed Behavior

These results are just testing for crashes/hangs, not correctness (yet).

zstd-fuzz-20250812-1.zip

Easiest way to reproduce the errors:

  • Clone https://github.com/squeek502/zig-std-lib-fuzzing
  • zig build fuzz-zstandard-debug (no AFL++ required, this just builds the pure Zig version for debugging)
  • ./zig-out/bin/fuzz-zstandard-debug < 'path-to-unzipped-repros/crashes/id:000000,sig:06,src:000000,time:8842,execs:3848,op:ext_UO,pos:0'
    • etc, for the rest of the repros

All the crashes have this stack trace:

thread 753422 panic: access of union field 'in_frame' while field 'skipping_frame' is active
/home/ryan/Programming/zig/zig/lib/std/compress/zstd/Decompress.zig:167:53: 0x1159222 in stream (std.zig)
            return readInFrame(d, w, limit, &d.state.in_frame) catch |err| switch (err) {
                                                    ^
/home/ryan/Programming/zig/zig/lib/std/Io/Reader.zig:178:34: 0x107edbe in stream (std.zig)
    const n = try r.vtable.stream(r, w, limit);
                                 ^
/home/ryan/Programming/zig/zig/lib/std/Io/Reader.zig:257:27: 0x114fb75 in streamRemaining (std.zig)
        offset += r.stream(w, .unlimited) catch |err| switch (err) {
                          ^
/home/ryan/Programming/zig/zig-std-lib-fuzzing/fuzzers/zstandard.zig:27:43: 0x114c95d in zigMain (zstandard.zig)
    _ = zstd_stream.reader.streamRemaining(&out.writer) catch {
                                          ^
/home/ryan/Programming/zig/zig-std-lib-fuzzing/fuzzers/zstandard.zig:4:12: 0x114ce61 in main (zstandard.zig)
    zigMain() catch unreachable;
           ^
/home/ryan/Programming/zig/zig/lib/std/start.zig:618:22: 0x114ac1d in posixCallMainAndExit (std.zig)
            root.main();
                     ^
/home/ryan/Programming/zig/zig/lib/std/start.zig:232:5: 0x114a4b1 in _start (std.zig)
    asm volatile (switch (native_arch) {
    ^
???:?:?: 0x0 in ??? (???)

The hangs seem to be the same as the hangs found with flate in #24741, where there's an infinite loop here:

zig/lib/std/Io/Writer.zig

Lines 381 to 383 in 0d0f09f

while (w.buffer.len - w.end < minimum_length) {
try drainPreserve(w, preserve_len);
} else {

but it's being called from here:

const dest = (try w.writableSliceGreedyPreserve(window_len, frame_block_size_max))[0..frame_block_size_max];

Expected Behavior

No crashes/hangs

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