#[cfg(feature = "audio")]
mod audio_fuzz {
use crabcamera::audio::{AudioFrame, OpusEncoder};
use proptest::prelude::*;
proptest! {
#![proptest_config(ProptestConfig::with_cases(1000))]
#[test]
fn fuzz_opus_encoder_creation(
sample_rate in 0u32..100000,
channels in 0u16..10,
bitrate in 0u32..10_000_000,
) {
let _ = OpusEncoder::new(sample_rate, channels, bitrate);
}
#[test]
fn fuzz_opus_encode_samples(
samples in proptest::collection::vec(-2.0f32..2.0f32, 0..10000),
timestamp in 0.0f64..100000.0,
) {
let mut encoder = match OpusEncoder::new(48000, 2, 128000) {
Ok(e) => e,
Err(_) => return Ok(()),
};
let frame = AudioFrame {
samples,
sample_rate: 48000,
channels: 2,
timestamp,
};
let _ = encoder.encode(&frame);
let _ = encoder.flush();
}
#[test]
fn fuzz_opus_mismatched_sample_rate(
frame_sample_rate in 0u32..100000,
samples in proptest::collection::vec(-1.0f32..1.0f32, 0..5000),
) {
let mut encoder = match OpusEncoder::new(48000, 2, 128000) {
Ok(e) => e,
Err(_) => return Ok(()),
};
let frame = AudioFrame {
samples,
sample_rate: frame_sample_rate,
channels: 2,
timestamp: 0.0,
};
let _ = encoder.encode(&frame);
}
#[test]
fn fuzz_opus_mismatched_channels(
frame_channels in 0u16..10,
samples in proptest::collection::vec(-1.0f32..1.0f32, 0..5000),
) {
let mut encoder = match OpusEncoder::new(48000, 2, 128000) {
Ok(e) => e,
Err(_) => return Ok(()),
};
let frame = AudioFrame {
samples,
sample_rate: 48000,
channels: frame_channels,
timestamp: 0.0,
};
let _ = encoder.encode(&frame);
}
}
}
#[cfg(feature = "recording")]
mod recording_fuzz {
use crabcamera::recording::{H264Encoder, RecordingConfig};
use proptest::prelude::*;
proptest! {
#![proptest_config(ProptestConfig::with_cases(500))]
#[test]
fn fuzz_recording_config(
width in 0u32..10000,
height in 0u32..10000,
fps in -100.0f64..1000.0,
bitrate in 0u32..1_000_000_000,
) {
let config = RecordingConfig::new(width, height, fps);
let _ = config.with_bitrate(bitrate);
}
#[test]
fn fuzz_h264_encoder_creation(
width in 0u32..10000,
height in 0u32..10000,
fps in -100.0f64..1000.0,
bitrate in 0u32..100_000_000,
) {
let _ = H264Encoder::new(width, height, fps, bitrate);
}
#[test]
fn fuzz_h264_encode_rgb(
width_mult in 1u32..30,
height_mult in 1u32..30,
rgb_values in proptest::collection::vec(0u8..255, 100..50000),
) {
let width = width_mult * 16;
let height = height_mult * 16;
let expected_size = (width * height * 3) as usize;
let mut encoder = match H264Encoder::new(width, height, 30.0, 1_000_000) {
Ok(e) => e,
Err(_) => return Ok(()),
};
let rgb: Vec<u8> = if rgb_values.len() >= expected_size {
rgb_values[..expected_size].to_vec()
} else {
let mut padded = rgb_values;
padded.resize(expected_size, 128);
padded
};
let _ = encoder.encode_rgb(&rgb);
}
}
}
#[cfg(feature = "recording")]
mod muxer_fuzz {
use proptest::prelude::*;
use std::fs::File;
use tempfile::tempdir;
proptest! {
#![proptest_config(ProptestConfig::with_cases(100))]
#[test]
fn fuzz_muxer_write_video(
pts in 0.0f64..100000.0,
data in proptest::collection::vec(0u8..255, 0..10000),
is_keyframe in proptest::bool::ANY,
) {
use muxide::api::{MuxerBuilder, VideoCodec};
let dir = match tempdir() {
Ok(d) => d,
Err(_) => return Ok(()),
};
let path = dir.path().join("fuzz_test.mp4");
let file = match File::create(&path) {
Ok(f) => f,
Err(_) => return Ok(()),
};
let builder = MuxerBuilder::new(file)
.video(VideoCodec::H264, 640, 480, 30.0);
let mut muxer = match builder.build() {
Ok(m) => m,
Err(_) => return Ok(()),
};
let _ = muxer.write_video(pts, &data, is_keyframe);
}
}
}