diff --git a/src/items/mod.rs b/src/items/mod.rs index 51fe78a..1f56077 100644 --- a/src/items/mod.rs +++ b/src/items/mod.rs @@ -303,7 +303,7 @@ fn with_timezone_restore( offset: time::Offset, at: DateTime, ) -> Option> { - let offset: FixedOffset = chrono::FixedOffset::from(offset); + let offset: FixedOffset = chrono::FixedOffset::try_from(offset).ok()?; let copy = at; let x = at .with_timezone(&offset) @@ -360,7 +360,9 @@ fn at_date_inner(date: Vec, mut d: DateTime) -> Option { - let offset = offset.map(chrono::FixedOffset::from).unwrap_or(*d.offset()); + let offset = offset + .and_then(|o| chrono::FixedOffset::try_from(o).ok()) + .unwrap_or(*d.offset()); d = new_date( year.map(|x| x as i32).unwrap_or(d.year()), @@ -379,7 +381,10 @@ fn at_date_inner(date: Vec, mut d: DateTime) -> Option { - let offset = offset.map(chrono::FixedOffset::from).unwrap_or(*d.offset()); + let offset = offset + .and_then(|o| chrono::FixedOffset::try_from(o).ok()) + .unwrap_or(*d.offset()); + d = new_date( d.year(), d.month(), diff --git a/src/items/time.rs b/src/items/time.rs index 6177f97..7fa8d3f 100644 --- a/src/items/time.rs +++ b/src/items/time.rs @@ -50,6 +50,8 @@ use winnow::{ ModalResult, Parser, }; +use crate::ParseDateTimeError; + use super::{dec_uint, relative, s}; #[derive(PartialEq, Debug, Clone, Default)] @@ -95,22 +97,33 @@ impl Offset { } } -impl From for chrono::FixedOffset { - fn from( +impl TryFrom for chrono::FixedOffset { + type Error = ParseDateTimeError; + + fn try_from( Offset { negative, hours, minutes, }: Offset, - ) -> Self { + ) -> Result { let secs = hours * 3600 + minutes * 60; - if negative { - FixedOffset::west_opt(secs.try_into().expect("secs overflow")) - .expect("timezone overflow") + let offset = if negative { + FixedOffset::west_opt( + secs.try_into() + .map_err(|_| ParseDateTimeError::InvalidInput)?, + ) + .ok_or(ParseDateTimeError::InvalidInput)? } else { - FixedOffset::east_opt(secs.try_into().unwrap()).unwrap() - } + FixedOffset::east_opt( + secs.try_into() + .map_err(|_| ParseDateTimeError::InvalidInput)?, + ) + .ok_or(ParseDateTimeError::InvalidInput)? + }; + + Ok(offset) } } diff --git a/src/lib.rs b/src/lib.rs index 9462a75..3e36bf0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -266,6 +266,12 @@ mod tests { .and_utc(); assert_eq!(actual, expected); } + + #[test] + fn offset_overflow() { + assert!(parse_datetime("m+12").is_err()); + assert!(parse_datetime("24:00").is_err()); + } } #[cfg(test)]