address review: limit sanitized names to 255 bytes

This commit is contained in:
Dylan M. Taylor
2026-11-03 12:58:58 +00:00
parent 71dca9fe72
commit 2089117ec0
+17 -3
View File
@@ -1529,9 +1529,15 @@ pub fn numbered_template(template: &str, n: u32) -> String {
/// Make a name safe as a file name component.
pub fn sanitize(name: &str) -> String {
// At most a file name's worth (255 characters): a template repeating a long name token
// must not expand to gigabytes.
let s: String = name.chars().take(255).map(|c| if matches!(c, '/' | '\\' | ':' | '*' | '?' | '"' | '<' | '>' | '|') { '_' } else { c }).collect();
// At most a file name's worth (255 UTF-8 bytes, whole characters only): a template repeating
// a long name token must not expand to gigabytes.
let mut s = String::new();
for c in name.chars() {
if s.len() + c.len_utf8() > 255 {
break;
}
s.push(if matches!(c, '/' | '\\' | ':' | '*' | '?' | '"' | '<' | '>' | '|') { '_' } else { c });
}
// `.` and `..` would name the folder itself or its parent when the token is a path component.
if !s.is_empty() && s.chars().all(|c| c == '.') { "_".repeat(s.len()) } else { s }
}
@@ -1540,6 +1546,14 @@ pub fn sanitize(name: &str) -> String {
mod tests {
use super::*;
#[test]
fn sanitize_limits_the_name_in_bytes() {
// 255 two-byte characters: 127 fit (254 bytes); the 128th would pass the limit.
let s = sanitize(&"é".repeat(255));
assert_eq!(s.len(), 254);
assert!(s.chars().all(|c| c == 'é'));
}
#[test]
fn templates_and_sequences() {
let v = TemplateVars { comp_name: "Main/Title", project_name: "P", width: 1920, height: 1080, frame_rate: 29.97, start_frame: 0, end_frame: 9 };