From 7ec6b30d98b6116c081dc800710ad04f6e098bd3 Mon Sep 17 00:00:00 2001 From: Paul Dicker Date: Sun, 28 May 2023 16:10:02 +0200 Subject: [PATCH] Deny offset when parsing to `NaiveDateTime` --- src/format/parsed.rs | 5 ++++- src/naive/datetime/mod.rs | 15 ++++++++++----- src/naive/datetime/tests.rs | 8 ++++---- src/naive/time/tests.rs | 4 +--- 4 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/format/parsed.rs b/src/format/parsed.rs index 073ba1f5d2..392708ccfd 100644 --- a/src/format/parsed.rs +++ b/src/format/parsed.rs @@ -507,6 +507,9 @@ impl Parsed { /// from date and time fields or a single [`timestamp`](#structfield.timestamp) field. /// Either way those fields have to be consistent to each other. pub fn to_naive_datetime_with_offset(&self, offset: i32) -> ParseResult { + if self.offset.is_some() { + return Err(BAD_FORMAT); + } self.to_naive_datetime_with_offset_inner(offset, true) } @@ -650,7 +653,7 @@ impl Parsed { // `guessed_offset` should be correct when `self.timestamp` is given. // it will be 0 otherwise, but this is fine as the algorithm ignores offset for that case. - let datetime = self.to_naive_datetime_with_offset(guessed_offset)?; + let datetime = self.to_naive_datetime_with_offset_inner(guessed_offset, false)?; match tz.from_local_datetime(&datetime) { LocalResult::None => Err(IMPOSSIBLE), LocalResult::Single(t) => { diff --git a/src/naive/datetime/mod.rs b/src/naive/datetime/mod.rs index af5066aae8..2a4ed35826 100644 --- a/src/naive/datetime/mod.rs +++ b/src/naive/datetime/mod.rs @@ -240,13 +240,18 @@ impl NaiveDateTime { /// Ok(NaiveDate::from_ymd_opt(2015, 9, 5).unwrap().and_hms_micro_opt(13, 23, 45, 678_900).unwrap())); /// ``` /// - /// Offset is ignored for the purpose of parsing. + /// An included offset will return an error, parse to a `DateTime` first. /// /// ``` - /// # use chrono::{NaiveDateTime, NaiveDate}; - /// # let parse_from_str = NaiveDateTime::parse_from_str; - /// assert_eq!(parse_from_str("2014-5-17T12:34:56+09:30", "%Y-%m-%dT%H:%M:%S%z"), - /// Ok(NaiveDate::from_ymd_opt(2014, 5, 17).unwrap().and_hms_opt(12, 34, 56).unwrap())); + /// use chrono::{DateTime, NaiveDateTime, NaiveDate, FixedOffset}; + /// use chrono::format::ParseErrorKind; + /// + /// let r = NaiveDateTime::parse_from_str("2014-5-17T12:34:56+09:30", "%Y-%m-%dT%H:%M:%S%z"); + /// assert_eq!(r.unwrap_err().kind(), ParseErrorKind::BadFormat); + /// let dt = + /// DateTime::::parse_from_str("2014-5-17T12:34:56+09:30", "%Y-%m-%dT%H:%M:%S%z"); + /// assert_eq!(dt.unwrap().naive_local(), + /// NaiveDate::from_ymd_opt(2014, 5, 17).unwrap().and_hms_opt(12, 34, 56).unwrap()); /// ``` /// /// [Leap seconds](./struct.NaiveTime.html#leap-second-handling) are correctly handled by diff --git a/src/naive/datetime/tests.rs b/src/naive/datetime/tests.rs index 96ff3b15b5..ecb1939a0e 100644 --- a/src/naive/datetime/tests.rs +++ b/src/naive/datetime/tests.rs @@ -281,10 +281,6 @@ fn test_datetime_parse_from_str() { let ymdhmsn = |y, m, d, h, n, s, nano| { NaiveDate::from_ymd_opt(y, m, d).unwrap().and_hms_nano_opt(h, n, s, nano).unwrap() }; - assert_eq!( - NaiveDateTime::parse_from_str("2014-5-7T12:34:56+09:30", "%Y-%m-%dT%H:%M:%S%z"), - Ok(ymdhms(2014, 5, 7, 12, 34, 56)) - ); // ignore offset assert!( // intermixed whitespace NaiveDateTime::parse_from_str("2015-W06-1 000000", "%G-W%V-%u%H%M%S").is_err() @@ -324,6 +320,10 @@ fn test_datetime_parse_from_str() { NaiveDateTime::parse_from_str("1437742189.918273645", "%s%.9f"), Ok(ymdhmsn(2015, 7, 24, 12, 49, 49, 918273645)) ); + + assert!( + NaiveDateTime::parse_from_str("2014-5-7T12:34:56+09:30", "%Y-%m-%dT%H:%M:%S%z").is_err() + ); } #[test] diff --git a/src/naive/time/tests.rs b/src/naive/time/tests.rs index a26ced32bc..0b3450cef8 100644 --- a/src/naive/time/tests.rs +++ b/src/naive/time/tests.rs @@ -342,9 +342,7 @@ fn test_time_parse_from_str() { assert!(NaiveTime::parse_from_str("2014-5-7T12:34:56", "%Y-%m-%dT%H:%M:%S").is_err()); assert!(NaiveTime::parse_from_str("12:34:56+09:30", "%%H:%M:%S%z").is_err()); - assert!( - NaiveTime::parse_from_str("2014-5-7T12:34:56+09:30", "%Y-%m-%dT%H:%M:%S%z").is_err() - ); + assert!(NaiveTime::parse_from_str("2014-5-7T12:34:56+09:30", "%Y-%m-%dT%H:%M:%S%z").is_err()); } #[test]