You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
If a glyph was loaded using LoadFlag::RENDER like this:
use freetype::Library;use freetype::face::LoadFlag;let lib = Library::init().unwrap();let face = lib.new_face("test.ttf",0).unwrap();
face.load_char('A'asusize,LoadFlag::RENDER).unwrap();
and created a bitmap glyph using to_bitmap:
let glyph_slot = face.glyph();let glyph = glyph_slot.get_glyph().unwrap();let bitmap_glyph = glyph.to_bitmap(RenderMode::Normal,None).unwrap();
In to_bitmap, not only it will pass the_glyph(which contains self's raw pointer) to FT_Glyph_To_Bitmap, but it also receives the resulting pointer through the_glyph. So the_glyph would contain pointer to the new glyph after successful FT_Glyph_To_Bitmap.
Ok(unsafe{BitmapGlyph::from_raw(self.library_raw, the_glyph as ffi::FT_BitmapGlyph)})
But the problem is that FT_Glyph_To_Bitmap will NOT replace the_glyph's value if glyph was already rendered(and still return error code 0, which means it's OK). I was able to confirm this by modifying the source code like this, and checking the output:
letmut the_glyph = self.raw;letmut p_origin = null_mut();dbg!(the_glyph);// <- Before FT_Glyph_To_BitmapifletSome(refmut o) = origin {
p_origin = o as*mutVector;}let err =
unsafe{ ffi::FT_Glyph_To_Bitmap(&mut the_glyph, render_mode asu32, p_origin,0)};dbg!(the_glyph);// <- After FT_Glyph_To_Bitmap// *** Both dbg! printed the SAME result! ***dbg!(err);// <- Just to confirm that error code was actually 0, and it was.
So to_bitmap copies the old value(which is again, self's raw pointer) to the BitmapGlyph, creating two glyphs pointing to the same glyph. Not only this means modifying old glyph can affect the "new" BitmapGlyph, but it also means when drop is called on both glyphs, it will cause double-free and eventually segfault.
Using DEFAULT flag(which does not render the glyph) does stop the segfault, and to_bitmap works without any issue.
So I think there should be a check if glyph is already a bitmap before calling FT_Glyph_To_Bitmap. FT_GlyphRec's format field might help that.
A code that segfaults
Below simply loads a glyph with LoadFlag::RENDER(which renders the glyph and turns it into bitmap), and then tries to convert it to bitmap. I used explicit drop call to show exactly where it was segfaulting.
Finished dev [unoptimized + debuginfo] target(s) in 0.01s
Running `target/debug/freetype-rs-segfault`
drop()ping bitmap_glyph
drop()ped bitmap_glyph
drop()ping glyph
Segmentation fault (core dumped)
Backtrace:
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7eda102 in FT_Done_Glyph () from /usr/lib/libfreetype.so.6
(gdb) bt
#0 0x00007ffff7eda102 in FT_Done_Glyph () from /usr/lib/libfreetype.so.6
#1 0x000055555555d9ab in freetype::glyph::{{impl}}::drop (self=0x7fffffffe138)
at /home/kun/.cargo/registry/src/github.com-1ecc6299db9ec823/freetype-rs-0.26.0/src/glyph.rs:170
#2 0x000055555555ab1f in core::ptr::drop_in_place<freetype::glyph::Glyph> ()
at /home/kun/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:175
#3 0x000055555555b8b8 in core::mem::drop<freetype::glyph::Glyph> (_x=...)
at /home/kun/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/mem/mod.rs:881
#4 0x000055555555b1fb in freetype_rs_segfault::main () at src/main.rs:20
It probably segfaulted because two glyphs were sharing the pointer(because of the bug I mentioned above), and dropping one of them invalidated the other glyph.
The text was updated successfully, but these errors were encountered:
If a glyph was loaded using
LoadFlag::RENDER
like this:and created a bitmap glyph using
to_bitmap
:In
to_bitmap
, not only it will passthe_glyph
(which containsself
's raw pointer) toFT_Glyph_To_Bitmap
, but it also receives the resulting pointer throughthe_glyph
. Sothe_glyph
would contain pointer to the new glyph after successfulFT_Glyph_To_Bitmap
.freetype-rs/src/glyph.rs
Lines 76 to 86 in 5975d3c
But the problem is that
FT_Glyph_To_Bitmap
will NOT replacethe_glyph
's value if glyph was already rendered(and still return error code 0, which means it's OK). I was able to confirm this by modifying the source code like this, and checking the output:So
to_bitmap
copies the old value(which is again,self
's raw pointer) to theBitmapGlyph
, creating two glyphs pointing to the same glyph. Not only this means modifying old glyph can affect the "new"BitmapGlyph
, but it also means whendrop
is called on both glyphs, it will cause double-free and eventually segfault.Using
DEFAULT
flag(which does not render the glyph) does stop the segfault, andto_bitmap
works without any issue.So I think there should be a check if glyph is already a bitmap before calling
FT_Glyph_To_Bitmap
.FT_GlyphRec
'sformat
field might help that.A code that segfaults
Below simply loads a glyph with
LoadFlag::RENDER
(which renders the glyph and turns it into bitmap), and then tries to convert it to bitmap. I used explicitdrop
call to show exactly where it was segfaulting.This will crash with following output:
Backtrace:
It probably segfaulted because two glyphs were sharing the pointer(because of the bug I mentioned above), and
drop
ping one of them invalidated the other glyph.The text was updated successfully, but these errors were encountered: