moodmosaic

Fuzzing The Money Parser With libFuzzer

This post is part of the Input Coverage > Code Coverage series.

Add a fuzz target. Keep it small.

fuzz/fuzz_targets/parse_money.rs:

#![no_main]
use libfuzzer_sys::fuzz_target;

fuzz_target!(|data: &[u8]| {
    if let Ok(s) = std::str::from_utf8(data) {
        let had_minus = money_amounts::contains_any_minus(s);
        if let Ok(v) = money_amounts::parse_money(s) {
            if had_minus {
                assert!(v <= 0, "minus present but value positive");
            }
            let canon = money_amounts::format_cents(v);
            let v2 = money_amounts::parse_money(&canon).unwrap();
            assert_eq!(v, v2);
        }
    }
});

Run:

cargo install cargo-fuzz
rustup toolchain install nightly
cargo +nightly fuzz run parse_money -max_total_time=60

Expect a crash input with U+2212. Fix by normalizing Unicode minus to ASCII -. Add the crash as a test.


Next: Enterprise Case 2: CSV Import CLI, Unbounded Header