Skip to content

Commit

Permalink
fuzz: fuzzing decimal (#3190)
Browse files Browse the repository at this point in the history
  • Loading branch information
overvenus committed Jun 26, 2018
1 parent ab69d21 commit 472bc2f
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 2 deletions.
4 changes: 4 additions & 0 deletions fuzz/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,7 @@ git = "https://github.com/rust-fuzz/libfuzzer-sys.git"
[[bin]]
name = "codec_bytes"
path = "fuzz_targets/codec_bytes.rs"

[[bin]]
name = "coprocessor_codec_mysql_decimal"
path = "fuzz_targets/coprocessor/codec/mysql/decimal.rs"
3 changes: 2 additions & 1 deletion fuzz/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ Fuzz testing for TiKV.

Currently, it targets in following components:

- tikv::util::codec::bytes
- `tikv::util::codec::bytes`
- `tikv::coprocessor::codec::mysql::decimal::Decimal`

To run fuzz testing, you need to install `cargo-fuzz`:

Expand Down
76 changes: 76 additions & 0 deletions fuzz/fuzz_targets/coprocessor/codec/mysql/decimal.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#![no_main]
#[macro_use]
extern crate libfuzzer_sys;
extern crate tikv;

use std::mem;
use tikv::coprocessor::codec::mysql::decimal::{Decimal, RoundMode};

fn make_u64<I>(iter: &mut I) -> u64
where
I: Iterator<Item = u8>,
{
let mut bytes = [0u8; 8];
for byte in bytes.iter_mut() {
*byte = iter.next().unwrap();
}
unsafe { mem::transmute(bytes) }
}

fn fuzz<I>(lhs: &Decimal, rhs: &Decimal, iter: &mut I)
where
I: Iterator<Item = u8>,
{
let _ = lhs.clone().abs();
let _ = lhs.ceil();
let _ = lhs.floor();
let _ = lhs.prec_and_frac();

let mode = match iter.next().unwrap() % 3 {
0 => RoundMode::HalfEven,
1 => RoundMode::Truncate,
_ => RoundMode::Ceiling,
};
let frac = iter.next().unwrap() as i8;
let _ = lhs.clone().round(frac, mode.clone());

let shift = make_u64(iter) as isize;
let _ = lhs.clone().shift(shift);

let _ = lhs.as_i64();
let _ = lhs.as_u64();
let _ = lhs.as_f64();
let _ = lhs.is_zero();
let _ = lhs.approximate_encoded_size();

let frac_inc = iter.next().unwrap();
lhs.clone().div(rhs.clone(), frac_inc);

let _ = lhs > rhs;

let _ = lhs + rhs;
let _ = lhs - rhs;
let _ = lhs * rhs;
let _ = lhs.clone() / rhs.clone();
let _ = lhs.clone() % rhs.clone();
let _ = -lhs.clone();
}

fuzz_target!(|data: &[u8]| {
if data.is_empty() {
return;
}
let mut iter = data.iter().cycle().cloned();
let f1 = f64::from_bits(make_u64(&mut iter));
let f2 = f64::from_bits(make_u64(&mut iter));
let decimal1 = Decimal::from_f64(f1);
let decimal2 = Decimal::from_f64(f2);

let (decimal1, decimal2) = match (decimal1, decimal2) {
(Ok(d1), Ok(d2)) => (d1, d2),
_ => return,
};

fuzz(&decimal1, &decimal2, &mut iter);
fuzz(&decimal2, &decimal1, &mut iter);
});
2 changes: 1 addition & 1 deletion src/coprocessor/codec/mysql/decimal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -841,7 +841,7 @@ pub struct Decimal {
word_buf: Box<[u32]>,
}

#[derive(Debug)]
#[derive(Debug, Clone)]
pub enum RoundMode {
// HalfEven rounds normally.
HalfEven,
Expand Down

0 comments on commit 472bc2f

Please sign in to comment.