#![cfg(feature = "matching-regex")]
use proptest::prelude::*;
use vyre_libs::scan::{GpuLiteralSet, RulePipeline};
use vyre_primitives::matching::CompiledDfa;
fn arb_random_bytes() -> impl Strategy<Value = Vec<u8>> {
proptest::collection::vec(any::<u8>(), 0..=512)
}
proptest! {
#![proptest_config(ProptestConfig::with_cases(1024))]
#[test]
fn dfa_from_bytes_never_panics(bytes in arb_random_bytes()) {
let _ = CompiledDfa::from_bytes(&bytes);
}
#[test]
fn literal_set_from_bytes_never_panics(bytes in arb_random_bytes()) {
let _ = GpuLiteralSet::from_bytes(&bytes);
}
#[test]
fn rule_pipeline_from_bytes_never_panics(bytes in arb_random_bytes()) {
let _ = RulePipeline::from_bytes(&bytes);
}
#[test]
fn dfa_single_byte_mutation_safe(
flip_idx in 0usize..=4096,
flip_bit in 0u8..=7,
) {
use vyre_primitives::matching::dfa_compile;
let dfa = dfa_compile(&[b"AKIA".as_slice(), b"ghp_".as_slice()]);
let Ok(mut bytes) = dfa.to_bytes() else {
return Ok(());
};
if flip_idx >= bytes.len() {
return Ok(());
}
bytes[flip_idx] ^= 1u8 << flip_bit;
let _ = CompiledDfa::from_bytes(&bytes);
}
#[test]
fn literal_set_single_byte_mutation_safe(
flip_idx in 0usize..=8192,
flip_bit in 0u8..=7,
) {
let engine = GpuLiteralSet::compile(&[b"AKIA".as_slice(), b"ghp_".as_slice()]);
let Ok(mut bytes) = engine.to_bytes() else {
return Ok(());
};
if flip_idx >= bytes.len() {
return Ok(());
}
bytes[flip_idx] ^= 1u8 << flip_bit;
let _ = GpuLiteralSet::from_bytes(&bytes);
}
#[test]
fn tiny_input_safe(len in 0usize..=32) {
let bytes = vec![0u8; len];
let _ = CompiledDfa::from_bytes(&bytes);
let _ = GpuLiteralSet::from_bytes(&bytes);
let _ = RulePipeline::from_bytes(&bytes);
}
#[test]
fn truncation_at_every_length_safe(
truncate_to in 0usize..=8192,
) {
let engine = GpuLiteralSet::compile(&[b"AKIA".as_slice()]);
let Ok(bytes) = engine.to_bytes() else {
return Ok(());
};
let cut = bytes.len().min(truncate_to);
let _ = GpuLiteralSet::from_bytes(&bytes[..cut]);
}
}