History

add test to check times before unix epoch

Sebastian Thiel committed 4 years ago

Commit eb304ea1 parent e1a14062 files · +20 −2Browse files

Unified · Split

2 files
  1. git-date/src/parse.rs +12 −1
  2. git-date/tests/time/parse.rs +8 −1
git-date/src/parse.rs+12−1
@@ -1,6 +1,8 @@
11 #[derive(thiserror::Error, Debug)]
22 #[allow(missing_docs)]
33 pub enum Error {
4+ #[error("Cannot represent times before UNIX epoch at timestamp {timestamp}")]
5+ TooEarly { timestamp: i64 },
46 #[error("Date string can not be parsed")]
57 InvalidDateString,
68 #[error("Dates past 2038 can not be represented.")]
@@ -44,12 +46,21 @@ pub(crate) mod function { · 37 unmodified lines
4446 // Format::Raw
4547 val
4648 } else if let Some(time) = relative::parse(input, now).transpose()? {
47− Time::new(time.unix_timestamp().try_into()?, time.offset().whole_seconds())
49+ Time::new(timestamp(time)?, time.offset().whole_seconds())
4850 } else {
4951 return Err(Error::InvalidDateString);
5052 })
5153 }
5254
55+ fn timestamp(date: OffsetDateTime) -> Result<u32, Error> {
56+ let timestamp = date.unix_timestamp();
57+ if timestamp < 0 {
58+ Err(Error::TooEarly { timestamp })
59+ } else {
60+ Ok(timestamp.try_into()?)
61+ }
62+ }
63+
5364 fn parse_raw(input: &str) -> Option<Time> {
5465 let mut split = input.split_whitespace();
5566 let seconds_since_unix_epoch: u32 = split.next()?.parse().ok()?;
git-date/tests/time/parse.rs+8−1
@@ -89,6 +89,7 @@ fn invalid_dates_can_be_produced_without_current_time() { · 88 unmodified lines
8989 }
9090
9191 mod relative {
92+ use git_date::parse::Error;
9293 use git_date::time::Sign;
9394 use std::time::SystemTime;
9495 use time::{Duration, OffsetDateTime};
@@ -101,10 +102,16 @@ mod relative { · 6 unmodified lines
101102
102103 #[test]
103104 #[should_panic] // TODO: fix
104− fn large_ffsets_can_panic_elsewhere() {
105+ fn large_offsets_can_panic_elsewhere() {
105106 git_date::parse("9999999999 weeks ago", Some(std::time::UNIX_EPOCH)).ok();
106107 }
107108
109+ #[test]
110+ fn offset_leading_to_before_unix_epoch_cannot_be_represented() {
111+ let err = git_date::parse("1 second ago", Some(std::time::UNIX_EPOCH)).unwrap_err();
112+ assert!(matches!(err, Error::TooEarly{timestamp} if timestamp == -1));
113+ }
114+
108115 #[test]
109116 fn various() {
110117 let now = Some(SystemTime::now());