Engine: an xlsx save refuses a macro that skipped the check, as a JSON save does

`with_names` checked only the size of each item, so a macro built in code past the model's
limits (a name with a line break) was written to the file and dropped the next time it opened.
The xlsx save now runs `check` on every macro first.

- Test: the macro past the limits in `a_macro_built_in_code_goes_through_the_size_check_too`.
This commit is contained in:
prxnvt
2026-10-25 06:00:13 -04:00
parent bfcf50aad3
commit 0aae1ffeea
2 changed files with 14 additions and 5 deletions
+5
View File
@@ -106,6 +106,11 @@ pub fn with_names(wb: &Workbook) -> crate::Result<Option<Workbook>> {
if wb.macros.is_empty() && wb.macros_unread.is_empty() && !wb.names.iter().any(stored) { if wb.macros.is_empty() && wb.macros_unread.is_empty() && !wb.names.iter().any(stored) {
return Ok(None); return Ok(None);
} }
// A macro that skipped `check` (built in code) fails the save, as the JSON save does, rather
// than being written and dropped the next time the file opens.
for m in wb.macros.iter() {
check(m).map_err(crate::EngineError::Other)?;
}
let mut out = wb.clone(); let mut out = wb.clone();
// One pass drops the items of the last save, and one writes the macros (a file can hold a // One pass drops the items of the last save, and one writes the macros (a file can hold a
// thousand macros and many thousands of names). // thousand macros and many thousands of names).
+9 -5
View File
@@ -211,12 +211,16 @@ fn a_macro_built_in_code_goes_through_the_size_check_too() {
}; };
assert!(big.check_limits().is_ok(), "the model's limits say nothing about the size"); assert!(big.check_limits().is_ok(), "the model's limits say nothing about the size");
assert!(check(&big).unwrap_err().contains("too large")); assert!(check(&big).unwrap_err().contains("too large"));
let mut wb = Workbook::new();
wb.macros.push(big);
// A macro that fails `check` fails the save in either format, rather than being written and // A macro that fails `check` fails the save in either format, rather than being written and
// dropped the next time the file opens. // dropped the next time the file opens: too large, or past the model's limits.
for file in ["book.xlsx", "book.json"] { let bad_name = Macro { name: "Two\nlines".into(), ..Macro::default() };
assert!(crate::io::save_bytes(&wb, file).is_err(), "{file}"); assert!(check(&bad_name).is_err());
for m in [big, bad_name] {
let mut wb = Workbook::new();
wb.macros.push(m);
for file in ["book.xlsx", "book.json"] {
assert!(crate::io::save_bytes(&wb, file).is_err(), "{file}");
}
} }
} }