Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/znippy-zoomies

linflate/tests/overwrite_headroom.rs

//! The output buffer contract: nothing is ever written past the slice handed
//! to the decoder, even when the output does not fit (`OutputOverflow`, a size
//! guess or a header that was too small), whatever SIMD match copy the CPU
//! picks (AVX-512 copies 64 bytes at a time). Guard bytes behind the slice
//! must stay untouched.

use linflate::{OVERWRITE_HEADROOM, inflate_into};

const GUARD: usize = 4096;

#[test]
fn no_byte_is_written_past_expected_plus_headroom() {
    let mut x: u64 = 0x1234_5678_9abc_def1;
    for case in 0..200 {
        // random bytes, then long matches at distances ≥ 64 up to the very end
        let mut data = Vec::new();
        let n = 2000 + case * 37;
        for _ in 0..n {
            x ^= x << 13;
            x ^= x >> 7;
            x ^= x << 17;
            data.push(x as u8);
        }
        let reps = 3 + case % 11;
        for r in 0..reps {
            let d = 64 + (r * 97 + case) % 900;
            let start = data.len() - d;
            for i in 0..258 {
                let b = data[start + i % d];
                data.push(b);
            }
        }
        let deflate = miniz_oxide::deflate::compress_to_vec(&data, 9);
        // exact, then too small by a little and by a lot
        for short in [0usize, 1, 31, 64, 200, 290, 777, data.len() / 3] {
            let total = (data.len() + OVERWRITE_HEADROOM).saturating_sub(short);
            let mut buf = vec![0xA5u8; total + GUARD];
            let r = inflate_into(&deflate, &mut buf[..total]);
            if short == 0 {
                let n_out = r.expect("decode");
                assert_eq!(&buf[..n_out], &data[..], "case {case}: output");
            }
            if let Some(p) = buf[total..].iter().rposition(|&b| b != 0xA5) {
                panic!(
                    "case {case} short {short}: {} bytes written past the slice",
                    p + 1
                );
            }
        }
    }
}