mirror of
https://github.com/trussed-dev/cbor-smol.git
synced 2026-06-20 04:17:03 -07:00
Add basic fuzzing
This commit is contained in:
committed by
sosthene-nitrokey
parent
baf84e4811
commit
c75337e658
@@ -0,0 +1,4 @@
|
||||
target
|
||||
corpus
|
||||
artifacts
|
||||
coverage
|
||||
@@ -0,0 +1,31 @@
|
||||
[package]
|
||||
name = "cbor-smol-fuzz"
|
||||
version = "0.0.0"
|
||||
publish = false
|
||||
edition = "2018"
|
||||
|
||||
[package.metadata]
|
||||
cargo-fuzz = true
|
||||
|
||||
[dependencies]
|
||||
libfuzzer-sys = "0.4"
|
||||
arbitrary = { version = "1.2.3", features = ["derive"] }
|
||||
serde = { version = "1.0.152", features = ["derive"] }
|
||||
serde_bytes = "0.11.9"
|
||||
serde_cbor = "0.11.2"
|
||||
|
||||
[dependencies.cbor-smol]
|
||||
path = ".."
|
||||
|
||||
# Prevent this from interfering with workspaces
|
||||
[workspace]
|
||||
members = ["."]
|
||||
|
||||
[profile.release]
|
||||
debug = 1
|
||||
|
||||
[[bin]]
|
||||
name = "fuzz_target_1"
|
||||
path = "fuzz_targets/fuzz_target_1.rs"
|
||||
test = false
|
||||
doc = false
|
||||
@@ -0,0 +1,86 @@
|
||||
#![no_main]
|
||||
|
||||
use arbitrary::{Arbitrary, Unstructured};
|
||||
use libfuzzer_sys::fuzz_target;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, PartialEq, Arbitrary, Serialize, Deserialize)]
|
||||
enum AllEnums {
|
||||
I8(i8),
|
||||
U8(u8),
|
||||
I16(i16),
|
||||
U16(u16),
|
||||
I32(i32),
|
||||
U32(u32),
|
||||
// Not implemented
|
||||
// I64(i64),
|
||||
U64(u64),
|
||||
Struct(Struct),
|
||||
Array([Struct; 4]),
|
||||
Option(Option<Struct>),
|
||||
Vec(Vec<Struct>),
|
||||
Bytes(#[serde(with = "serde_bytes")] Vec<u8>),
|
||||
String(String),
|
||||
Tuple((Struct, Struct)),
|
||||
TupleVariant(Struct, Struct),
|
||||
TupleVariantBytes(Struct, Struct, #[serde(with = "serde_bytes")] Vec<u8>),
|
||||
StructVariant {
|
||||
x: Struct,
|
||||
y: Struct,
|
||||
},
|
||||
StructVariantBytes {
|
||||
x: Struct,
|
||||
y: Struct,
|
||||
#[serde(with = "serde_bytes")]
|
||||
z: Vec<u8>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Arbitrary, Serialize, Deserialize)]
|
||||
struct Struct {
|
||||
a: Box<AllEnums>,
|
||||
b: Box<AllEnums>,
|
||||
}
|
||||
|
||||
/// Workaround https://github.com/rust-fuzz/arbitrary/issues/144
|
||||
#[derive(Debug)]
|
||||
struct Input<'i>(AllEnums, &'i [u8]);
|
||||
|
||||
impl<'i> Arbitrary<'i> for Input<'i> {
|
||||
fn arbitrary(u: &mut Unstructured<'i>) -> Result<Self, arbitrary::Error> {
|
||||
Ok(Self(AllEnums::arbitrary(u)?, Arbitrary::arbitrary(u)?))
|
||||
}
|
||||
|
||||
fn arbitrary_take_rest(mut u: Unstructured<'i>) -> Result<Self, arbitrary::Error> {
|
||||
Ok(Self(
|
||||
AllEnums::arbitrary(&mut u)?,
|
||||
Arbitrary::arbitrary_take_rest(u)?,
|
||||
))
|
||||
}
|
||||
fn size_hint(_depth: usize) -> (usize, Option<usize>) {
|
||||
(0, None)
|
||||
}
|
||||
}
|
||||
|
||||
fuzz_target!(|data: Input<'_>| {
|
||||
let bytes = data.1;
|
||||
let data = data.0;
|
||||
let _res: Option<AllEnums> = cbor_smol::cbor_deserialize(&bytes).ok();
|
||||
let mut buffer = vec![0; 1024 * 20];
|
||||
let res = cbor_smol::cbor_serialize(&data, &mut buffer).unwrap();
|
||||
cbor_smol::cbor_deserialize(&res)
|
||||
.map(|b: AllEnums| {
|
||||
assert_eq!(data, b);
|
||||
})
|
||||
.map_err(|err| {
|
||||
let v: Result<serde_cbor::Value, _> = serde_cbor::from_slice(&res);
|
||||
panic!(
|
||||
"Failed to deserialize: {:?}\n\
|
||||
input: {:#?}\n\
|
||||
data: {:02x?}\n\
|
||||
serde_cbor gives: {:#?}\n",
|
||||
err, data, res, v
|
||||
);
|
||||
})
|
||||
.ok();
|
||||
});
|
||||
Reference in New Issue
Block a user