use std::panic::catch_unwind;
use proptest::{
collection::vec,
prelude::{ProptestConfig, Strategy, any},
prop_assert, prop_oneof, proptest,
};
use sciparse::{
core::view::{View, ViewConversionError},
packet::view::ScionRawPacketView,
util::fuzz::packet_shape::bias_to_packet_shape,
};
#[test]
fn parsing_random_packet_data_must_not_panic() {
proptest!(
ProptestConfig::with_cases(5_000),
| (data in rand_packet_data()) | {
random_packet_data_must_not_panic_impl(data)?;
}
);
fn random_packet_data_must_not_panic_impl(
data: Vec<u8>,
) -> Result<(), proptest::prelude::TestCaseError> {
let unwind = catch_unwind(|| {
let mut data = data;
match ScionRawPacketView::try_from_mut_slice(&mut data) {
Ok((view, _rest)) => {
sciparse::util::fuzz::view_function_checks::packet::exec_every_view_function(
view,
);
}
Err(ViewConversionError::BufferTooSmall { .. })
| Err(ViewConversionError::Other(_)) => {
return Ok(());
}
}
Ok(())
});
match unwind {
Ok(res) => res,
Err(panic) => {
println!("{:?}", panic.downcast_ref::<&str>());
prop_assert!(false, "Panic during random packet data parsing");
Ok(())
}
}
}
fn rand_packet_data() -> impl Strategy<Value = Vec<u8>> {
fn shape(mut data: Vec<u8>) -> Vec<u8> {
bias_to_packet_shape(&mut data);
data
}
prop_oneof![
6 => vec(any::<u8>(), 36..=256).prop_map(shape),
3 => vec(any::<u8>(), 36..=1024).prop_map(shape),
1 => vec(any::<u8>(), 0..=1024),
]
}
}