Skip to content

Commit

Permalink
test: add many_vecs fuzz target
Browse files Browse the repository at this point in the history
  • Loading branch information
bluurryy committed Oct 25, 2024
1 parent 3b17b3d commit ee28ba5
Show file tree
Hide file tree
Showing 7 changed files with 254 additions and 0 deletions.
21 changes: 21 additions & 0 deletions crates/fuzzing-support/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/fuzzing-support/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ edition = "2021"
bump-scope = { path = "../.." }
arbitrary = { version = "1.3.2", features = ["derive"] }
rangemap = "1.5.1"
zerocopy = { version = "0.8.7", features = ["derive"] }
1 change: 1 addition & 0 deletions crates/fuzzing-support/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ pub mod bump_greedy_up;
pub mod bump_up;
pub mod bumping;
mod from_bump_scope;
pub mod many_vecs;

#[derive(Debug, Clone)]
struct RcAllocator<A> {
Expand Down
197 changes: 197 additions & 0 deletions crates/fuzzing-support/src/many_vecs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
use arbitrary::Arbitrary;
use bump_scope::{allocator_api2::alloc::Global, Bump, BumpVec, MinimumAlignment, SupportedMinimumAlignment};
use zerocopy::{FromBytes, Immutable, IntoBytes};

impl Fuzz {
pub fn run(self) {
if self.up {
self.run_dir::<true>();
} else {
self.run_dir::<false>();
}
}

fn run_dir<const UP: bool>(self) {
match self.min_align {
MinAlign::A1 => self.run_dir_align::<UP, 1>(),
MinAlign::A2 => self.run_dir_align::<UP, 2>(),
MinAlign::A3 => self.run_dir_align::<UP, 4>(),
MinAlign::A4 => self.run_dir_align::<UP, 8>(),
MinAlign::A5 => self.run_dir_align::<UP, 16>(),
}
}

fn run_dir_align<const UP: bool, const MIN_ALIGN: usize>(self)
where
MinimumAlignment<MIN_ALIGN>: SupportedMinimumAlignment,
{
let bump: Bump<Global, MIN_ALIGN, UP> = Bump::new();

let mut vecs = self
.vecs
.iter()
.enumerate()
.map(|(i, kind)| {
let pattern = (i % 255) as u8;
match kind {
VecKind::T1 => VecObj::new::<T1, MIN_ALIGN, UP>(&bump, pattern),
VecKind::T2 => VecObj::new::<T2, MIN_ALIGN, UP>(&bump, pattern),
VecKind::T3 => VecObj::new::<T3, MIN_ALIGN, UP>(&bump, pattern),
VecKind::T4 => VecObj::new::<T4, MIN_ALIGN, UP>(&bump, pattern),
VecKind::T5 => VecObj::new::<T5, MIN_ALIGN, UP>(&bump, pattern),
VecKind::T6 => VecObj::new::<T6, MIN_ALIGN, UP>(&bump, pattern),
}
})
.collect::<Vec<_>>();

let vecs_len = vecs.len();

if vecs_len == 0 {
return;
}

for operation in self.operations {
match operation {
Operation::Push(i) => {
let vec = &mut vecs[i % vecs_len];
vec.push();
vec.assert_valid();
}
}

for vec in &vecs {
vec.assert_valid();
}
}
}
}

#[derive(Debug, Arbitrary)]
pub struct Fuzz {
up: bool,
min_align: MinAlign,

vecs: Vec<VecKind>,
operations: Vec<Operation>,
}

#[derive(Debug, Clone, Copy, Arbitrary)]
enum VecKind {
T1,
T2,
T3,
T4,
T5,
T6,
}

#[derive(Debug, Arbitrary)]

enum Operation {
Push(usize),
}

trait VecTrait {
fn push(&mut self, bit_pattern: u8);

fn assert_valid(&self, bit_pattern: u8);
}

struct VecObj<'a> {
vec: Box<dyn VecTrait + 'a>,
bit_pattern: u8,
}

impl<'a> VecObj<'a> {
fn new<T, const MIN_ALIGN: usize, const UP: bool>(bump: &'a Bump<Global, MIN_ALIGN, UP>, bit_pattern: u8) -> Self
where
MinimumAlignment<MIN_ALIGN>: SupportedMinimumAlignment,
T: Default + FromBytes + IntoBytes + Immutable + 'static,
{
Self {
vec: Box::new(BumpVec::<T, Global, MIN_ALIGN, UP>::new_in(bump)),
bit_pattern,
}
}

fn push(&mut self) {
let Self { vec, bit_pattern } = self;
vec.push(*bit_pattern);
}

fn assert_valid(&self) {
let Self { vec, bit_pattern } = self;
vec.assert_valid(*bit_pattern);
}
}

impl<T, const MIN_ALIGN: usize, const UP: bool> VecTrait for BumpVec<'_, '_, T, Global, MIN_ALIGN, UP>
where
MinimumAlignment<MIN_ALIGN>: SupportedMinimumAlignment,
T: Default + FromBytes + IntoBytes + Immutable,
{
fn push(&mut self, bit_pattern: u8) {
self.push(from_bit_pattern(bit_pattern));
}

fn assert_valid(&self, bit_pattern: u8) {
for &byte in self.as_slice().as_bytes() {
assert_eq!(byte, bit_pattern);
}
}
}

fn from_bit_pattern<T: FromBytes + IntoBytes>(byte: u8) -> T {
let mut value = T::new_zeroed();
value.as_mut_bytes().fill(byte);
value
}

#[derive(Debug, Clone, Copy, Arbitrary)]
enum Align {
T1 = 1 << 0,
T2 = 1 << 1,
T3 = 1 << 2,
T4 = 1 << 3,
T5 = 1 << 4,
T6 = 1 << 5,
}

#[derive(Debug, Clone, Copy, Arbitrary)]
enum MinAlign {
A1 = 1,
A2 = 2,
A3 = 4,
A4 = 8,
A5 = 16,
}

#[repr(transparent)]
#[derive(Clone, Default, IntoBytes, FromBytes, Immutable)]
#[allow(dead_code)]
struct T1(u8);

#[repr(transparent)]
#[derive(Clone, Default, IntoBytes, FromBytes, Immutable)]
#[allow(dead_code)]
struct T2(u16);

#[repr(transparent)]
#[derive(Clone, Default, IntoBytes, FromBytes, Immutable)]
#[allow(dead_code)]
struct T3(u32);

#[repr(transparent)]
#[derive(Clone, Default, IntoBytes, FromBytes, Immutable)]
#[allow(dead_code)]
struct T4(u64);

#[repr(transparent)]
#[derive(Clone, Default, IntoBytes, FromBytes, Immutable)]
#[allow(dead_code)]
struct T5([u64; 2]);

#[repr(transparent)]
#[derive(Clone, Default, IntoBytes, FromBytes, Immutable)]
#[allow(dead_code)]
struct T6([u64; 3]);
21 changes: 21 additions & 0 deletions fuzz/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions fuzz/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,10 @@ path = "fuzz_targets/bump_greedy_down.rs"
test = false
doc = false
bench = false

[[bin]]
name = "many_vecs"
path = "fuzz_targets/many_vecs.rs"
test = false
doc = false
bench = false
6 changes: 6 additions & 0 deletions fuzz/fuzz_targets/many_vecs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#![no_main]

use fuzzing_support::many_vecs::Fuzz;
use libfuzzer_sys::fuzz_target;

fuzz_target!(|fuzz: Fuzz| fuzz.run());

0 comments on commit ee28ba5

Please sign in to comment.