mirror of
https://github.com/storytold/deckcraft.git
synced 2026-11-03 08:50:47 -06:00
Use a short temp file name in write_file for long file names
Found while testing crates/engine/src/io.rs:49 Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com> Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Haiku 5.5
parent
0d45a64db2
commit
77cd617596
+17
-2
@@ -41,12 +41,13 @@ pub fn write_file(path: &str, bytes: &[u8]) -> Result<(), String> {
|
||||
Ok(canonical) => canonical,
|
||||
Err(_) => std::path::PathBuf::from(path),
|
||||
};
|
||||
let target_str = target_path.to_str().unwrap_or(path);
|
||||
let existing_perms = std::fs::metadata(&target_path).ok().map(|m| m.permissions());
|
||||
|
||||
let mut attempts = 0;
|
||||
let (tmp, mut file) = loop {
|
||||
let tmp = format!("{target_str}.{}.{}.saving", std::process::id(), COUNTER.fetch_add(1, Ordering::Relaxed));
|
||||
// A short fixed-size name: appending to the target's name could exceed the file name limit.
|
||||
let tmp_name = format!(".deckcraft.{}.{}.saving", std::process::id(), COUNTER.fetch_add(1, Ordering::Relaxed));
|
||||
let tmp = target_path.with_file_name(tmp_name);
|
||||
match std::fs::OpenOptions::new().write(true).create_new(true).open(&tmp) {
|
||||
Ok(f) => break (tmp, f),
|
||||
Err(e) if e.kind() == std::io::ErrorKind::AlreadyExists && attempts < 16 => attempts += 1,
|
||||
@@ -120,4 +121,18 @@ mod tests {
|
||||
let _ = std::fs::remove_file(&test_file);
|
||||
let _ = std::fs::remove_dir(&tmp_dir);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn write_file_overwrites_file_with_name_near_the_length_limit() {
|
||||
let dir = std::env::temp_dir().join("deckcraft_io_long_name_test");
|
||||
let _ = std::fs::create_dir_all(&dir);
|
||||
let file = dir.join(format!("{}.pptx", "a".repeat(250)));
|
||||
std::fs::write(&file, b"old").unwrap();
|
||||
let path_str = file.to_str().unwrap();
|
||||
|
||||
write_file(path_str, b"new").unwrap();
|
||||
assert_eq!(read_file(path_str).unwrap(), b"new");
|
||||
|
||||
let _ = std::fs::remove_file(&file);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user