From 60b60619b25737a290d840789fd476cd57104f8b Mon Sep 17 00:00:00 2001 From: nihilist-narwhal <240798405+nihilist-narwhal@users.noreply.github.com> Date: Sat, 10 Oct 2026 03:46:15 -0500 Subject: [PATCH] AutoFill: refuse a source as large as the sheet The target was capped at 5 million cells but the source wasn't: with the whole sheet as source and A1 as target, AutoFill read all 17 billion source cells one column at a time and never finished. --- crates/engine/src/cmd/edit.rs | 4 ++-- crates/engine/src/tests.rs | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/crates/engine/src/cmd/edit.rs b/crates/engine/src/cmd/edit.rs index 4c9f2d6ab..b88470a37 100644 --- a/crates/engine/src/cmd/edit.rs +++ b/crates/engine/src/cmd/edit.rs @@ -1076,8 +1076,8 @@ fn auto_fill(s: &mut Session, p: &Json) -> Result { "values" => crate::fill::FillMode::ValuesOnly, _ => crate::fill::FillMode::Series, }; - if target.count() > 5_000_000 { - return Err(bad("edit.autoFill", "target too large")); + if target.count() > 5_000_000 || src.count() > 5_000_000 { + return Err(bad("edit.autoFill", "range too large")); } edit(s, |cx| { crate::fill::fill(cx, sheet, src, target, mode)?; diff --git a/crates/engine/src/tests.rs b/crates/engine/src/tests.rs index e673485fb..c68211437 100644 --- a/crates/engine/src/tests.rs +++ b/crates/engine/src/tests.rs @@ -181,6 +181,7 @@ fn whole_sheet_selection_stays_within_the_data() { s.execute("edit.fillUp", json!({})).unwrap(); assert_eq!(v(&s, "A1"), Value::Number(5.0)); assert!(s.execute("edit.fillDown", json!({"range": "A1:Z1000000"})).is_err(), "too large to fill"); + assert!(s.execute("edit.autoFill", json!({"source": "A1:XFD1048576", "target": "A1"})).is_err(), "too large to fill"); s.execute("range.setValues", json!({"range": "D1", "values": [[1], [1], [2]]})).unwrap(); let r = s.execute("data.removeDuplicates", json!({"range": "D:D", "header": false})).unwrap(); assert_eq!((r["removed"].clone(), r["remaining"].clone()), (json!(1), json!(2)));