use anomalyx_normalize::ParserRegistry;
use proptest::prelude::*;
const MAGICS: &[&[u8]] = &[
b"SQLite format 3\x00", ];
proptest! {
#![proptest_config(ProptestConfig::with_cases(300))]
#[test]
fn normalize_never_panics(
bytes in proptest::collection::vec(any::<u8>(), 0..1024),
ext in "[a-z0-9]{0,6}",
) {
let src = format!("fuzz.{ext}");
let _ = anomalyx_normalize::normalize(&src, &bytes);
}
#[test]
fn normalize_is_deterministic(
bytes in proptest::collection::vec(any::<u8>(), 0..1024),
ext in "[a-z0-9]{0,6}",
) {
let src = format!("fuzz.{ext}");
match (
anomalyx_normalize::normalize(&src, &bytes),
anomalyx_normalize::normalize(&src, &bytes),
) {
(Ok(a), Ok(b)) => prop_assert_eq!(
serde_json::to_string(&a).unwrap(),
serde_json::to_string(&b).unwrap()
),
(Err(a), Err(b)) => prop_assert_eq!(a.to_string(), b.to_string()),
_ => prop_assert!(false, "normalize result varied between identical runs"),
}
}
#[test]
fn every_parser_survives_arbitrary_bytes(
bytes in proptest::collection::vec(any::<u8>(), 0..1024),
) {
let reg = ParserRegistry::default();
for id in reg.ids() {
let _ = reg.normalize_with(id, "fuzz.dat", &bytes);
}
}
#[test]
fn parsers_survive_magic_prefixed_garbage(
which in 0usize..MAGICS.len(),
tail in proptest::collection::vec(any::<u8>(), 0..1024),
) {
let mut bytes = MAGICS[which].to_vec();
bytes.extend_from_slice(&tail);
let reg = ParserRegistry::default();
for id in reg.ids() {
let _ = reg.normalize_with(id, "fuzz.dat", &bytes);
}
let _ = anomalyx_normalize::normalize("fuzz.bin", &bytes);
}
#[test]
fn truncated_text_never_panics(
full in "(\\{\"[a-z]{1,4}\":[0-9]{1,4}\\}\n){1,8}|([a-z]{1,5},){1,5}[a-z]{1,5}\n([0-9]{1,4},){1,5}[0-9]{1,4}\n",
cut in 0usize..256,
) {
let bytes = full.as_bytes();
let end = cut.min(bytes.len());
let reg = ParserRegistry::default();
for id in reg.ids() {
let _ = reg.normalize_with(id, "fuzz.dat", &bytes[..end]);
}
}
}