Skip to content

Commit 786f6dc

Browse files
committed
fix: prevent panics from dates which cannot be represented by the time crate (#720)
1 parent 78517a6 commit 786f6dc

File tree

3 files changed

+23
-8
lines changed

3 files changed

+23
-8
lines changed

git-date/src/parse.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
pub enum Error {
44
#[error("Cannot represent times before UNIX epoch at timestamp {timestamp}")]
55
TooEarly { timestamp: i64 },
6+
#[error("Could not convert a duration into a date")]
7+
RelativeTimeConversion,
68
#[error("Date string can not be parsed")]
79
InvalidDateString,
810
#[error("Dates past 2038 can not be represented.")]
@@ -114,10 +116,13 @@ mod relative {
114116
pub(crate) fn parse(input: &str, now: Option<SystemTime>) -> Option<Result<OffsetDateTime, Error>> {
115117
parse_inner(input).map(|offset| {
116118
let offset = std::time::Duration::from_secs(offset.whole_seconds().try_into()?);
117-
now.ok_or(Error::MissingCurrentTime).map(|now| {
118-
now.checked_sub(offset)
119-
.expect("BUG: values can't be large enough to cause underflow")
120-
.into()
119+
now.ok_or(Error::MissingCurrentTime).and_then(|now| {
120+
std::panic::catch_unwind(|| {
121+
now.checked_sub(offset)
122+
.expect("BUG: values can't be large enough to cause underflow")
123+
.into()
124+
})
125+
.map_err(|_| Error::RelativeTimeConversion)
121126
})
122127
})
123128
}

git-date/tests/time/parse.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,11 @@ mod relative {
134134
}
135135

136136
#[test]
137-
#[should_panic] // TODO: fix
138-
fn large_offsets_can_panic_elsewhere() {
139-
git_date::parse("9999999999 weeks ago", Some(std::time::UNIX_EPOCH)).ok();
137+
fn large_offsets_do_not_panic() {
138+
assert!(matches!(
139+
git_date::parse("9999999999 weeks ago", Some(std::time::UNIX_EPOCH)),
140+
Err(git_date::parse::Error::RelativeTimeConversion)
141+
));
140142
}
141143

142144
#[test]

git-revision/tests/spec/parse/mod.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,15 @@ mod fuzz {
240240

241241
#[test]
242242
fn failures() {
243-
for spec in ["|^--", "^^-^", "^^-", ":/!-", "A6a^-09223372036854775808", "^^^^^^-("] {
243+
for spec in [
244+
"@{6255520 day ago}: ",
245+
"|^--",
246+
"^^-^",
247+
"^^-",
248+
":/!-",
249+
"A6a^-09223372036854775808",
250+
"^^^^^^-(",
251+
] {
244252
drop(
245253
try_parse_opts(
246254
spec,

0 commit comments

Comments
 (0)