diff --git a/vendor/README.md b/vendor/README.md index b3fc2461..0d31ef90 100644 --- a/vendor/README.md +++ b/vendor/README.md @@ -7,7 +7,7 @@ the fix. Vendoring copyleft code is never allowed (plan/adr/0001). | Crate | Version | Licence | Patches | Test | |---|---|---|---|---| -| hayro-interpret | 0.7.0 | Apache-2.0 OR MIT | (1) select `/AP /N` appearance states via `/AS` (checkboxes, radios, stateful icons) and honour the NoView flag; (2) Type3 Unicode fallback to `/Encoding` glyph names, then printable ASCII; (3) `Type3Glyph::advance_width`; (4) `InterpreterSettings::ocg_overrides` for viewer layer toggles; (5) soft masks whose group lacks `/CS` were dropped (Chrome gradient text) | (1) `raster::tests::widget_appearance_states`; (2, 3) `xtask text-oracle` on corpus/pdfjs issue918; (4) `raster::tests::layer_override_hides_content`; (5) `raster::tests::soft_mask_without_group_colour_space_is_applied` | +| hayro-interpret | 0.7.0 | Apache-2.0 OR MIT | (1) select `/AP /N` appearance states via `/AS` (checkboxes, radios, stateful icons) and honour the NoView flag; (2) Type3 Unicode fallback to `/Encoding` glyph names, then printable ASCII; (3) `Type3Glyph::advance_width`; (4) `InterpreterSettings::ocg_overrides` for viewer layer toggles; (5) soft masks whose group lacks `/CS` were dropped (Chrome gradient text); (6) tiling-pattern nesting cap `MAX_PATTERN_NESTING` (a self-referencing pattern overflowed the stack); (7) CID width ranges in `/W` and `/W2` clamped to `MAX_CID` (a `0 4294967295 w` range hung) | (1) `raster::tests::widget_appearance_states`; (2, 3) `xtask text-oracle` on corpus/pdfjs issue918; (4) `raster::tests::layer_override_hides_content`; (5) `raster::tests::soft_mask_without_group_colour_space_is_applied`; (6) `raster::tests::self_referencing_tiling_pattern_terminates`; (7) `raster::tests::huge_cid_width_ranges_terminate` | | hayro | 0.7.1 | Apache-2.0 OR MIT | `RenderSettings::{x_offset, y_offset}` to render one tile of a large page | `raster::tests::tiles_match_full_render` | | hayro-syntax | 0.7.2 | Apache-2.0 OR MIT | Page-tree cycle guard in `resolve_pages` (visited set + depth cap): a `/Kids` loop among compressed objects overflowed the stack and aborted the process | `cos/tests/writer.rs::page_tree_loops_in_object_streams_do_not_crash_readers` | diff --git a/vendor/hayro-interpret/src/font/cid.rs b/vendor/hayro-interpret/src/font/cid.rs index dd724e37..ad00a84f 100644 --- a/vendor/hayro-interpret/src/font/cid.rs +++ b/vendor/hayro-interpret/src/font/cid.rs @@ -509,6 +509,9 @@ impl CidToGIdMap { } } +/// PrintCraft patch: the largest CID (ISO 32000-2 ยง9.7.2; CIDs are at most two bytes). +const MAX_CID: u32 = 65_535; + fn read_widths(arr: &Array<'_>) -> Option> { let mut map = HashMap::new(); let mut iter = arr.flex_iter(); @@ -516,11 +519,16 @@ fn read_widths(arr: &Array<'_>) -> Option> { loop { if let Some((mut first, range)) = iter.next::<(u32, Array<'_>)>() { for width in range.iter::() { + if first > MAX_CID { + break; + } map.insert(first, width); first = first.checked_add(1)?; } } else if let Some((first, second, width)) = iter.next::<(u32, u32, f32)>() { - for i in first..=second { + // PrintCraft patch: CIDs stop at 65535. A corrupt range such as + // `0 4294967295 500` inserted billions of entries (found by fuzzing). + for i in first..=second.min(MAX_CID) { map.insert(i, width); } } else { @@ -546,7 +554,8 @@ fn read_widths2(arr: &Array<'_>) -> Option> { first = first.checked_add(1)?; } } else if let Some((first, second, w, v1, v2)) = iter.next::<(u32, u32, f32, f32, f32)>() { - for i in first..=second { + // PrintCraft patch: as in `read_widths`. + for i in first..=second.min(MAX_CID) { map.insert(i, [w, v1, v2]); } } else { diff --git a/vendor/hayro-interpret/src/pattern.rs b/vendor/hayro-interpret/src/pattern.rs index dfb9d93f..3c01695f 100644 --- a/vendor/hayro-interpret/src/pattern.rs +++ b/vendor/hayro-interpret/src/pattern.rs @@ -24,6 +24,9 @@ use kurbo::{Affine, BezPath, Rect, Shape}; use std::fmt::{Debug, Formatter}; use std::sync::Arc; + +/// PrintCraft patch: maximum nesting of tiling patterns (and the forms around them). +const MAX_PATTERN_NESTING: u32 = 16; /// A PDF pattern. #[derive(Debug, Clone)] pub enum Pattern<'a> { @@ -228,6 +231,13 @@ impl<'a> TilingPattern<'a> { initial_transform: Affine, is_stroke: bool, ) -> Option<()> { + // PrintCraft patch: a tiling pattern can paint itself (directly, or through resources it + // inherits when its own are missing), which recursed until the stack overflowed. Bound + // the nesting like XObjects do, tighter because every level rasterizes a tile. + if self.nesting_depth > MAX_PATTERN_NESTING { + warn!("tiling pattern nesting depth exceeded"); + return None; + } let state = State::new(initial_transform); let mut context = Context::new_with(