Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions .github/workflows/fuzzing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,7 @@ jobs:
- name: fuzz
run: |
cargo install cargo-fuzz
set -e
for i in {1..6}; do
cargo fuzz run main -- -max_total_time=300 -rss_limit_mb=4096
done
cargo fuzz run main -- -max_total_time=1800 -rss_limit_mb=4096
- name: minimize corpus
if: always()
run: cargo fuzz cmin main
Expand Down
28 changes: 19 additions & 9 deletions fuzz/fuzz_targets/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

use {arbitrary::Arbitrary, libfuzzer_sys::fuzz_target, smallvec::SmallVec, std::fmt::Debug};

// Upper bound on the harness's test vectors's capacity.
const MAX_CAP: usize = 1024;

/// A generic wrapper that bounds data generated via `arbitrary`.
/// Default cap is 255.
#[derive(Debug, Clone)]
Expand Down Expand Up @@ -47,8 +50,8 @@ enum Op {
New,
WithCapacity(Bounded<usize>),
FromVec,
FromSlice(Bounded<Vec<usize>>),
Push(usize),
FromSlice(Bounded<Vec<u64>>),
Push(u64),
Pop,
Grow(Bounded<usize>),
Reserve(Bounded<usize>),
Expand All @@ -58,12 +61,12 @@ enum Op {
SwapRemove,
Clear,
Remove,
Insert(usize),
Insert(u64),
Drain,
RetainEven,
Dedup,
ExtendFromSlice(Bounded<Vec<usize>>),
Resize(Bounded<usize>, usize),
ExtendFromSlice(Bounded<Vec<u64>>),
Resize(Bounded<usize>, u64),
}

/// Helper to assert equivalence of all structural invariants of `SmallVec`
Expand Down Expand Up @@ -135,12 +138,12 @@ fn test_with_inline_cap<const N: usize>(
u: &mut arbitrary::Unstructured,
ops: &[Op],
) -> arbitrary::Result<()> {
// We let `T` be `usize` instead of `u8` because, albeit less efficient,
// We let `T` be `u64` instead of `u8` because, albeit less efficient,
// this incurs potential memory misalignment which should be properly
// handled by the library.

let mut small_vec = SmallVec::<[usize; N]>::new();
let mut std_vec = Vec::<usize>::new();
let mut small_vec = SmallVec::<[u64; N]>::new();
let mut std_vec = Vec::<u64>::new();

for op in ops {
match op {
Expand Down Expand Up @@ -251,6 +254,13 @@ fn test_with_inline_cap<const N: usize>(
}
}

if small_vec.capacity() > MAX_CAP {
small_vec.truncate(MAX_CAP);
std_vec.truncate(MAX_CAP);
small_vec.shrink_to_fit();
std_vec.shrink_to_fit();
}

assert_invariants(&mut small_vec, &mut std_vec);
}

Expand All @@ -261,7 +271,7 @@ fn run_test(mut u: arbitrary::Unstructured) -> arbitrary::Result<()> {
let ops = Vec::<Op>::arbitrary(&mut u)?;
let dynamic_entropy = u.take_rest();

let run_test = |test_func: fn(&mut arbitrary::Unstructured, &[Op]) -> arbitrary::Result<()>| {
let run_test = |test_func: fn(&mut arbitrary::Unstructured, &[Op]) -> _| {
test_func(&mut arbitrary::Unstructured::new(dynamic_entropy), &ops)
};

Expand Down
Loading