Skip to content

Commit

Permalink
fix: Stricter raw date parsing
Browse files Browse the repository at this point in the history
The raw date parser (git_date::parse::function::parse_raw()) accepted some
inputs that it should not have. Specifically, it would accept:

- Any character for the timezone offset's sign
- Trailing, non-whitespace characters after the timezone offset

Now either '+' or '-' is required for the timezone offset sign and only
trailing whitespace is allowed.

Additional tests are added to cover both acceptable and unacceptable
inputs.

N.B. the raw date parser is still accepting of whitespace leading, in the
middle of, and trailing the date string. A yet stricter parser would only
allow a single space character between the seconds-since-epoch and the
timezone offset.

Signed-off-by: Peter Grayson <pete@jpgrayson.net>
  • Loading branch information
jpgrayson committed Dec 31, 2022
1 parent a910d9e commit 046af94
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 11 deletions.
8 changes: 6 additions & 2 deletions git-date/src/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,14 @@ pub(crate) mod function {
let mut split = input.split_whitespace();
let seconds_since_unix_epoch: u32 = split.next()?.parse().ok()?;
let offset = split.next()?;
if offset.len() != 5 {
if offset.len() != 5 || split.next().is_some() {
return None;
}
let sign = if &offset[..1] == "-" { Sign::Minus } else { Sign::Plus };
let sign = match &offset[..1] {
"-" => Some(Sign::Minus),
"+" => Some(Sign::Plus),
_ => None,
}?;
let hours: i32 = offset[1..3].parse().ok()?;
let minutes: i32 = offset[3..5].parse().ok()?;
let mut offset_in_seconds = hours * 3600 + minutes * 60;
Expand Down
42 changes: 33 additions & 9 deletions git-date/tests/time/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,17 +65,41 @@ fn raw() {
offset_in_seconds: 28800,
sign: Sign::Plus,
},
"could not parse with raw format"
);

assert_eq!(
git_date::parse("1660874655 -0800", None).unwrap(),
Time {
seconds_since_unix_epoch: 1660874655,
offset_in_seconds: -28800,
sign: Sign::Minus,
},
);
let expected = Time {
seconds_since_unix_epoch: 1660874655,
offset_in_seconds: -28800,
sign: Sign::Minus,
};
for date_str in [
"1660874655 -0800",
"1660874655 -0800 ",
" 1660874655 -0800",
" 1660874655 -0800 ",
" 1660874655 -0800 ",
"1660874655\t-0800",
] {
assert_eq!(git_date::parse(date_str, None).unwrap(), expected);
}
}

#[test]
fn bad_raw() {
for bad_date_str in [
"123456 !0600",
"123456 +060",
"123456 -060",
"123456 +06000",
"123456 06000",
"123456 0600",
"123456 +0600 extra",
"-123456 +0600",
"123456+0600",
"123456 + 600",
] {
assert!(git_date::parse(bad_date_str, None).is_err());
}
}

#[test]
Expand Down

0 comments on commit 046af94

Please sign in to comment.