Zig 0.17.0-dev (Split by item)

This is an example of documentation generated by ZigDoc, an alternative to Zig's built-in Auto Doc feature. See also examples in other modes/formats. The project being documented here (as the example) is the Zig library itself.

testFuzzedCompressInput

Compress.testFuzzedCompressInput
fn testFuzzedCompressInput(fbufs: *const [2][65536]u8, smith: *std.testing.Smith) !void

File

lib/std/compress/flate/Compress.zig:1495

Code

fn testFuzzedCompressInput(fbufs: *const [2][65536]u8, smith: *std.testing.Smith) !void {
    @disableInstrumentation();
    const container = smith.value(flate.Container);
    const good = smith.valueRangeAtMost(u16, 3, 258);
    const nice = smith.valueRangeAtMost(u16, 3, 258);
    const lazy = smith.valueRangeAtMost(u16, 3, nice);
    const chain = smith.valueWeighted(u16, &.{
        .rangeAtMost(u16, if (good <= lazy) 4 else 1, 255, 65536),
        // The following weights are greatly reduced since they increasing take more time to run
        .rangeAtMost(u16, 256, 4095, 256),
        .rangeAtMost(u16, 4096, 32767 + 256, 1),
    });
    var expected_hash: flate.Container.Hasher = .init(container);
    var expected_size: u32 = 0;

    var flate_buf: [128 * 1024]u8 = undefined;
    var flate_w: Writer = .fixed(&flate_buf);
    var deflate_buf: [flate.max_window_len * 2]u8 = undefined;
    const bufsize = smith.valueRangeAtMost(u32, flate.max_window_len, @intCast(deflate_buf.len));
    var deflate_w = try Compress.init(&flate_w, deflate_buf[0..bufsize], container, .{
        .good = good,
        .nice = nice,
        .lazy = lazy,
        .chain = chain,
    });

    var max_output: usize = 32; // Headers / footer
    while (!smith.eosWeightedSimple(7, 1)) {
        const buffered = deflate_w.writer.buffered();
        // Required for repeating patterns and since writing from `buffered` is illegal
        var copy_buf: [512]u8 = undefined;

        const bytes = bytes: switch (smith.valueRangeAtMost(
            u2,
            @intFromBool(buffered.len == 0),
            3,
        )) {
            0 => { // Copy
                const start = smith.valueRangeLessThan(u32, 0, @intCast(buffered.len));
                // Reuse the implementation's history; otherwise, our own would need maintained.
                const from = buffered[start..];
                const len = smith.valueRangeAtMost(u16, 1, copy_buf.len);

                const history_bytes = from[0..@min(from.len, len)];
                @memcpy(copy_buf[0..history_bytes.len], history_bytes);
                const repeat_len = len - history_bytes.len;
                for (
                    copy_buf[history_bytes.len..][0..repeat_len],
                    copy_buf[0..repeat_len],
                ) |*next, prev| {
                    next.* = prev;
                }
                break :bytes copy_buf[0..len];
            },
            1 => { // Bytes
                const fbuf = &fbufs[
                    smith.valueWeighted(u1, &.{
                        .value(FreqBufIndex, .gradient, 3),
                        .value(FreqBufIndex, .random, 1),
                    })
                ];
                const len = smith.valueRangeAtMost(u32, 1, fbuf.len);
                const off = smith.valueRangeAtMost(u32, 0, @intCast(fbuf.len - len));
                break :bytes fbuf[off..][0..len];
            },
            2 => { // Rebase
                const rebaseable = bufsize - rebase_reserved_capacity;
                const capacity = smith.valueRangeAtMost(u32, 1, rebaseable - rebase_min_preserve);
                const preserve = smith.valueRangeAtMost(u32, 0, rebaseable - capacity);
                const failed = deflate_w.writer.rebase(preserve, capacity);
                if (flate_w.buffered().len > max_output) return error.OverheadTooLarge;
                failed catch return; // Wrote too much data and ran out of space
                continue;
            },
            3 => { // Flush
                max_output += 8; // Alignment data
                const failed = deflate_w.writer.flush();
                if (flate_w.buffered().len > max_output) return error.OverheadTooLarge;
                failed catch return; // Wrote too much data and ran out of space
                continue;
            },
        };

        // An overhead of 64 bytes is given for each block since the implementation does not
        // gaurauntee it writes store blocks when optimal. This comes from taking less than 32
        // bytes to write an optimal dynamic block header of mostly bitlen 8 codes and the end
        // of block literal plus `(65536 / 256) / 8`, which is is the maximum number of extra
        // bytes from bitlen 9 codes.
        max_output += bytes.len + ((bytes.len + flate_buf.len - 1) / block_tokens) * 64;
        const failed = deflate_w.writer.writeAll(bytes);
        if (flate_w.buffered().len > max_output) return error.OverheadTooLarge;
        failed catch return; // Wrote too much data and ran out of space
        expected_hash.update(bytes);
        expected_size += @intCast(bytes.len);
    }

    const failed = deflate_w.finish();
    if (flate_w.buffered().len > max_output) return error.OverheadTooLarge;
    failed catch return; // Wrote too much data and ran out of space
    try testingCheckDecompressedMatches(flate_w.buffered(), expected_size, expected_hash);
}