Skip to content

Commit d92249f

Browse files
committed
Support RFC3339 timestamps
This extracts @lukesteensen's RFC 3339 timestamp parser from theupdateframework#377. This allows rust-tuf to interoperate better with other TUF implementations, which might include things like microseconds, or not be in the UTC timezone.
1 parent 6229fc6 commit d92249f

File tree

1 file changed

+31
-1
lines changed

1 file changed

+31
-1
lines changed

tuf/src/interchange/cjson/shims.rs

+31-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ use crate::Result;
1111
const SPEC_VERSION: &str = "1.0";
1212

1313
fn parse_datetime(ts: &str) -> Result<DateTime<Utc>> {
14-
Utc.datetime_from_str(ts, "%FT%TZ")
14+
DateTime::parse_from_rfc3339(ts)
15+
.map(|ts| ts.with_timezone(&Utc))
1516
.map_err(|e| Error::Encoding(format!("Can't parse DateTime: {:?}", e)))
1617
}
1718

@@ -570,3 +571,32 @@ mod deserialize_reject_duplicates {
570571
})
571572
}
572573
}
574+
575+
#[cfg(test)]
576+
mod test {
577+
use super::*;
578+
579+
#[test]
580+
fn datetime_formats() {
581+
// The TUF spec says datetimes should be in ISO8601 format, specifically
582+
// "YYYY-MM-DDTHH:MM:SSZ". Since not all TUF clients adhere strictly to that, we choose to
583+
// be more lenient here. The following represent the intersection of valid ISO8601 and
584+
// RFC3339 datetime formats (source: https://ijmacd.github.io/rfc3339-iso8601/).
585+
let valid_formats = [
586+
"2022-08-30T19:53:55Z",
587+
"2022-08-30T19:53:55.7Z",
588+
"2022-08-30T19:53:55.77Z",
589+
"2022-08-30T19:53:55.775Z",
590+
"2022-08-30T19:53:55+00:00",
591+
"2022-08-30T19:53:55.7+00:00",
592+
"2022-08-30T14:53:55-05:00",
593+
"2022-08-30T14:53:55.7-05:00",
594+
"2022-08-30T14:53:55.77-05:00",
595+
"2022-08-30T14:53:55.775-05:00",
596+
];
597+
598+
for format in valid_formats {
599+
assert!(parse_datetime(format).is_ok(), "should parse {:?}", format);
600+
}
601+
}
602+
}

0 commit comments

Comments
 (0)