From a1ea2d376376d7efbffd3670b6202b7ee02deac9 Mon Sep 17 00:00:00 2001 From: eliets2 Date: Mon, 9 Nov 2026 19:54:53 +0200 Subject: [PATCH] Align stream decode cap with renderer at 256 MiB (#6585) Editor, export and redaction must not read or rewrite text that the page view and Find never see, which a mismatched cap allows on large streams. Lower MAX_DECODED to 256 MiB to match the renderer cap, so every Stream::decoded-based content reader stops at the same byte and oversized streams error instead of exposing later text. Test: decoded_stops_at_renderer_cap_of_256_mib failed before the change and passes after. Co-authored-by: eliets2 <287273517+eliets2@users.noreply.github.com> --- crates/cos/src/object.rs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/crates/cos/src/object.rs b/crates/cos/src/object.rs index f40f175d69..97a3b60ab9 100644 --- a/crates/cos/src/object.rs +++ b/crates/cos/src/object.rs @@ -351,10 +351,12 @@ impl Stream { } /// Decoded data, tolerating truncated or corrupt encodings the way viewers do (the data - /// decoded before the damage is returned). Streams with image codecs fail with + /// decoded before the damage is returned). Decoding past + /// [`crate::budget::MAX_PAGE_DECODED`] (256 MiB), the most the renderer reads from one + /// stream, is an error. Streams with image codecs fail with /// `CosError::Filter` (keep them encoded). Use `decoded_strict` to detect damage. pub fn decoded(&self) -> Result, CosError> { - self.decoded_within(MAX_DECODED) + self.decoded_within(crate::budget::MAX_PAGE_DECODED) } /// Like [`Stream::decoded`], for a stream whose decoded size has a tighter bound than @@ -780,6 +782,13 @@ mod tests { assert_eq!(stream.decoded_strict().unwrap(), b"A"); } + #[test] + fn decoded_stops_at_renderer_cap_of_256_mib() { + let data = vec![0u8; (256 << 20) + 1]; + let stream = Stream::flate(Dict::new(), &data); + assert!(matches!(stream.decoded(), Err(CosError::Filter(_)))); + } + #[test] fn first_filter_decodes_only_the_outer_wrapper() { let data = "0 0 m 100 100 l S\n".repeat(64).into_bytes();