From ac95e9e8c3da79e09f48a10f05d5fd594d9ccae4 Mon Sep 17 00:00:00 2001 From: Mike Meehan Date: Wed, 18 Jul 2018 22:27:29 -0400 Subject: [PATCH] Add fuzzing, find and fix a parser bug. --- fuzz/.gitignore | 5 +++++ fuzz/Cargo.toml | 22 ++++++++++++++++++++++ fuzz/fuzzers/fuzzer_script_1.rs | 10 ++++++++++ src/lib.rs | 6 +++++- src/tests/fuzzing.rs | 5 ++++- 5 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 fuzz/.gitignore create mode 100644 fuzz/Cargo.toml create mode 100644 fuzz/fuzzers/fuzzer_script_1.rs diff --git a/fuzz/.gitignore b/fuzz/.gitignore new file mode 100644 index 0000000..dfeb7db --- /dev/null +++ b/fuzz/.gitignore @@ -0,0 +1,5 @@ + +target +libfuzzer +corpus +artifacts diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml new file mode 100644 index 0000000..0350800 --- /dev/null +++ b/fuzz/Cargo.toml @@ -0,0 +1,22 @@ + +[package] +name = "dtparse-fuzz" +version = "0.0.1" +authors = ["Automatically generated"] +publish = false + +[package.metadata] +cargo-fuzz = true + +[dependencies.dtparse] +path = ".." +[dependencies.libfuzzer-sys] +git = "https://github.com/rust-fuzz/libfuzzer-sys.git" + +# Prevent this from interfering with workspaces +[workspace] +members = ["."] + +[[bin]] +name = "fuzzer_script_1" +path = "fuzzers/fuzzer_script_1.rs" diff --git a/fuzz/fuzzers/fuzzer_script_1.rs b/fuzz/fuzzers/fuzzer_script_1.rs new file mode 100644 index 0000000..40d7dbe --- /dev/null +++ b/fuzz/fuzzers/fuzzer_script_1.rs @@ -0,0 +1,10 @@ +#![no_main] +extern crate libfuzzer_sys; +extern crate dtparse; +use dtparse::parse; +#[export_name="rust_fuzzer_test_input"] +pub extern fn go(data: &[u8]) { + if let Ok(s) = sd::str::from_utf8(data) { + parse(s); + } +} diff --git a/src/lib.rs b/src/lib.rs index 1b3f71c..680ea7c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -952,7 +952,11 @@ impl Parser { if let Some(value) = info.get_month(&tokens[idx + 4]) { ymd.append(value as i32, &tokens[idx + 4], Some(YMDLabel::Month))?; } else { - ymd.append(tokens[idx + 4].parse::().unwrap(), &tokens[idx + 4], None)?; + if let Ok(val) = tokens[idx + 4].parse::() { + ymd.append(val, &tokens[idx + 4], None)?; + } else { + return Err(ParseInternalError::ValueError("".to_owned())); + } } idx += 2; diff --git a/src/tests/fuzzing.rs b/src/tests/fuzzing.rs index 5f0d842..2508f02 100644 --- a/src/tests/fuzzing.rs +++ b/src/tests/fuzzing.rs @@ -3,13 +3,16 @@ use std::collections::HashMap; use parse; use ParseError; +use ParseInternalError; use Parser; #[test] fn test_fuzz() { assert_eq!(parse("\x2D\x38\x31\x39\x34\x38\x34"), Err(ParseError::InvalidMonth)); - + // Garbage in the third delimited field + assert_eq!(parse("2..\x00\x000d\x00+\x010d\x01\x00\x00\x00+"), + Err(ParseError::InternalError(ParseInternalError::ValueError("".to_owned())))); let default = NaiveDate::from_ymd(2016, 6, 29).and_hms(0, 0, 0); let mut p = Parser::default(); let res = p.parse("\x0D\x31", None, None, false, false, Some(&default), false, HashMap::new()).unwrap();