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>
This commit is contained in:
eliets2andeliets2 authored and GitHub committed 2026-11-09 18:54:53 +01:00
1 parent ba28458ad8
commit a1ea2d3763
1 file changed
+11 -2
+11 -2
View File
@@ -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<Vec<u8>, 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();