From 72ac32715ffd5c94de9e6d6b1cfb9bce7ccb65c4 Mon Sep 17 00:00:00 2001 From: NetterSilver <133535268+Silvertree2010@users.noreply.github.com> Date: Mon, 2 Nov 2026 12:21:37 +0100 Subject: [PATCH] Reject invalid master and layout indices in view.slideMaster Found while testing crates/engine/src/cmd/design/master_view.rs:8 (master_view; `master` read via usize_param, `layout` at :14) Co-Authored-By: Claude Haiku 5.5 Co-Authored-By: Claude Sonnet 5.5 --- crates/engine/src/cmd/design/master_view.rs | 6 +++--- crates/engine/src/tests.rs | 11 +++++++++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/crates/engine/src/cmd/design/master_view.rs b/crates/engine/src/cmd/design/master_view.rs index 5dfe0496..c03bfa57 100644 --- a/crates/engine/src/cmd/design/master_view.rs +++ b/crates/engine/src/cmd/design/master_view.rs @@ -1,17 +1,17 @@ use super::{ Arc, Fill, NO_ID_SPACE, PhType, Result, Run, RunKind, Session, Shape, ShapeId, Size, Target, TextBody, Value, bad, bool_param, json, - master_index, ok, opt_usize_param, rect_param, str_param, usize_param, + master_index, ok, opt_usize_param, rect_param, str_param, }; pub(super) fn master_view(s: &mut Session, p: &Value) -> Result { let st = s.doc()?; - let mi = usize_param(p, "master").unwrap_or_else(|| master_index(&st.doc, &st.selection)); + let mi = opt_usize_param(p, "master", "view.slideMaster")?.unwrap_or_else(|| master_index(&st.doc, &st.selection)); // A master thumbnail sends `{master}` and means the master itself. `{master, layout}` selects // that layout. With neither key, follow the current slide's layout. let layout = if p.get("master").is_some() && p.get("layout").is_none() { None } else { - usize_param(p, "layout") + opt_usize_param(p, "layout", "view.slideMaster")? .or_else(|| st.current_slide().and_then(|sl| st.doc.masters.get(mi).and_then(|m| m.layouts.iter().position(|l| l.id == sl.layout)))) }; let target = match layout { diff --git a/crates/engine/src/tests.rs b/crates/engine/src/tests.rs index 68de1341..140a88de 100644 --- a/crates/engine/src/tests.rs +++ b/crates/engine/src/tests.rs @@ -6458,3 +6458,14 @@ fn master_body_placeholder_format_keeps_per_level_formatting() { assert_eq!((level(&s, 0).run.size, level(&s, 1).run.size), (Some(28.0), Some(24.0))); assert_eq!(shown(&s), vec![Some(28.0), Some(24.0)]); } + +#[test] +fn slide_master_view_rejects_invalid_indices() { + let mut s = Session::with_new(); + for p in [json!({"master": -1}), json!({"master": 0.5}), json!({"master": 0, "layout": -1}), json!({"master": 0, "layout": 1.5})] { + let r = s.execute("view.slideMaster", &p); + assert!(r.is_err(), "invalid index accepted for {p}: {r:?}"); + } + assert!(s.execute("view.slideMaster", &json!({})).is_ok()); + assert!(s.execute("view.slideMaster", &json!({"master": 0})).is_ok()); +}