From 35e38661a7783a04e89015eb149da89f0259f359 Mon Sep 17 00:00:00 2001 From: storybored379 Date: Sun, 4 Oct 2026 21:11:55 -0700 Subject: [PATCH] Metadata: gracefully reject invalid Unicode timezone offsets Co-Authored-By: OpenAI Codex --- crates/meta/src/datetime.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/crates/meta/src/datetime.rs b/crates/meta/src/datetime.rs index ed77ee9e..271aa67d 100644 --- a/crates/meta/src/datetime.rs +++ b/crates/meta/src/datetime.rs @@ -71,7 +71,7 @@ impl DateTime { }; let (h, m) = match rest.split_once(':') { Some((h, m)) => (num(h)?, num(m)?), - None if rest.len() == 4 => (num(&rest[..2])?, num(&rest[2..])?), + None if rest.len() == 4 => (num(rest.get(..2)?)?, num(rest.get(2..)?)?), None => (num(rest)?, 0), }; if h > 18 || m > 59 { @@ -180,6 +180,17 @@ mod tests { assert_eq!(DateTime::parse_offset("+99:00"), None); } + #[test] + fn unicode_offsets_are_rejected_without_panicking() { + for offset in ["+1€", "-1€", "+€1", "-€1"] { + assert_eq!(DateTime::parse_offset(offset), None); + let date = format!("2024-06-01T13:45:59{offset}"); + let metadata = crate::Metadata { capture_time: DateTime::parse_iso("2024-06-01T13:45:59Z"), ..Default::default() }; + let xmp = crate::write_xmp(&metadata, None).replace("2024-06-01T13:45:59+00:00", &date); + assert!(crate::parse_xmp(&xmp).unwrap().metadata.capture_time.is_none()); + } + } + #[test] fn iso_roundtrip() { for s in ["2024-06-01T13:45:59", "2024-06-01T13:45:59.250+02:00", "1999-12-31T23:59:00-05:30", "2024-02-29T00:00:00Z"] {