From 34e1d373bfa8cd2b0ba30784eee806029d3a6fde Mon Sep 17 00:00:00 2001 From: MarekSpodBiedry <73122968+MarekSpodBiedry@users.noreply.github.com> Date: Mon, 12 Oct 2026 08:27:26 +0200 Subject: [PATCH] fix(engine): CSV named History keeps a valid sheet name (#570) --- crates/engine/src/io.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/crates/engine/src/io.rs b/crates/engine/src/io.rs index e613611..f0bd5e4 100644 --- a/crates/engine/src/io.rs +++ b/crates/engine/src/io.rs @@ -144,7 +144,9 @@ fn rename_first_sheet(wb: &mut Workbook, path: &str) { let stem = std::path::Path::new(path).file_stem().and_then(|s| s.to_str()).unwrap_or("Sheet1"); let clean: String = stem.chars().filter(|c| !matches!(c, ':' | '\\' | '/' | '?' | '*' | '[' | ']')).take(31).collect(); let clean = clean.trim_matches('\'').to_string(); + // "History" is reserved (see `Workbook::check_sheet_name`): keep the default name instead. if !clean.is_empty() + && !clean.eq_ignore_ascii_case("History") && let Some(sh) = wb.sheet_mut(0) { sh.name = clean; @@ -434,6 +436,17 @@ mod tests { assert!(wb.vba_project.is_some(), "the open workbook keeps its macros"); } + #[test] + fn csv_named_history_does_not_get_the_reserved_sheet_name() { + for file in ["History.csv", "hIsToRy.csv", "history.tsv"] { + let (wb, _) = open_bytes(file, b"1\n").unwrap(); + let name = wb.sheets[0].name.clone(); + assert!(wb.check_sheet_name(&name, Some(0)).is_ok(), "{file} opened as {name:?}"); + } + let (wb, _) = open_bytes("Sales.csv", b"1\n").unwrap(); + assert_eq!(wb.sheets[0].name, "Sales"); + } + /// A minimal compound (CFB/OLE2) file — FAT in sector 0, directory in sector 1 — holding a /// root entry and the given stream names. fn cfb(streams: &[&str]) -> Vec {