From 3cfd7e461fa50fea959ef9f60c588673488cd080 Mon Sep 17 00:00:00 2001 From: NetterSilver <133535268+Silvertree2010@users.noreply.github.com> Date: Wed, 28 Oct 2026 09:09:43 +0100 Subject: [PATCH] Fix Align Video to Data panic on multi-byte char in timestamp Found while testing crates/engine/src/cmd/align_data.rs:75 (parse_stamp) Co-Authored-By: Claude Haiku 5.5 Co-Authored-By: Claude Sonnet 5.5 --- crates/engine/src/cmd/align_data.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/crates/engine/src/cmd/align_data.rs b/crates/engine/src/cmd/align_data.rs index 38d9e7841..99ed3d113 100644 --- a/crates/engine/src/cmd/align_data.rs +++ b/crates/engine/src/cmd/align_data.rs @@ -72,9 +72,9 @@ pub fn parse_stamp(v: &Value, fps: f64) -> Option { } // ISO 8601: date [T| ] time [zone]. if s.len() >= 10 && s.as_bytes()[4] == b'-' && s.as_bytes()[7] == b'-' { - let (y, m, d) = (s[0..4].parse::().ok()?, s[5..7].parse::().ok()?, s[8..10].parse::().ok()?); + let (y, m, d) = (s.get(0..4)?.parse::().ok()?, s.get(5..7)?.parse::().ok()?, s.get(8..10)?.parse::().ok()?); let mut secs = days_from_civil(y, m, d)? as f64 * 86_400.0; - let rest = s[10..].trim_start_matches(['T', 't', ' ']); + let rest = s.get(10..)?.trim_start_matches(['T', 't', ' ']); if !rest.is_empty() { // Zone: Z or ±hh:mm / ±hhmm. let (time, zone) = match rest.find(['Z', 'z', '+']).or_else(|| rest.rfind('-')) { @@ -229,6 +229,12 @@ pub fn specs() -> Vec { mod tests { use super::*; + #[test] + fn multibyte_date_is_rejected() { + assert_eq!(parse_stamp(&json!("2026-05-0é"), 25.0), None); + assert_eq!(parse_stamp(&json!("2026-05-01é"), 25.0), None); + } + #[test] fn parses_timestamps() { let p = |v: Value| parse_stamp(&v, 25.0).unwrap();