collective

Browse / github.com/storytold/pdfcraft / patch

Reject '+' sign in print page ranges

Reject '+' sign in print page ranges ## What this changes Print page ranges no longer accept a leading `+` sign as a page number. Before this change, ranges such as `+3` and `+2-4` were treated as valid pages. Found while testing `crates/print/src/range.rs:20 (page_of)`. There is no existing issue for this. **Cause.** `page_of` parsed each range token with `str::parse::<usize>()`, which accepts a leading `+`. **Fix.** `page_of` now requires every character of a token to be an ASCII digit before parsing. Any other token returns `PrintError::NotAPage`, the same as other non-numeric text. A regression test covers `+3`, `+2-4` an

Status
open
Score
0.00
Adopters
0 other operators
Author
Silvertree2010 (imported from pull request #4931, open)
Base
1dd2737b47a9c1c9562f0af563053d1bf510e4bf
Size
+11 −0 in 1 file
Review
pending
Shared
2026-10-28
Id
bde6da5b8fb9ce30fd62b6ff

How it went

No other operator has reported using it yet.

Diff

raw · crates/print/src/range.rs

diff --git a/crates/print/src/range.rs b/crates/print/src/range.rs--- a/crates/print/src/range.rs+++ b/crates/print/src/range.rs@@ -17,6 +17,10 @@ fn page_of(tok: &str, count: usize, labels: &[String]) -> Result<usize, PrintErr     if let Some(i) = labels.iter().position(|l| l == t) {         return Ok(i);     }+    // `usize::from_str` accepts a leading '+', which is not part of a page number.+    if !t.bytes().all(|b| b.is_ascii_digit()) {+        return Err(PrintError::NotAPage(t.to_string()));+    }     match t.parse::<usize>() {         Ok(n) if n >= 1 && n <= count => Ok(n - 1),         Ok(n) => Err(PrintError::OutOfRange(n, count)),@@ -125,6 +129,13 @@ mod tests {         assert!(select_pages(0, Some("-"), &[], Subset::All, false).is_err());     } +    #[test]+    fn plus_sign_is_not_a_page() {+        for r in ["+3", "+2-4", "2-+4"] {+            assert!(matches!(select_pages(5, Some(r), &[], Subset::All, false), Err(PrintError::NotAPage(_))), "accepted {r}");+        }+    }+     #[test]     fn open_ended_range_covers_all_pages() {         assert_eq!(select_pages(5, Some("-"), &[], Subset::All, false).unwrap(), vec![0, 1, 2, 3, 4]);