diff --git a/src/lib.rs b/src/lib.rs index 0092f33..e9a3de5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -147,6 +147,8 @@ pub enum ParseError { /// Parser unable to make sense of year/month/day parameters in the time string; /// please report to maintainer as the timestring likely exposes a bug in implementation YearMonthDayError(&'static str), + /// Parser unable to find any date/time-related content in the supplied string + NoDate, } impl fmt::Display for ParseError { @@ -624,6 +626,31 @@ struct ParsingResult { any_unused_tokens: Vec, } +macro_rules! option_len { + ($o:expr) => {{ + if $o.is_some() { + 1 + } else { + 0 + } + }}; +} + +impl ParsingResult { + fn len(&self) -> usize { + option_len!(self.year) + + option_len!(self.month) + + option_len!(self.day) + + option_len!(self.weekday) + + option_len!(self.hour) + + option_len!(self.minute) + + option_len!(self.second) + + option_len!(self.microsecond) + + option_len!(self.tzname) + + option_len!(self.ampm) + } +} + /// Parser is responsible for doing the actual work of understanding a time string. /// The root level `parse` function is responsible for constructing a default `Parser` /// and triggering its behavior. @@ -691,6 +718,10 @@ impl Parser { let (res, tokens) = self.parse_with_tokens(timestr, dayfirst, yearfirst, fuzzy, fuzzy_with_tokens)?; + if res.len() == 0 { + return Err(ParseError::NoDate); + } + let naive = self.build_naive(&res, &default_ts)?; if !ignoretz { diff --git a/src/tests/fuzzing.rs b/src/tests/fuzzing.rs index 48373f3..4fd99d5 100644 --- a/src/tests/fuzzing.rs +++ b/src/tests/fuzzing.rs @@ -17,23 +17,20 @@ fn test_fuzz() { parse("2..\x00\x000d\x00+\x010d\x01\x00\x00\x00+"), Err(ParseError::UnrecognizedFormat) ); - // OverflowError: Python int too large to convert to C long - // assert_eq!(parse("8888884444444888444444444881"), Err(ParseError::AmPmWithoutHour)); + let default = NaiveDate::from_ymd(2016, 6, 29).and_hms(0, 0, 0); let p = Parser::default(); - let res = p - .parse( - "\x0D\x31", - None, - None, - false, - false, - Some(&default), - false, - &HashMap::new(), - ) - .unwrap(); - assert_eq!(res.0, default); + let res = p.parse( + "\x0D\x31", + None, + None, + false, + false, + Some(&default), + false, + &HashMap::new(), + ); + assert_eq!(res, Err(ParseError::NoDate)); assert_eq!( parse("\x2D\x2D\x32\x31\x38\x6D"), @@ -45,5 +42,9 @@ fn test_fuzz() { fn large_int() { let parse_result = parse("1412409095009.jpg"); assert!(parse_result.is_err()); - println!("{:?}", parse_result); +} + +#[test] +fn empty_string() { + assert_eq!(parse(""), Err(ParseError::NoDate)) }