From 352086304ead5973c0055f7aa1d2ea904068a614 Mon Sep 17 00:00:00 2001 From: Harrison Booth <73434116+Harrison-Booth@users.noreply.github.com> Date: Wed, 28 Oct 2026 09:55:23 -0500 Subject: [PATCH] F-09: cap font collection face enumeration --- crates/fonts/src/fontdb.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/crates/fonts/src/fontdb.rs b/crates/fonts/src/fontdb.rs index 751f36ca..373f4c32 100644 --- a/crates/fonts/src/fontdb.rs +++ b/crates/fonts/src/fontdb.rs @@ -604,12 +604,19 @@ fn fontconfig_dirs(text: &str, data_home: Option<&str>, home: Option<&std::path: /// axis settings. type Found = (u32, String, String, Vec<([u8; 4], f32)>); +/// Maximum number of faces we enumerate from a single font collection. +const MAX_COLLECTION_FACES: u32 = 256; + +fn capped_face_count(count: u32) -> u32 { + count.min(MAX_COLLECTION_FACES) +} + /// Parse every face in `data` (a font file or collection); a variable font yields one face per /// named instance (InDesign lists them as styles). fn enumerate_faces(data: &[u8]) -> Vec { let count = match FileRef::new(data) { Ok(FileRef::Font(_)) => 1, - Ok(FileRef::Collection(c)) => c.len(), + Ok(FileRef::Collection(c)) => capped_face_count(c.len()), Err(_) => 0, }; let mut out = Vec::new(); @@ -1435,6 +1442,12 @@ mod font_dir_tests { use super::*; + #[test] + fn font_collection_face_count_is_capped() { + assert_eq!(capped_face_count(MAX_COLLECTION_FACES), MAX_COLLECTION_FACES); + assert_eq!(capped_face_count(MAX_COLLECTION_FACES + 1), MAX_COLLECTION_FACES); + } + #[test] fn xdg_data_dirs_contribute_their_fonts_folders() { let home = Path::new("/home/ann");