diff --git a/crates/engine/src/cmd/file.rs b/crates/engine/src/cmd/file.rs index 0d52e6358..7857535c0 100644 --- a/crates/engine/src/cmd/file.rs +++ b/crates/engine/src/cmd/file.rs @@ -359,7 +359,13 @@ pub fn pdf_options(p: &Value, count: usize) -> Result let mut o = deckcraft_pdf::PdfOptions { layout: deckcraft_pdf::PageLayout::Slides, ..Default::default() }; o.layout = match str_param(p, "layout").unwrap_or("slides") { "notes" => deckcraft_pdf::PageLayout::Notes, - "handouts" => deckcraft_pdf::PageLayout::Handouts { per_page: usize_param(p, "perPage").unwrap_or(6).clamp(1, 9) as u8 }, + "handouts" => { + let per_page = opt_usize_param(p, "perPage", "file.export")?.unwrap_or(6); + if ![1, 2, 3, 4, 6, 9].contains(&per_page) { + return Err(bad("file.export", format!("perPage {per_page} isn't one of 1, 2, 3, 4, 6, 9"))); + } + deckcraft_pdf::PageLayout::Handouts { per_page: per_page as u8 } + } _ => deckcraft_pdf::PageLayout::Slides, }; o.dpi = f64_or(p, "dpi", o.dpi).clamp(36.0, 600.0); diff --git a/crates/engine/src/tests.rs b/crates/engine/src/tests.rs index 68de13418..1c8e7a8ac 100644 --- a/crates/engine/src/tests.rs +++ b/crates/engine/src/tests.rs @@ -2410,6 +2410,23 @@ fn pdf_options_take_paper_and_orientation() { assert!(cmd::file::pdf_options(&json!({"orientation": "sideways"}), 1).is_err()); } +/// Handout `perPage` accepts only 1, 2, 3, 4, 6 and 9; anything else is an error, not a 9-up page. +#[test] +fn pdf_options_reject_unsupported_per_page() { + for n in [1, 2, 3, 4, 6, 9] { + let o = cmd::file::pdf_options(&json!({"layout": "handouts", "perPage": n}), 1).unwrap(); + assert!(matches!(o.layout, deckcraft_pdf::PageLayout::Handouts { per_page } if per_page as usize == n)); + } + for n in [0, 5, 7, 8, 10] { + let e = cmd::file::pdf_options(&json!({"layout": "handouts", "perPage": n}), 1).unwrap_err(); + assert!(e.to_string().contains("1, 2, 3, 4, 6, 9"), "perPage {n}: {e}"); + } + // Not a count at all: refused too, instead of falling back to 6. + for v in [json!(-1), json!(5.5), json!("6")] { + assert!(cmd::file::pdf_options(&json!({"layout": "handouts", "perPage": v}), 1).is_err(), "perPage {v}"); + } +} + #[test] fn shape_line_sets_compound_and_arrow_sizes() { // The Format Shape pane's Line page: compound type, arrowheads and their sizes.