Skip to content

Commit 5d95f47

Browse files
authored
Fix SIGBUS crash on macOS arm64 for any \setmainfont{} call (#1345) (#1346)
2 parents e080610 + 9b0f21a commit 5d95f47

3 files changed

Lines changed: 18 additions & 17 deletions

File tree

crates/mac_core/src/array.rs

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use super::{sys, CoreType};
22
use std::marker::PhantomData;
3-
use std::ops::Index;
43
use std::ptr;
54
use std::ptr::NonNull;
65

@@ -53,20 +52,22 @@ impl<T: CoreType> CFArray<T> {
5352
pub fn is_empty(&self) -> bool {
5453
self.len() == 0
5554
}
56-
}
57-
58-
impl<T: CoreType> Index<usize> for CFArray<T> {
59-
type Output = T;
6055

61-
fn index(&self, index: usize) -> &Self::Output {
56+
/// Get a borrowed value at the given index. The returned value has its reference count
57+
/// incremented and will be released when dropped.
58+
///
59+
/// `CFArrayGetValueAtIndex` returns the stored `CFTypeRef` value directly (not a pointer
60+
/// to it), so we must construct a new borrowed `T` from it rather than casting to `&T`.
61+
pub fn get(&self, index: usize) -> T {
6262
if index >= self.len() {
6363
panic!("Index {index} out of bounds for CFArray");
6464
}
6565
// SAFETY: Internal pointer is guaranteed valid. Index has been verified in-bounds.
66-
let ptr =
67-
unsafe { sys::CFArrayGetValueAtIndex(self.0.cast().as_ptr(), index as sys::CFIndex) }
68-
.cast::<T>();
69-
// SAFETY: API contracts ensure all values are of the correct type and live for our lifetime.
70-
unsafe { &*ptr }
66+
let value =
67+
unsafe { sys::CFArrayGetValueAtIndex(self.0.cast().as_ptr(), index as sys::CFIndex) };
68+
// SAFETY: The returned value is a valid CFTypeRef for type T.
69+
// new_borrowed calls CFRetain, giving us ownership of a new reference.
70+
let ptr = NonNull::new(value.cast_mut()).unwrap();
71+
unsafe { T::new_borrowed(ptr.cast()) }
7172
}
7273
}

crates/xetex_layout/src/font.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ impl Font {
274274
let sz = engine.input_get_size(afm_handle);
275275
let mut backing_data2 = vec![0; sz];
276276
engine
277-
.input_read(handle, &mut backing_data2)
277+
.input_read(afm_handle, &mut backing_data2)
278278
.expect("failed to read AFM file");
279279

280280
self.ft_face().attach_stream_mem(backing_data2).unwrap();

crates/xetex_layout/src/manager/mac.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@ fn find_fonts_with_name(name: CFString, key: FontAttribute) -> CFArray<CTFontDes
2121
fn find_font_with_name(name: CFString, key: FontAttribute) -> Option<CTFontDescriptor> {
2222
let matches = find_fonts_with_name(name, key);
2323

24-
let mut matched = None;
2524
if !matches.is_empty() {
26-
matched = Some(matches[0].clone());
25+
Some(matches.get(0))
26+
} else {
27+
None
2728
}
28-
matched
2929
}
3030

3131
fn append_name_to_list(font: &CTFont, name_list: &mut Vec<CString>, name_key: FontNameKey) {
@@ -48,9 +48,9 @@ impl MacBackend {
4848

4949
fn add_fonts_to_caches(&self, maps: &mut FontMaps, members: CFArray<CTFontDescriptor>) {
5050
for i in 0..members.len() {
51-
let font = &members[i];
51+
let font = members.get(i);
5252
let names = self.read_names(font.clone());
53-
maps.add_to_maps(self, font.clone(), &names)
53+
maps.add_to_maps(self, font, &names)
5454
}
5555
}
5656

0 commit comments

Comments
 (0)