mp4parse_capi/fuzz/fuzz_targets/mp4.rs (54 lines of code) (raw):

#![no_main] use libfuzzer_sys::fuzz_target; use mp4parse_capi::*; use std::convert::TryInto; use std::io::Read; type CursorType<'a> = std::io::Cursor<&'a [u8]>; extern "C" fn vec_read(buf: *mut u8, size: usize, userdata: *mut std::os::raw::c_void) -> isize { let input: &mut CursorType = unsafe { &mut *(userdata as *mut _) }; let buf = unsafe { std::slice::from_raw_parts_mut(buf, size) }; match input.read(buf) { Ok(n) => n.try_into().expect("invalid conversion"), Err(_) => -1, } } fuzz_target!(|data: &[u8]| { let mut cursor: CursorType = std::io::Cursor::new(data); let io = Mp4parseIo { read: Some(vec_read), userdata: &mut cursor as *mut _ as *mut std::os::raw::c_void, }; unsafe { let mut context = std::ptr::null_mut(); if mp4parse_new(&io, &mut context) != Mp4parseStatus::Ok { return; } let mut frag_info = Default::default(); mp4parse_get_fragment_info(context, &mut frag_info); let mut pssh_info = Default::default(); mp4parse_get_pssh_info(context, &mut pssh_info); let mut count = 0; mp4parse_get_track_count(context, &mut count); for track in 0..count { let mut fragmented = 0; mp4parse_is_fragmented(context, track, &mut fragmented); let mut info = Default::default(); mp4parse_get_track_info(context, track, &mut info); match info.track_type { Mp4parseTrackType::Video => { let mut video = Mp4parseTrackVideoInfo::default(); mp4parse_get_track_video_info(context, track, &mut video); } Mp4parseTrackType::Audio => { let mut audio = Default::default(); mp4parse_get_track_audio_info(context, track, &mut audio); } // No C API for metadata tracks yet. Mp4parseTrackType::Metadata => {} // Skip image data - handled by AVIF fuzzer. Mp4parseTrackType::Picture | Mp4parseTrackType::AuxiliaryVideo => {} } let mut indices = Default::default(); mp4parse_get_indice_table(context, track, &mut indices); } mp4parse_free(context); } });