Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Add fuzzer for the compact custom codec implementation from PR #6720 #7091

Merged
4 commits merged into from
Sep 13, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
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: 5 additions & 0 deletions primitives/npos-elections/fuzzer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ sp-std = { version = "2.0.0-rc6", path = "../../std" }
sp-runtime = { version = "2.0.0-rc6", path = "../../runtime" }
honggfuzz = "0.5"
rand = { version = "0.7.3", features = ["std", "small_rng"] }
codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] }

[[bin]]
name = "reduce"
Expand All @@ -27,3 +28,7 @@ path = "src/reduce.rs"
[[bin]]
name = "balance_solution"
path = "src/balance_solution.rs"

[[bin]]
name = "compact"
path = "src/compact.rs"
39 changes: 39 additions & 0 deletions primitives/npos-elections/fuzzer/src/compact.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use honggfuzz::fuzz;
use sp_npos_elections::generate_solution_type;
use sp_npos_elections::sp_arithmetic::Percent;
use sp_runtime::codec::{Encode, Error};

fn main() {
generate_solution_type!(#[compact] pub struct InnerTestSolutionCompact::<u32, u32, Percent>(16));
loop {
fuzz!(|fuzzer_data: &[u8]| {
let result_decoded: Result<InnerTestSolutionCompact, Error> =
<InnerTestSolutionCompact as codec::Decode>::decode(&mut &fuzzer_data[..]);
match result_decoded {
Ok(decoded) => {
// Decoding works, let's re-encode it and compare results.
let reencoded: std::vec::Vec<u8> = decoded.encode();
// The reencoded value may or may not be equal to the original fuzzer output. However, the
// original decoder should be optimal (in the sense that there is no shorter encoding of
// the same object). So let's see if the fuzzer can find something shorter:
if fuzzer_data.len() < reencoded.len() {
panic!("fuzzer_data.len() < reencoded.len()");
}
// The reencoded value should definitely be decodable (if unwrap() fails that is a valid
// panic/finding for the fuzzer):
let decoded2: InnerTestSolutionCompact =
<InnerTestSolutionCompact as codec::Decode>::decode(
&mut reencoded.as_slice(),
)
.unwrap();
// And it should be equal to the original decoded object (resulting from directly
// decoding fuzzer_data):
assert_eq!(decoded, decoded2);
}
Err(_e) => {
// Can happen, not every random sequence of bytes an be decoded as InnerTestSolutionCompact
}
}
viniul marked this conversation as resolved.
Show resolved Hide resolved
});
}
}