From 7d53e07f4330ca398a555ac9efc608b5eaa10cc7 Mon Sep 17 00:00:00 2001 From: Grzegorz Martens Date: Sat, 31 Oct 2026 10:36:41 +0100 Subject: [PATCH] M2.6: the JBIG2 cap's doc and test say what happens The decoder has the same 2^28 cap as decode_jbig2, and can refuse a page first, so the doc says either error can come. The page at the cap decodes, which the test now asserts, rather than failing later. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01AmsdeUCdTaD72jkDw2pJKY --- crates/filters/src/jbig2/decode.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/crates/filters/src/jbig2/decode.rs b/crates/filters/src/jbig2/decode.rs index 2ec9f97dd5..320e02445a 100644 --- a/crates/filters/src/jbig2/decode.rs +++ b/crates/filters/src/jbig2/decode.rs @@ -20,7 +20,8 @@ pub const MAX_JBIG2_PIXELS: u64 = 1 << 28; /// /// Errors: `data` or `globals` that don't decode, or a page of another size /// ([`FilterError::Corrupt`]); a page past `max` ([`FilterError::LimitExceeded`]) or -/// [`MAX_JBIG2_PIXELS`] ([`FilterError::Unsupported`]). +/// [`MAX_JBIG2_PIXELS`] ([`FilterError::Unsupported`], or `Corrupt` from the decoder, which has the +/// same cap and can refuse the page first). pub fn decode_jbig2(data: &[u8], globals: Option<&[u8]>, columns: u32, rows: u32, max: usize) -> Result, FilterError> { if rows == 0 { return Ok(Vec::new()); @@ -137,11 +138,11 @@ mod tests { let page = 26 * h as usize; assert!(matches!(decode_jbig2(&data, None, w, h, page - 1), Err(FilterError::LimitExceeded(m)) if m == page - 1), "a byte short"); assert_eq!(decode_jbig2(&data, None, w, h, page).unwrap().len(), page, "the page within max"); - // 16,384 × 16,384 is 2^28 pixels, and fails only later; a row more is past the cap, here or - // in the decoder, which can refuse it first. + // 16,384 × 16,384 is 2^28 pixels, which decodes; a row more is past the cap, here or in the + // decoder, which has the same one and can refuse it first. let large = |rows| decode_jbig2(&page_of(&data, 16_384, rows), None, 16_384, rows, usize::MAX); assert!(matches!(large(16_385), Err(FilterError::Unsupported(_) | FilterError::Corrupt { .. })), "{:?}", large(16_385)); - assert!(!matches!(large(16_384), Err(FilterError::Unsupported(_))), "{:?}", large(16_384)); + assert!(large(16_384).is_ok(), "{:?}", large(16_384).map(|page| page.len())); // An extension segment (ISO/IEC 14492 7.4.14), which a decoder skips: its 11-byte header // gives the length of the data after it.