From 50b067c089b4beb5b51c6b4b099c21e841c95d1b Mon Sep 17 00:00:00 2001 From: NetterSilver <133535268+Silvertree2010@users.noreply.github.com> Date: Sun, 25 Oct 2026 11:16:58 +0100 Subject: [PATCH] Refuse signs, exponents and non-numeric text in Export for Screens sizes Found while testing crates/engine/src/cmd/fileio/screens.rs:49 (ScreenSize::parse) Co-Authored-By: Claude Haiku 5.5 Co-Authored-By: Claude Sonnet 5.5 --- crates/engine/src/cmd/fileio/screens.rs | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/crates/engine/src/cmd/fileio/screens.rs b/crates/engine/src/cmd/fileio/screens.rs index 1d9c0303c..8ff9e682a 100644 --- a/crates/engine/src/cmd/fileio/screens.rs +++ b/crates/engine/src/cmd/fileio/screens.rs @@ -46,7 +46,14 @@ impl ScreenSize { /// `2x` (or `2`), `100w`, `100h` or `72ppi`, in any case; positive numbers only. pub fn parse(s: &str) -> Option { let s = s.trim().to_ascii_lowercase(); - let num = |t: &str| t.trim().parse::().ok().filter(|v| v.is_finite() && *v > 0.0); + // Digits and `.` only: `str::parse` would also take `+2`, `1e2`, `inf` and `nan`. + let num = |t: &str| { + let t = t.trim(); + if !t.bytes().all(|b| b.is_ascii_digit() || b == b'.') { + return None; + } + t.parse::().ok().filter(|v| v.is_finite() && *v > 0.0) + }; if let Some(n) = s.strip_suffix("ppi") { return num(n).map(Self::Ppi); } @@ -995,3 +1002,19 @@ pub(crate) fn store_settings(s: &mut Session, settings: Map) -> R pub(super) fn export_settings(s: &mut Session, _: &Value) -> Result { Ok(json!({ "settings": s.doc()?.doc.export_settings })) } + +#[cfg(test)] +mod tests { + use super::ScreenSize; + + #[test] + fn size_parse_refuses_signs_and_exponents() { + for s in ["+2x", "+2", "+100w", "+100h", "+72ppi", "-2x", "1e2", "2e0w"] { + assert_eq!(ScreenSize::parse(s), None, "{s}"); + } + assert_eq!(ScreenSize::parse("2x"), Some(ScreenSize::Scale(2.0))); + assert_eq!(ScreenSize::parse("1.5"), Some(ScreenSize::Scale(1.5))); + assert_eq!(ScreenSize::parse("100W"), Some(ScreenSize::Width(100.0))); + assert_eq!(ScreenSize::parse("72ppi"), Some(ScreenSize::Ppi(72.0))); + } +}