mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-11-02 22:41:47 -06:00
Each JBIG2 bitmap is bounded, but nothing bounded how many a stream asks for, so a few hundred bytes could tie up a render worker for minutes, and CodeRabbit raised the same on #5461. Measured through pdfcraft-cli, before and after: - one halftone segment, a 795-byte PDF: 265 s, now refused at once; - 66 halftones over patterns 1 wide, a 3,894-byte PDF: about 330 s, now refused at once; - about 226,000 generic regions behind nested Flate, a 923-byte PDF: unfinished at 40 s, some 88 hours by extrapolation, now 4.8 s; - 8 dictionaries of symbols of no width, a 983-byte PDF: 81 s, now 0.7 s; - about 1,048,000 generic regions of no width, a 34 KB PDF: unfinished at 90 s, now 2.6 s; - an aggregated dictionary over 2^20 symbols, a 713-byte PDF: unfinished at 90 s, now 9.1 s; - 10,000 instances of an 8192 × 8192 symbol, an 18 KB PDF: 64 s, now 3.2 s; - 30 generic regions of no data: 48 s, now 4.7 s. A stream may now ask for 2^30 units of work: four of the largest pages, about 6 s on data the decoder predicts and about 17 s on data it can't, inside the viewer's 20 s watchdog. Decoding a bitmap costs a unit a pixel and 4 a row, since a row costs time at any width. Copying one costs a unit a word and 1 a row, so a tall thin bitmap costs its rows. Each item is charged before it is decoded, apart from what is known only as it goes: new symbols and text instances are charged in their loops. An aggregated symbol is charged for the symbol table it rebuilds. Past the bound the image isn't drawn, as with the other caps, and the rest of the page is. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AmsdeUCdTaD72jkDw2pJKY