Reduce the size of some unsafe blocks in shaper.rs (#38597)

This change ensures that safe operations are done outside of unsafe
blocks as often as possible.

Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
This commit is contained in:
Simon Wülker 2025-08-11 15:39:07 +02:00 committed by GitHub
parent b75c3feb97
commit abc549eff7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -692,15 +692,13 @@ extern "C" fn glyph_func(
let font: *const Font = font_data as *const Font; let font: *const Font = font_data as *const Font;
assert!(!font.is_null()); assert!(!font.is_null());
unsafe { match unsafe { (*font).glyph_index(char::from_u32(unicode).unwrap()) } {
match (*font).glyph_index(char::from_u32(unicode).unwrap()) {
Some(g) => { Some(g) => {
*glyph = g as hb_codepoint_t; unsafe { *glyph = g as hb_codepoint_t };
true as hb_bool_t true as hb_bool_t
}, },
None => false as hb_bool_t, None => false as hb_bool_t,
} }
}
} }
extern "C" fn glyph_h_advance_func( extern "C" fn glyph_h_advance_func(
@ -712,47 +710,44 @@ extern "C" fn glyph_h_advance_func(
let font: *mut Font = font_data as *mut Font; let font: *mut Font = font_data as *mut Font;
assert!(!font.is_null()); assert!(!font.is_null());
unsafe { let advance = unsafe { (*font).glyph_h_advance(glyph as GlyphId) };
let advance = (*font).glyph_h_advance(glyph as GlyphId);
Shaper::float_to_fixed(advance) Shaper::float_to_fixed(advance)
}
} }
// Callback to get a font table out of a font. /// Callback to get a font table out of a font.
extern "C" fn font_table_func( extern "C" fn font_table_func(
_: *mut hb_face_t, _: *mut hb_face_t,
tag: hb_tag_t, tag: hb_tag_t,
user_data: *mut c_void, user_data: *mut c_void,
) -> *mut hb_blob_t { ) -> *mut hb_blob_t {
unsafe {
// NB: These asserts have security implications. // NB: These asserts have security implications.
let font = user_data as *const Font; let font = user_data as *const Font;
assert!(!font.is_null()); assert!(!font.is_null());
// TODO(Issue #197): reuse font table data, which will change the unsound trickery here. // TODO(Issue #197): reuse font table data, which will change the unsound trickery here.
match (*font).table_for_tag(tag as FontTableTag) { let Some(font_table) = (unsafe { (*font).table_for_tag(tag as FontTableTag) }) else {
None => ptr::null_mut(), return ptr::null_mut();
Some(font_table) => { };
// `Box::into_raw` intentionally leaks the FontTable so we don't destroy the buffer // `Box::into_raw` intentionally leaks the FontTable so we don't destroy the buffer
// while HarfBuzz is using it. When HarfBuzz is done with the buffer, it will pass // while HarfBuzz is using it. When HarfBuzz is done with the buffer, it will pass
// this raw pointer back to `destroy_blob_func` which will deallocate the Box. // this raw pointer back to `destroy_blob_func` which will deallocate the Box.
let font_table_ptr = Box::into_raw(Box::new(font_table)); let font_table_ptr = Box::into_raw(Box::new(font_table));
let buf = (*font_table_ptr).buffer(); let buf = unsafe { (*font_table_ptr).buffer() };
// HarfBuzz calls `destroy_blob_func` when the buffer is no longer needed. // HarfBuzz calls `destroy_blob_func` when the buffer is no longer needed.
let blob = hb_blob_create( let blob = unsafe {
hb_blob_create(
buf.as_ptr() as *const c_char, buf.as_ptr() as *const c_char,
buf.len() as c_uint, buf.len() as c_uint,
HB_MEMORY_MODE_READONLY, HB_MEMORY_MODE_READONLY,
font_table_ptr as *mut c_void, font_table_ptr as *mut c_void,
Some(destroy_blob_func), Some(destroy_blob_func),
); )
};
assert!(!blob.is_null()); assert!(!blob.is_null());
blob blob
},
}
}
} }
extern "C" fn destroy_blob_func(font_table_ptr: *mut c_void) { extern "C" fn destroy_blob_func(font_table_ptr: *mut c_void) {