Skip to content

Commit

Permalink
Parse invalid single-letter timezones as -00:00
Browse files Browse the repository at this point in the history
  • Loading branch information
pitdicker committed Jun 1, 2023
1 parent e3f8fb3 commit af9a12e
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 19 deletions.
11 changes: 6 additions & 5 deletions src/format/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -915,12 +915,13 @@ fn test_rfc2822() {
("Tue, 20 Jan 2015 17:35:20 PDT", Ok("Tue, 20 Jan 2015 17:35:20 -0700")),
("Tue, 20 Jan 2015 17:35:20 PST", Ok("Tue, 20 Jan 2015 17:35:20 -0800")),
("Tue, 20 Jan 2015 17:35:20 pst", Ok("Tue, 20 Jan 2015 17:35:20 -0800")),
// named single-letter military timezones must fallback to +0000
// Z is the only single-letter military timezones that maps to +0000
("Tue, 20 Jan 2015 17:35:20 Z", Ok("Tue, 20 Jan 2015 17:35:20 +0000")),
("Tue, 20 Jan 2015 17:35:20 A", Ok("Tue, 20 Jan 2015 17:35:20 +0000")),
("Tue, 20 Jan 2015 17:35:20 a", Ok("Tue, 20 Jan 2015 17:35:20 +0000")),
("Tue, 20 Jan 2015 17:35:20 K", Ok("Tue, 20 Jan 2015 17:35:20 +0000")),
("Tue, 20 Jan 2015 17:35:20 k", Ok("Tue, 20 Jan 2015 17:35:20 +0000")),
// other named single-letter military timezones must fallback to -0000
("Tue, 20 Jan 2015 17:35:20 A", Ok("Tue, 20 Jan 2015 17:35:20 -0000")),
("Tue, 20 Jan 2015 17:35:20 a", Ok("Tue, 20 Jan 2015 17:35:20 -0000")),
("Tue, 20 Jan 2015 17:35:20 K", Ok("Tue, 20 Jan 2015 17:35:20 -0000")),
("Tue, 20 Jan 2015 17:35:20 k", Ok("Tue, 20 Jan 2015 17:35:20 -0000")),
// named single-letter timezone "J" is specifically not valid
("Tue, 20 Jan 2015 17:35:20 J", Err(INVALID)),
("Tue, 20 Jan 2015😈17:35:20 -0800", Err(INVALID)), // bad character!
Expand Down
27 changes: 13 additions & 14 deletions src/format/scan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -325,30 +325,29 @@ pub(super) fn timezone_offset_2822(s: &str) -> ParseResult<(&str, Option<i32>)>
let name = &s.as_bytes()[..upto];
let s = &s[upto..];
let offset_hours = |o| Ok((s, Some(o * 3600)));
if equals(name, "gmt") || equals(name, "ut") {
offset_hours(0)
// RFC 2822 requires support for some named North America timezones, a small subset of all
// named timezones.
if equals(name, "gmt") || equals(name, "ut") || equals(name, "z") || equals(name, "Z") {
return offset_hours(0);
} else if equals(name, "edt") {
offset_hours(-4)
return offset_hours(-4);
} else if equals(name, "est") || equals(name, "cdt") {
offset_hours(-5)
return offset_hours(-5);
} else if equals(name, "cst") || equals(name, "mdt") {
offset_hours(-6)
return offset_hours(-6);
} else if equals(name, "mst") || equals(name, "pdt") {
offset_hours(-7)
return offset_hours(-7);
} else if equals(name, "pst") {
offset_hours(-8)
return offset_hours(-8);
} else if name.len() == 1 {
match name[0] {
if let b'a'..=b'i' | b'k'..=b'y' | b'A'..=b'I' | b'K'..=b'Y' = name[0] {
// recommended by RFC 2822: consume but treat it as -0000
b'a'..=b'i' | b'k'..=b'z' | b'A'..=b'I' | b'K'..=b'Z' => offset_hours(0),
_ => Err(INVALID),
return Ok((s, None));
}
} else {
Err(INVALID)
}
Err(INVALID)
} else {
let (s_, offset) = timezone_offset(s, |s| Ok(s))?;
Ok((s_, offset))
timezone_offset(s, |s| Ok(s))
}
}

Expand Down

0 comments on commit af9a12e

Please sign in to comment.