From 650601593e02d6ef687dd26becac92907bc5a335 Mon Sep 17 00:00:00 2001 From: NetterSilver <133535268+Silvertree2010@users.noreply.github.com> Date: Sat, 31 Oct 2026 21:05:43 +0100 Subject: [PATCH] Reject negative or fractional index in page.move Found while testing crates/engine/src/cmd/page.rs:132 Co-Authored-By: Claude Haiku 5.5 Co-Authored-By: Claude Sonnet 5.5 --- crates/engine/src/cmd/page.rs | 2 +- crates/engine/src/panels_behaviour_tests.rs | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/crates/engine/src/cmd/page.rs b/crates/engine/src/cmd/page.rs index 2835deff3..458e7572c 100644 --- a/crates/engine/src/cmd/page.rs +++ b/crates/engine/src/cmd/page.rs @@ -129,7 +129,7 @@ pub fn specs() -> Vec { }), spec!("page.move", "Move page", "{id?, index}", true, |s, p| { let id = id(p, "id").unwrap_or(s.page()?); - let k = req_num("page.move", p, "index")?.max(0.0) as usize; + let k = req_index("page.move", p, "index")?; let doc = s.doc_mut()?; if !doc.pages.contains(&id) { return Err(bad("page.move", format!("{id} is not a page"))); diff --git a/crates/engine/src/panels_behaviour_tests.rs b/crates/engine/src/panels_behaviour_tests.rs index d97d25075..e44d99fc0 100644 --- a/crates/engine/src/panels_behaviour_tests.rs +++ b/crates/engine/src/panels_behaviour_tests.rs @@ -393,6 +393,20 @@ fn page_select_and_doc_switch_refuse_negative_or_fractional_indexes() { } } +#[test] +fn page_move_refuses_negative_or_fractional_indexes() { + let mut s = Session::new(); + ex(&mut s, "page.add", json!({})); + let p3 = id(&ex(&mut s, "page.add", json!({}))); + let before = pages(&mut s); + for bad_index in [json!(-1), json!(1.5)] { + assert!(s.execute("page.move", &json!({"id": p3, "index": bad_index})).is_err(), "page.move index {bad_index} must fail"); + assert_eq!(pages(&mut s), before, "page.move index {bad_index} leaves the order alone"); + } + ex(&mut s, "page.move", json!({"id": p3, "index": 0})); + assert_eq!(pages(&mut s)[0]["id"], json!(p3), "a valid index still moves the page"); +} + #[test] fn assets_panel_lists_files_and_drops_by_the_documented_rules() { let mut s = Session::new();