Skip to content

Commit

Permalink
fix: prevent panics from dates which cannot be represented by the `ti…
Browse files Browse the repository at this point in the history
…me` crate (#720)
  • Loading branch information
Byron committed Feb 4, 2023
1 parent 78517a6 commit 786f6dc
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 8 deletions.
13 changes: 9 additions & 4 deletions git-date/src/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
pub enum Error {
#[error("Cannot represent times before UNIX epoch at timestamp {timestamp}")]
TooEarly { timestamp: i64 },
#[error("Could not convert a duration into a date")]
RelativeTimeConversion,
#[error("Date string can not be parsed")]
InvalidDateString,
#[error("Dates past 2038 can not be represented.")]
Expand Down Expand Up @@ -114,10 +116,13 @@ mod relative {
pub(crate) fn parse(input: &str, now: Option<SystemTime>) -> Option<Result<OffsetDateTime, Error>> {
parse_inner(input).map(|offset| {
let offset = std::time::Duration::from_secs(offset.whole_seconds().try_into()?);
now.ok_or(Error::MissingCurrentTime).map(|now| {
now.checked_sub(offset)
.expect("BUG: values can't be large enough to cause underflow")
.into()
now.ok_or(Error::MissingCurrentTime).and_then(|now| {
std::panic::catch_unwind(|| {
now.checked_sub(offset)
.expect("BUG: values can't be large enough to cause underflow")
.into()
})
.map_err(|_| Error::RelativeTimeConversion)
})
})
}
Expand Down
8 changes: 5 additions & 3 deletions git-date/tests/time/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,11 @@ mod relative {
}

#[test]
#[should_panic] // TODO: fix
fn large_offsets_can_panic_elsewhere() {
git_date::parse("9999999999 weeks ago", Some(std::time::UNIX_EPOCH)).ok();
fn large_offsets_do_not_panic() {
assert!(matches!(
git_date::parse("9999999999 weeks ago", Some(std::time::UNIX_EPOCH)),
Err(git_date::parse::Error::RelativeTimeConversion)
));
}

#[test]
Expand Down
10 changes: 9 additions & 1 deletion git-revision/tests/spec/parse/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,15 @@ mod fuzz {

#[test]
fn failures() {
for spec in ["|^--", "^^-^", "^^-", ":/!-", "A6a^-09223372036854775808", "^^^^^^-("] {
for spec in [
"@{6255520 day ago}: ",
"|^--",
"^^-^",
"^^-",
":/!-",
"A6a^-09223372036854775808",
"^^^^^^-(",
] {
drop(
try_parse_opts(
spec,
Expand Down

0 comments on commit 786f6dc

Please sign in to comment.