mirror of
https://github.com/wez/wezterm.git
synced 2024-12-23 21:32:13 +03:00
macos: fonts: fix a potential unterminated loop
for fonts located by core text, if they are singular TTF files rather than TTC files, and the font doesn't exactly match the search critiera, we could loop forever re-parsing the same file over and over again. This commit restructures the logic to definitively check the number of contained font entries and constrain the loop to that number. In addition, it adjusts the name matching, as macos can return names like "Cascadia Code Roman" when the underlying font is named "Cascadia Code". refs: https://github.com/wez/wezterm/issues/475
This commit is contained in:
parent
35060fb2de
commit
4e27607615
@ -10,6 +10,7 @@ use core_foundation::string::CFString;
|
||||
use core_text::font::*;
|
||||
use core_text::font_descriptor::*;
|
||||
use std::collections::HashSet;
|
||||
use ttf_parser::fonts_in_collection;
|
||||
|
||||
/// A FontLocator implemented using the system font loading
|
||||
/// functions provided by core text.
|
||||
@ -51,15 +52,24 @@ fn descriptor_from_attr(attr: &FontAttributes) -> anyhow::Result<CTFontDescripto
|
||||
fn handle_from_descriptor(descriptor: &CTFontDescriptor) -> Option<FontDataHandle> {
|
||||
let path = descriptor.font_path()?;
|
||||
let name = descriptor.display_name();
|
||||
let family_name = descriptor.family_name();
|
||||
|
||||
for index in 0.. {
|
||||
let handle = FontDataHandle::OnDisk {
|
||||
path: path.clone(),
|
||||
index,
|
||||
let data = std::fs::read(path).ok()?;
|
||||
let size = fonts_in_collection(&data).unwrap_or(1);
|
||||
|
||||
let mut handle = FontDataHandle::Memory {
|
||||
data,
|
||||
name,
|
||||
index: 0,
|
||||
};
|
||||
|
||||
for index in 0..size {
|
||||
if let FontDataHandle::Memory { index: idx, .. } = &mut handle {
|
||||
*idx = index;
|
||||
}
|
||||
let parsed = crate::parser::ParsedFont::from_locator(&handle).ok()?;
|
||||
let names = parsed.names();
|
||||
if names.full_name == name {
|
||||
if names.full_name == family_name || names.family.as_ref() == Some(&family_name) {
|
||||
return Some(handle);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user