From e300e447b1b4752f8aa9d26872c2e5993f7dd0b0 Mon Sep 17 00:00:00 2001 From: messense Date: Mon, 2 Jul 2018 13:56:48 +0800 Subject: [PATCH 1/2] Use from_hms_micro_opt instead of from_hms_micro Fixes #9 --- src/lib.rs | 30 ++++++++++++++++++++---------- src/tests.rs | 4 +++- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index c05597d..adff6bf 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -74,13 +74,12 @@ impl From for ParseInternalError { pub enum ParseError { AmbiguousWeekday, InternalError(ParseInternalError), - InvalidDay, InvalidMonth, UnrecognizedToken(String), InvalidParseResult(ParsingResult), AmPmWithoutHour, - InvalidHour, TimezoneUnsupported, + ImpossibleTimestamp(&'static str), } impl From for ParseError { @@ -774,7 +773,7 @@ impl Parser { if fuzzy { Ok(false) } else { - Err(ParseError::InvalidHour) + Err(ParseError::ImpossibleTimestamp("Invalid hour")) } } else { Ok(false) @@ -806,13 +805,24 @@ impl Parser { let d = d + d_offset; - let t = NaiveTime::from_hms_micro( - res.hour.unwrap_or(default.hour() as i32) as u32, - res.minute.unwrap_or(default.minute() as i32) as u32, - res.second.unwrap_or(default.second() as i32) as u32, - res.microsecond - .unwrap_or(default.timestamp_subsec_micros() as i32) as u32, - ); + let hour = res.hour.unwrap_or(default.hour() as i32) as u32; + let minute = res.minute.unwrap_or(default.minute() as i32) as u32; + let second = res.second.unwrap_or(default.second() as i32) as u32; + let microsecond = res.microsecond + .unwrap_or(default.timestamp_subsec_micros() as i32) as u32; + let t = NaiveTime::from_hms_micro_opt(hour, minute, second, microsecond).ok_or_else(|| { + if hour >= 24 { + ParseError::ImpossibleTimestamp("Invalid hour") + } else if minute >= 60 { + ParseError::ImpossibleTimestamp("Invalid minute") + } else if second >= 60 { + ParseError::ImpossibleTimestamp("Invalid second") + } else if microsecond >= 2_000_000 { + ParseError::ImpossibleTimestamp("Invalid microsecond") + } else { + unreachable!(); + } + })?; Ok(NaiveDateTime::new(d, t)) } diff --git a/src/tests.rs b/src/tests.rs index 16e5bc0..5f0d842 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -14,4 +14,6 @@ fn test_fuzz() { let mut p = Parser::default(); let res = p.parse("\x0D\x31", None, None, false, false, Some(&default), false, HashMap::new()).unwrap(); assert_eq!(res.0, default); -} \ No newline at end of file + + assert_eq!(parse("\x2D\x2D\x32\x31\x38\x6D"), Err(ParseError::ImpossibleTimestamp("Invalid minute"))); +} From b3a13405749a021605dbd6bd9072d70e8d7e3fc7 Mon Sep 17 00:00:00 2001 From: messense Date: Tue, 3 Jul 2018 16:44:09 +0800 Subject: [PATCH 2/2] Upgrade rust_decimal to 0.9 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 3f61863..e244d72 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,4 +18,4 @@ name = "dtparse" chrono = "0.4" lazy_static = "1.0" num-traits = "0.2" -rust_decimal = "0.8" +rust_decimal = "0.9"