M2.6: autotagging says decoding takes more than 16 MiB, not that the content does

Read through DecodeBudget::decode_strict since cbc3fc221, a stream counts what each of its filter stages decodes against the 16 MiB, as a page's decode allowance does, where main bounded each stage alone. A page of 12 MiB behind ASCIIHex and Flate, with 9.1 MiB between them, was tagged on main and is refused now; the refusal said the decoded content exceeds 16 MiB, which it does not. It now says decoding the content takes more than that.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AmsdeUCdTaD72jkDw2pJKY
This commit is contained in:
Grzegorz Martens
2026-11-07 12:37:35 +01:00
co-authored by Claude Opus 5.5
parent 477f0abd49
commit 79ea9154cf
2 changed files with 4 additions and 3 deletions
+3 -2
View File
@@ -57,13 +57,14 @@ fn content_bytes(doc: &Document, page: &pdfcraft_model::Page, index: usize) -> R
let Object::Stream(stream) = &*value else { return Err(unsupported(index, "contents include a non-stream object")) };
let remaining = MAX_PAGE_BYTES.saturating_sub(all.len().saturating_add(1));
if remaining == 0 {
return Err(unsupported(index, "decoded content exceeds 16 MiB"));
return Err(unsupported(index, "decoding the content takes more than 16 MiB"));
}
// Strictly, and with `/DecodeParms` given by reference: the content is written back from it.
let mut budget = DecodeBudget::new(remaining, 0);
let decoded = budget.decode_strict(doc, stream).map_err(|e| {
// The allowance counts what every filter stage decodes, as a page's does.
if budget.remaining() == 0 {
unsupported(index, "decoded content exceeds 16 MiB")
unsupported(index, "decoding the content takes more than 16 MiB")
} else {
unsupported(index, format!("content cannot be decoded strictly: {e}"))
}
+1 -1
View File
@@ -134,7 +134,7 @@ fn autotag_text_says_why_it_cannot_read_a_page() {
other => panic!("{other:?}"),
}
};
assert_eq!(reason(Stream::from_raw(Dict::new(), vec![b' '; 17 << 20])), "decoded content exceeds 16 MiB");
assert_eq!(reason(Stream::from_raw(Dict::new(), vec![b' '; 17 << 20])), "decoding the content takes more than 16 MiB");
let mut corrupt = Stream::from_raw(Dict::new(), b"not zlib data".to_vec());
corrupt.dict.set(b"Filter".to_vec(), Object::name("FlateDecode"));
let why = reason(corrupt);