diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml index c93ef06ce..22b42fbe7 100644 --- a/fuzz/Cargo.toml +++ b/fuzz/Cargo.toml @@ -35,3 +35,10 @@ path = "fuzzers/parse_date.rs" test = false doc = false bench = false + +[[bin]] +name = "parse_duration" +path = "fuzzers/parse_duration.rs" +test = false +doc = false +bench = false diff --git a/fuzz/fuzzers/parse_duration.rs b/fuzz/fuzzers/parse_duration.rs new file mode 100644 index 000000000..145fca15b --- /dev/null +++ b/fuzz/fuzzers/parse_duration.rs @@ -0,0 +1,31 @@ +#![no_main] + +use libfuzzer_sys::fuzz_target; + +fuzz_target!(|data: &[u8]| test_parse_duration(data)); + +pub fn test_parse_duration(data: &[u8]) { + use std::str::from_utf8; + use std::str::FromStr; + + // input must be text + let Ok(original_text) = from_utf8(data) else { + return; + }; + + // parse input as a duration + let Ok(duration) = prost_types::Duration::from_str(original_text) else { + if original_text.ends_with("s") { + assert!( + original_text.parse::().is_err(), + "prost failed to parse duration, but it seems to be a valid number: {}", + original_text + ); + } + return; + }; + + // roundtrip to and from string + let roundtrip_text = format!("{duration}"); + assert_eq!(Ok(&duration), roundtrip_text.parse().as_ref()); +}