From be0d54738b8da8329683394a9fbe844653459c5d Mon Sep 17 00:00:00 2001 From: Jean Pierre Dudey Date: Tue, 21 Aug 2018 16:21:29 -0400 Subject: [PATCH] Add fuzz tests for `Decimal`/`UDecimal` parsing. Signed-off-by: Jean Pierre Dudey --- fuzz/Cargo.toml | 10 +++- fuzz/fuzz_targets/deserialize_decimal.rs | 61 +++++++++++++++++++++++ fuzz/fuzz_targets/deserialize_udecimal.rs | 61 +++++++++++++++++++++++ 3 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 fuzz/fuzz_targets/deserialize_decimal.rs create mode 100644 fuzz/fuzz_targets/deserialize_udecimal.rs diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml index 51437b21..990bf0ac 100644 --- a/fuzz/Cargo.toml +++ b/fuzz/Cargo.toml @@ -14,7 +14,7 @@ honggfuzz_fuzz = ["honggfuzz"] [dependencies] honggfuzz = { version = "0.5", optional = true } afl = { version = "0.3", optional = true } -bitcoin = { path = "..", features = ["fuzztarget"] } +bitcoin = { path = "..", features = ["fuzztarget", "serde-decimal"] } # Prevent this from interfering with workspaces [workspace] @@ -35,3 +35,11 @@ path = "fuzz_targets/deserialize_transaction.rs" [[bin]] name = "deserialize_address" path = "fuzz_targets/deserialize_address.rs" + +[[bin]] +name = "deserialize_decimal" +path = "fuzz_targets/deserialize_decimal.rs" + +[[bin]] +name = "deserialize_udecimal" +path = "fuzz_targets/deserialize_udecimal.rs" diff --git a/fuzz/fuzz_targets/deserialize_decimal.rs b/fuzz/fuzz_targets/deserialize_decimal.rs new file mode 100644 index 00000000..002bb760 --- /dev/null +++ b/fuzz/fuzz_targets/deserialize_decimal.rs @@ -0,0 +1,61 @@ +extern crate bitcoin; +use std::str::FromStr; +fn do_test(data: &[u8]) { + let data_str = String::from_utf8_lossy(data); + let dec = match bitcoin::util::decimal::Decimal::from_str(&data_str) { + Ok(dec) => dec, + Err(_) => return, + }; + let dec_roundtrip = match bitcoin::util::decimal::Decimal::from_str(&dec.to_string()) { + Ok(dec) => dec, + Err(_) => return, + }; + assert_eq!(dec, dec_roundtrip); +} + +#[cfg(feature = "afl")] +extern crate afl; +#[cfg(feature = "afl")] +fn main() { + afl::read_stdio_bytes(|data| { + do_test(&data); + }); +} + +#[cfg(feature = "honggfuzz")] +#[macro_use] extern crate honggfuzz; +#[cfg(feature = "honggfuzz")] +fn main() { + loop { + fuzz!(|data| { + do_test(data); + }); + } +} + +#[cfg(test)] +mod tests { + fn extend_vec_from_hex(hex: &str, out: &mut Vec) { + let mut b = 0; + for (idx, c) in hex.as_bytes().iter().enumerate() { + b <<= 4; + match *c { + b'A'...b'F' => b |= c - b'A' + 10, + b'a'...b'f' => b |= c - b'a' + 10, + b'0'...b'9' => b |= c - b'0', + _ => panic!("Bad hex"), + } + if (idx & 1) == 1 { + out.push(b); + b = 0; + } + } + } + + #[test] + fn duplicate_crash() { + let mut a = Vec::new(); + extend_vec_from_hex("00000000", &mut a); + super::do_test(&a); + } +} diff --git a/fuzz/fuzz_targets/deserialize_udecimal.rs b/fuzz/fuzz_targets/deserialize_udecimal.rs new file mode 100644 index 00000000..558b1e31 --- /dev/null +++ b/fuzz/fuzz_targets/deserialize_udecimal.rs @@ -0,0 +1,61 @@ +extern crate bitcoin; +use std::str::FromStr; +fn do_test(data: &[u8]) { + let data_str = String::from_utf8_lossy(data); + let dec = match bitcoin::util::decimal::UDecimal::from_str(&data_str) { + Ok(dec) => dec, + Err(_) => return, + }; + let dec_roundtrip = match bitcoin::util::decimal::UDecimal::from_str(&dec.to_string()) { + Ok(dec) => dec, + Err(_) => return, + }; + assert_eq!(dec, dec_roundtrip); +} + +#[cfg(feature = "afl")] +extern crate afl; +#[cfg(feature = "afl")] +fn main() { + afl::read_stdio_bytes(|data| { + do_test(&data); + }); +} + +#[cfg(feature = "honggfuzz")] +#[macro_use] extern crate honggfuzz; +#[cfg(feature = "honggfuzz")] +fn main() { + loop { + fuzz!(|data| { + do_test(data); + }); + } +} + +#[cfg(test)] +mod tests { + fn extend_vec_from_hex(hex: &str, out: &mut Vec) { + let mut b = 0; + for (idx, c) in hex.as_bytes().iter().enumerate() { + b <<= 4; + match *c { + b'A'...b'F' => b |= c - b'A' + 10, + b'a'...b'f' => b |= c - b'a' + 10, + b'0'...b'9' => b |= c - b'0', + _ => panic!("Bad hex"), + } + if (idx & 1) == 1 { + out.push(b); + b = 0; + } + } + } + + #[test] + fn duplicate_crash() { + let mut a = Vec::new(); + extend_vec_from_hex("00000000", &mut a); + super::do_test(&a); + } +}