Return BadParams for overflowing start in review.spellingChange

Found while testing crates/engine/src/cmd/review.rs:424 (spelling_change)

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:
NetterSilver
2026-10-24 13:53:26 +00:00
co-authored by Claude Haiku 5.5
parent 38d2ade2b7
commit 35f240e453
+16 -1
View File
@@ -430,7 +430,7 @@ fn spelling_change(s: &mut Session, p: &Value) -> Result<Value> {
// One exact occurrence (a squiggled word): paragraph `para`, from character `start`.
if let (Some(id), Some(para), Some(start)) = (shape, usize_param(p, "para"), usize_param(p, "start")) {
let id = deckcraft_model::ShapeId(u32::try_from(id).map_err(|_| bad("review.spellingChange", "bad `shape`"))?);
let end = start + word.chars().count();
let end = start.checked_add(word.chars().count()).ok_or_else(|| bad("review.spellingChange", "bad `start`"))?;
let cell = usize_param(p, "row").zip(usize_param(p, "col"));
let slide = {
let st = s.doc()?;
@@ -843,3 +843,18 @@ mod tests {
assert!(s.active().unwrap().doc.slides[0].comments.is_empty());
}
}
#[cfg(test)]
mod spelling_change_range_tests {
use crate::{EngineError, Session};
use serde_json::json;
#[test]
fn spelling_change_huge_start_is_bad_params() {
let mut s = Session::with_new();
let r = s.execute("insert.textBox", &json!({"text": "Hello"})).unwrap();
let id = r["id"].clone();
let err = s.execute("review.spellingChange", &json!({"shape": id, "para": 0, "start": u64::MAX, "word": "Hello", "to": "x"})).unwrap_err();
assert!(matches!(err, EngineError::BadParams { .. }), "{err:?}");
}
}