mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-10-14 19:27:04 -04:00
A poster scale large enough to make both tile counts saturate at usize::MAX overflowed when they were multiplied for the 1024-sheet check: a panic with overflow checks, and a product that wraps to 1 without them, which let the sheet loops run. The headless doc_print tool accepts any finite positive scale, so a script could reach it. Multiply with checked_mul and treat an overflow as over the limit, so the request gets the existing "more than 1024 sheets" error. Adds tests::huge_posters_are_refused_at_the_sheet_limit, which panics before this change and passes with and without overflow checks after it.
This commit is contained in:
1 parent
9593ff7419
commit
2796f3de0d
2 files changed
+13
-1
No files matched your search
@@ -467,7 +467,8 @@ pub fn layout(sizes: &[(f64, f64)], settings: &Settings) -> Result<Vec<Sheet>, P
|
||||
let (stepx, stepy) = (tw - overlap, th - overlap);
|
||||
let nx = (((sw - overlap) / stepx).ceil() as usize).max(1);
|
||||
let ny = (((sh - overlap) / stepy).ceil() as usize).max(1);
|
||||
if nx * ny > 1024 {
|
||||
// The counts saturate at usize::MAX for a huge scale, so their product can overflow.
|
||||
if nx.checked_mul(ny).is_none_or(|n| n > 1024) {
|
||||
return Err(PrintError::Invalid("the poster would need more than 1024 sheets".into()));
|
||||
}
|
||||
// Tiles from the top-left, row by row.
|
||||
|
||||
@@ -192,6 +192,17 @@ fn posters_tile_with_overlap() {
|
||||
assert!(layout(&[(200.0, 300.0)], &settings(vec![0], Layout::Poster { scale: 400.0, overlap: 400.0, cut_marks: false })).is_err());
|
||||
}
|
||||
|
||||
/// Issue #1335: a scale so large that the tile counts saturate is refused with the sheet-limit
|
||||
/// error, not an overflow in counting the sheets.
|
||||
#[test]
|
||||
fn huge_posters_are_refused_at_the_sheet_limit() {
|
||||
let refused = Err(PrintError::Invalid("the poster would need more than 1024 sheets".into()));
|
||||
for scale in [100_000.0, 1e22, f64::MAX] {
|
||||
let poster = settings(vec![0], Layout::Poster { scale, overlap: 18.0, cut_marks: true });
|
||||
assert_eq!(layout(&[(200.0, 300.0)], &poster), refused, "scale {scale}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn imposed_pdf_has_the_sheets_and_honours_comments_and_forms() {
|
||||
let doc = fixture(3);
|
||||
|
||||
Reference in new issue
Block a user