-
Notifications
You must be signed in to change notification settings - Fork 252
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
323 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
|
||
target | ||
corpus | ||
artifacts |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
|
||
[package] | ||
name = "rav1e-fuzz" | ||
version = "0.0.1" | ||
authors = ["Automatically generated"] | ||
publish = false | ||
|
||
[package.metadata] | ||
cargo-fuzz = true | ||
|
||
[dependencies.rav1e] | ||
path = ".." | ||
features = ["decode_test_dav1d"] | ||
[dependencies.libfuzzer-sys] | ||
git = "https://github.com/rust-fuzz/libfuzzer-sys.git" | ||
|
||
# Prevent this from interfering with workspaces | ||
[workspace] | ||
members = ["."] | ||
|
||
[[bin]] | ||
name = "encode_decode" | ||
path = "fuzz_targets/encode_decode.rs" | ||
required-features = ["rav1e/decode_test_dav1d"] | ||
|
||
[[bin]] | ||
name = "encode" | ||
path = "fuzz_targets/encode.rs" | ||
|
||
[[bin]] | ||
name = "construct_context" | ||
path = "fuzz_targets/construct_context.rs" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
#![no_main] | ||
#[macro_use] extern crate libfuzzer_sys; | ||
extern crate rav1e; | ||
use rav1e::fuzzing::*; | ||
|
||
fuzz_target!(|data: &[u8]| { | ||
fuzz_construct_context(data, std::env::var_os("FUZZ_DEBUG").is_some()); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
#![no_main] | ||
#[macro_use] extern crate libfuzzer_sys; | ||
extern crate rav1e; | ||
use rav1e::fuzzing::*; | ||
|
||
fuzz_target!(|data: &[u8]| { | ||
fuzz_encode(data, std::env::var_os("FUZZ_DEBUG").is_some()); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
#![no_main] | ||
#[macro_use] extern crate libfuzzer_sys; | ||
extern crate rav1e; | ||
use rav1e::fuzzing::*; | ||
|
||
fuzz_target!(|data: &[u8]| { | ||
fuzz_encode_decode(data, std::env::var_os("FUZZ_DEBUG").is_some()); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,227 @@ | ||
use std::sync::Arc; | ||
|
||
use arbitrary::*; | ||
|
||
use crate::prelude::*; | ||
|
||
// Adding new fuzz targets | ||
// | ||
// 1. Add a function to this file which looks like this: | ||
// | ||
// pub fn fuzz_something(data: &[u8], debug: bool) { | ||
// let mut g = create_generator!(); | ||
// | ||
// // Invoke everything you need. | ||
// // | ||
// // You should use g.g() to get an arbitrary value of any type that | ||
// // implements Arbitrary [1]. This is how fuzzer affects the | ||
// // execution—by feeding in different bytes, which result in different | ||
// // arbitrary values being generated. | ||
// // [1]: https://docs.rs/arbitrary/0.2.0/arbitrary/trait.Arbitrary.html | ||
// // | ||
// // Print out the structures you create with arbitrary data when debug | ||
// // is set to true. This is for running individual artifacts with | ||
// // FUZZ_DEBUG. | ||
// } | ||
// | ||
// 2. cargo fuzz add something | ||
// 3. Copy the contents of any other .rs file from fuzz/fuzz_targets/ into the | ||
// newly created fuzz/fuzz_targets/something.rs and change the function | ||
// being called to fuzz_something. | ||
// | ||
// Now you can fuzz the new target with cargo fuzz. | ||
|
||
// A helper for generating arbitrary data. | ||
struct Generator<'a> { | ||
buffer: RingBuffer<'a>, | ||
} | ||
|
||
impl<'a> Generator<'a> { | ||
fn new(data: &'a [u8]) -> Result<Self, BufferError> { | ||
Ok(Self { buffer: RingBuffer::new(data, data.len())? }) | ||
} | ||
|
||
fn g<T: Arbitrary>(&mut self) -> T { | ||
<T as Arbitrary>::arbitrary(&mut self.buffer).unwrap() | ||
} | ||
} | ||
|
||
macro_rules! create_generator { | ||
($data:expr) => {{ | ||
let g = Generator::new($data); | ||
if g.is_err() { | ||
return; | ||
} | ||
g.unwrap() | ||
}}; | ||
} | ||
|
||
pub fn fuzz_construct_context(data: &[u8], debug: bool) { | ||
let mut g = create_generator!(data); | ||
|
||
let mut config = Config::default(); | ||
config.threads = 1; | ||
config.enc.width = g.g(); | ||
config.enc.height = g.g(); | ||
config.enc.bit_depth = (g.g::<u8>() % 17) as usize; | ||
config.enc.still_picture = g.g(); | ||
config.enc.time_base = Rational::new(g.g(), g.g()); | ||
config.enc.min_key_frame_interval = g.g(); | ||
config.enc.max_key_frame_interval = g.g(); | ||
config.enc.reservoir_frame_delay = g.g(); | ||
config.enc.low_latency = g.g(); | ||
config.enc.quantizer = g.g(); | ||
config.enc.min_quantizer = g.g(); | ||
config.enc.bitrate = g.g(); | ||
config.enc.tile_cols = g.g(); | ||
config.enc.tile_rows = g.g(); | ||
config.enc.tiles = g.g(); | ||
config.enc.rdo_lookahead_frames = g.g(); | ||
config.enc.speed_settings = SpeedSettings::from_preset(g.g()); | ||
config.enc.show_psnr = g.g(); | ||
config.enc.train_rdo = g.g(); | ||
|
||
if debug { | ||
println!("config = {:#?}", config); | ||
} | ||
|
||
let _: Result<Context<u16>, _> = config.new_context(); | ||
} | ||
|
||
fn encode_frames( | ||
ctx: &mut Context<u8>, mut frames: impl Iterator<Item = Frame<u8>>, | ||
debug: bool, | ||
) -> Result<(), EncoderStatus> { | ||
loop { | ||
let rv = ctx.receive_packet(); | ||
if debug { | ||
println!("ctx.receive_packet() = {:#?}", rv); | ||
} | ||
|
||
match rv { | ||
Ok(_packet) => {} | ||
Err(EncoderStatus::Encoded) => {} | ||
Err(EncoderStatus::LimitReached) => { | ||
break; | ||
} | ||
Err(EncoderStatus::NeedMoreData) => { | ||
ctx.send_frame(frames.next().map(Arc::new))?; | ||
} | ||
Err(EncoderStatus::EnoughData) => { | ||
unreachable!(); | ||
} | ||
Err(EncoderStatus::NotReady) => { | ||
unreachable!(); | ||
} | ||
Err(EncoderStatus::Failure) => { | ||
return Err(EncoderStatus::Failure); | ||
} | ||
} | ||
} | ||
|
||
Ok(()) | ||
} | ||
|
||
pub fn fuzz_encode(data: &[u8], debug: bool) { | ||
let mut g = create_generator!(data); | ||
|
||
let mut config = Config::default(); | ||
config.threads = 1; | ||
config.enc.width = g.g::<u8>() as usize + 1; | ||
config.enc.height = g.g::<u8>() as usize + 1; | ||
config.enc.still_picture = g.g(); | ||
config.enc.time_base = Rational::new(g.g(), g.g()); | ||
config.enc.min_key_frame_interval = (g.g::<u8>() % 4) as u64; | ||
config.enc.max_key_frame_interval = (g.g::<u8>() % 4) as u64 + 1; | ||
config.enc.low_latency = g.g(); | ||
config.enc.quantizer = g.g(); | ||
config.enc.min_quantizer = g.g(); | ||
config.enc.bitrate = g.g(); | ||
// config.enc.tile_cols = g.g(); | ||
// config.enc.tile_rows = g.g(); | ||
// config.enc.tiles = g.g(); | ||
config.enc.rdo_lookahead_frames = g.g(); | ||
config.enc.speed_settings = SpeedSettings::from_preset(10); | ||
|
||
if debug { | ||
println!("config = {:#?}", config); | ||
} | ||
|
||
let res = config.new_context(); | ||
if res.is_err() { | ||
return; | ||
} | ||
let mut context: Context<u8> = res.unwrap(); | ||
|
||
let frame_count = g.g::<u8>() % 3 + 1; | ||
let frames = (0..frame_count).map(|_| { | ||
let mut frame = Frame::new( | ||
config.enc.width, | ||
config.enc.height, | ||
config.enc.chroma_sampling, | ||
); | ||
|
||
for plane in &mut frame.planes { | ||
let stride = plane.cfg.stride; | ||
for row in plane.data_origin_mut().chunks_mut(stride) { | ||
for pixel in row { | ||
*pixel = g.g(); | ||
} | ||
} | ||
} | ||
|
||
frame | ||
}); | ||
|
||
let _ = encode_frames(&mut context, frames, debug); | ||
} | ||
|
||
#[cfg(feature = "decode_test_dav1d")] | ||
pub fn fuzz_encode_decode(data: &[u8], debug: bool) { | ||
use crate::test_encode_decode::*; | ||
|
||
let mut g = create_generator!(data); | ||
|
||
let w = g.g::<u8>() as usize + 1; | ||
let h = g.g::<u8>() as usize + 1; | ||
let speed = 10; | ||
let q = g.g(); | ||
let limit = (g.g::<u8>() % 3) as usize + 1; | ||
let min_keyint = g.g::<u64>() % 4; | ||
let max_keyint = g.g::<u64>() % 4 + 1; | ||
let low_latency = g.g(); | ||
let bitrate = g.g(); | ||
|
||
if debug { | ||
println!( | ||
"w = {:#?}\n\ | ||
h = {:#?}\n\ | ||
speed = {:#?}\n\ | ||
q = {:#?}\n\ | ||
limit = {:#?}\n\ | ||
min_keyint = {:#?}\n\ | ||
max_keyint = {:#?}\n\ | ||
low_latency = {:#?}\n\ | ||
bitrate = {:#?}", | ||
w, h, speed, q, limit, min_keyint, max_keyint, low_latency, bitrate | ||
); | ||
} | ||
|
||
let mut dec = get_decoder::<u8>("dav1d", w, h); | ||
dec.encode_decode( | ||
w, | ||
h, | ||
speed, | ||
q, | ||
limit, | ||
8, | ||
Default::default(), | ||
min_keyint, | ||
max_keyint, | ||
low_latency, | ||
bitrate, | ||
1, | ||
1, | ||
debug, | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters