diff options
Diffstat (limited to 'vendor/chrono/src/round.rs')
-rw-r--r-- | vendor/chrono/src/round.rs | 41 |
1 files changed, 31 insertions, 10 deletions
diff --git a/vendor/chrono/src/round.rs b/vendor/chrono/src/round.rs index b95f24570..f43ab595c 100644 --- a/vendor/chrono/src/round.rs +++ b/vendor/chrono/src/round.rs @@ -24,7 +24,7 @@ pub trait SubsecRound { /// /// # Example /// ``` rust - /// # use chrono::{DateTime, SubsecRound, Timelike, TimeZone, Utc, NaiveDate}; + /// # use chrono::{SubsecRound, Timelike, Utc, NaiveDate}; /// let dt = NaiveDate::from_ymd_opt(2018, 1, 11).unwrap().and_hms_milli_opt(12, 0, 0, 154).unwrap().and_local_timezone(Utc).unwrap(); /// assert_eq!(dt.round_subsecs(2).nanosecond(), 150_000_000); /// assert_eq!(dt.round_subsecs(1).nanosecond(), 200_000_000); @@ -36,7 +36,7 @@ pub trait SubsecRound { /// /// # Example /// ``` rust - /// # use chrono::{DateTime, SubsecRound, Timelike, TimeZone, Utc, NaiveDate}; + /// # use chrono::{SubsecRound, Timelike, Utc, NaiveDate}; /// let dt = NaiveDate::from_ymd_opt(2018, 1, 11).unwrap().and_hms_milli_opt(12, 0, 0, 154).unwrap().and_local_timezone(Utc).unwrap(); /// assert_eq!(dt.trunc_subsecs(2).nanosecond(), 150_000_000); /// assert_eq!(dt.trunc_subsecs(1).nanosecond(), 100_000_000); @@ -75,7 +75,7 @@ where } // Return the maximum span in nanoseconds for the target number of digits. -fn span_for_digits(digits: u16) -> u32 { +const fn span_for_digits(digits: u16) -> u32 { // fast lookup form of: 10^(9-min(9,digits)) match digits { 0 => 1_000_000_000, @@ -111,7 +111,7 @@ pub trait DurationRound: Sized { /// /// # Example /// ``` rust - /// # use chrono::{DateTime, DurationRound, Duration, TimeZone, Utc, NaiveDate}; + /// # use chrono::{DurationRound, Duration, Utc, NaiveDate}; /// let dt = NaiveDate::from_ymd_opt(2018, 1, 11).unwrap().and_hms_milli_opt(12, 0, 0, 154).unwrap().and_local_timezone(Utc).unwrap(); /// assert_eq!( /// dt.duration_round(Duration::milliseconds(10)).unwrap().to_string(), @@ -128,7 +128,7 @@ pub trait DurationRound: Sized { /// /// # Example /// ``` rust - /// # use chrono::{DateTime, DurationRound, Duration, TimeZone, Utc, NaiveDate}; + /// # use chrono::{DurationRound, Duration, Utc, NaiveDate}; /// let dt = NaiveDate::from_ymd_opt(2018, 1, 11).unwrap().and_hms_milli_opt(12, 0, 0, 154).unwrap().and_local_timezone(Utc).unwrap(); /// assert_eq!( /// dt.duration_trunc(Duration::milliseconds(10)).unwrap().to_string(), @@ -178,6 +178,9 @@ where T: Timelike + Add<Duration, Output = T> + Sub<Duration, Output = T>, { if let Some(span) = duration.num_nanoseconds() { + if span < 0 { + return Err(RoundingError::DurationExceedsLimit); + } if naive.timestamp().abs() > MAX_SECONDS_TIMESTAMP_FOR_NANOS { return Err(RoundingError::TimestampExceedsLimit); } @@ -217,6 +220,9 @@ where T: Timelike + Add<Duration, Output = T> + Sub<Duration, Output = T>, { if let Some(span) = duration.num_nanoseconds() { + if span < 0 { + return Err(RoundingError::DurationExceedsLimit); + } if naive.timestamp().abs() > MAX_SECONDS_TIMESTAMP_FOR_NANOS { return Err(RoundingError::TimestampExceedsLimit); } @@ -243,7 +249,7 @@ pub enum RoundingError { /// Error when the Duration exceeds the Duration from or until the Unix epoch. /// /// ``` rust - /// # use chrono::{DateTime, DurationRound, Duration, RoundingError, TimeZone, Utc}; + /// # use chrono::{DurationRound, Duration, RoundingError, TimeZone, Utc}; /// let dt = Utc.with_ymd_and_hms(1970, 12, 12, 0, 0, 0).unwrap(); /// /// assert_eq!( @@ -256,7 +262,7 @@ pub enum RoundingError { /// Error when `Duration.num_nanoseconds` exceeds the limit. /// /// ``` rust - /// # use chrono::{DateTime, DurationRound, Duration, RoundingError, TimeZone, Utc, NaiveDate}; + /// # use chrono::{DurationRound, Duration, RoundingError, Utc, NaiveDate}; /// let dt = NaiveDate::from_ymd_opt(2260, 12, 31).unwrap().and_hms_nano_opt(23, 59, 59, 1_75_500_000).unwrap().and_local_timezone(Utc).unwrap(); /// /// assert_eq!( @@ -269,7 +275,7 @@ pub enum RoundingError { /// Error when `DateTime.timestamp_nanos` exceeds the limit. /// /// ``` rust - /// # use chrono::{DateTime, DurationRound, Duration, RoundingError, TimeZone, Utc}; + /// # use chrono::{DurationRound, Duration, RoundingError, TimeZone, Utc}; /// let dt = Utc.with_ymd_and_hms(2300, 12, 12, 0, 0, 0).unwrap(); /// /// assert_eq!(dt.duration_round(Duration::days(1)), Err(RoundingError::TimestampExceedsLimit),); @@ -304,10 +310,10 @@ impl std::error::Error for RoundingError { #[cfg(test)] mod tests { - use super::{Duration, DurationRound, SubsecRound}; + use super::{Duration, DurationRound, RoundingError, SubsecRound}; use crate::offset::{FixedOffset, TimeZone, Utc}; - use crate::NaiveDate; use crate::Timelike; + use crate::{NaiveDate, NaiveDateTime}; #[test] fn test_round_subsecs() { @@ -760,4 +766,19 @@ mod tests { "1969-12-12 12:10:00 UTC" ); } + + #[test] + fn issue1010() { + let dt = NaiveDateTime::from_timestamp_opt(-4227854320, 1678774288).unwrap(); + let span = Duration::microseconds(-7019067213869040); + assert_eq!(dt.duration_trunc(span), Err(RoundingError::DurationExceedsLimit)); + + let dt = NaiveDateTime::from_timestamp_opt(320041586, 1920103021).unwrap(); + let span = Duration::nanoseconds(-8923838508697114584); + assert_eq!(dt.duration_round(span), Err(RoundingError::DurationExceedsLimit)); + + let dt = NaiveDateTime::from_timestamp_opt(-2621440, 0).unwrap(); + let span = Duration::nanoseconds(-9223372036854771421); + assert_eq!(dt.duration_round(span), Err(RoundingError::DurationExceedsLimit)); + } } |