Pier Angelo Vendrame pushed to branch tor-browser-140.10.0esr-15.0-1 at The Tor Project / Applications / Tor Browser Commits: 1ca1b1fb by Jonathan Kew at 2026-04-16T08:41:11+02:00 Bug 2009213 - Use local statics for harfbuzz callback pointers, to ensure thread-safe initialization. r=gfx-reviewers,lsalzman Differential Revision: https://phabricator.services.mozilla.com/D278945 - - - - - 2 changed files: - gfx/thebes/gfxHarfBuzzShaper.cpp - gfx/thebes/gfxHarfBuzzShaper.h Changes: ===================================== gfx/thebes/gfxHarfBuzzShaper.cpp ===================================== @@ -1181,9 +1181,6 @@ static void AddOpenTypeFeature(uint32_t aTag, uint32_t aValue, void* aUserArg) { * gfxFontShaper override to initialize the text run using HarfBuzz */ -static hb_font_funcs_t* sHBFontFuncs = nullptr; -static hb_font_funcs_t* sNominalGlyphFunc = nullptr; -static hb_unicode_funcs_t* sHBUnicodeFuncs = nullptr; MOZ_RUNINIT static const hb_script_t sMathScript = hb_ot_tag_to_script(HB_TAG('m', 'a', 't', 'h')); @@ -1192,52 +1189,58 @@ bool gfxHarfBuzzShaper::Initialize() { // other thread can yet be using it. MOZ_PUSH_IGNORE_THREAD_SAFETY - if (!sHBFontFuncs) { - // static function callback pointers, initialized by the first - // harfbuzz shaper used - sHBFontFuncs = hb_font_funcs_create(); - hb_font_funcs_set_nominal_glyph_func(sHBFontFuncs, HBGetNominalGlyph, - nullptr, nullptr); - hb_font_funcs_set_nominal_glyphs_func(sHBFontFuncs, HBGetNominalGlyphs, - nullptr, nullptr); - hb_font_funcs_set_variation_glyph_func(sHBFontFuncs, HBGetVariationGlyph, - nullptr, nullptr); - hb_font_funcs_set_glyph_h_advance_func(sHBFontFuncs, HBGetGlyphHAdvance, - nullptr, nullptr); - hb_font_funcs_set_glyph_h_advances_func(sHBFontFuncs, HBGetGlyphHAdvances, - nullptr, nullptr); - hb_font_funcs_set_glyph_v_advance_func(sHBFontFuncs, HBGetGlyphVAdvance, - nullptr, nullptr); - hb_font_funcs_set_glyph_v_origin_func(sHBFontFuncs, HBGetGlyphVOrigin, - nullptr, nullptr); - hb_font_funcs_set_glyph_extents_func(sHBFontFuncs, HBGetGlyphExtents, - nullptr, nullptr); - hb_font_funcs_set_glyph_contour_point_func(sHBFontFuncs, HBGetContourPoint, + // Function callback pointers; these are local statics to ensure thread-safe + // initialization on first use. + static hb_font_funcs_t* sHBFontFuncs = [] { + auto* funcs = hb_font_funcs_create(); + hb_font_funcs_set_nominal_glyph_func(funcs, HBGetNominalGlyph, nullptr, + nullptr); + hb_font_funcs_set_nominal_glyphs_func(funcs, HBGetNominalGlyphs, nullptr, + nullptr); + hb_font_funcs_set_variation_glyph_func(funcs, HBGetVariationGlyph, nullptr, + nullptr); + hb_font_funcs_set_glyph_h_advance_func(funcs, HBGetGlyphHAdvance, nullptr, + nullptr); + hb_font_funcs_set_glyph_h_advances_func(funcs, HBGetGlyphHAdvances, nullptr, + nullptr); + hb_font_funcs_set_glyph_v_advance_func(funcs, HBGetGlyphVAdvance, nullptr, + nullptr); + hb_font_funcs_set_glyph_v_origin_func(funcs, HBGetGlyphVOrigin, nullptr, + nullptr); + hb_font_funcs_set_glyph_extents_func(funcs, HBGetGlyphExtents, nullptr, + nullptr); + hb_font_funcs_set_glyph_contour_point_func(funcs, HBGetContourPoint, nullptr, nullptr); - hb_font_funcs_set_glyph_h_kerning_func(sHBFontFuncs, HBGetHKerning, nullptr, + hb_font_funcs_set_glyph_h_kerning_func(funcs, HBGetHKerning, nullptr, nullptr); - hb_font_funcs_make_immutable(sHBFontFuncs); - - sNominalGlyphFunc = hb_font_funcs_create(); - hb_font_funcs_set_nominal_glyph_func(sNominalGlyphFunc, HBGetNominalGlyph, - nullptr, nullptr); - hb_font_funcs_make_immutable(sNominalGlyphFunc); - - sHBUnicodeFuncs = hb_unicode_funcs_create(hb_unicode_funcs_get_empty()); - hb_unicode_funcs_set_mirroring_func(sHBUnicodeFuncs, HBGetMirroring, - nullptr, nullptr); - hb_unicode_funcs_set_script_func(sHBUnicodeFuncs, HBGetScript, nullptr, - nullptr); - hb_unicode_funcs_set_general_category_func( - sHBUnicodeFuncs, HBGetGeneralCategory, nullptr, nullptr); - hb_unicode_funcs_set_combining_class_func( - sHBUnicodeFuncs, HBGetCombiningClass, nullptr, nullptr); - hb_unicode_funcs_set_compose_func(sHBUnicodeFuncs, HBUnicodeCompose, - nullptr, nullptr); - hb_unicode_funcs_set_decompose_func(sHBUnicodeFuncs, HBUnicodeDecompose, - nullptr, nullptr); - hb_unicode_funcs_make_immutable(sHBUnicodeFuncs); - } + hb_font_funcs_make_immutable(funcs); + return funcs; + }(); + + static hb_font_funcs_t* sNominalGlyphFunc = [] { + auto* funcs = hb_font_funcs_create(); + hb_font_funcs_set_nominal_glyph_func(funcs, HBGetNominalGlyph, nullptr, + nullptr); + hb_font_funcs_make_immutable(funcs); + return funcs; + }(); + + static hb_unicode_funcs_t* sHBUnicodeFuncs = [] { + auto* funcs = hb_unicode_funcs_create(hb_unicode_funcs_get_empty()); + hb_unicode_funcs_set_mirroring_func(funcs, HBGetMirroring, nullptr, + nullptr); + hb_unicode_funcs_set_script_func(funcs, HBGetScript, nullptr, nullptr); + hb_unicode_funcs_set_general_category_func(funcs, HBGetGeneralCategory, + nullptr, nullptr); + hb_unicode_funcs_set_combining_class_func(funcs, HBGetCombiningClass, + nullptr, nullptr); + hb_unicode_funcs_set_compose_func(funcs, HBUnicodeCompose, nullptr, + nullptr); + hb_unicode_funcs_set_decompose_func(funcs, HBUnicodeDecompose, nullptr, + nullptr); + hb_unicode_funcs_make_immutable(funcs); + return funcs; + }(); gfxFontEntry* entry = mFont->GetFontEntry(); if (!mUseFontGetGlyph) { @@ -1280,11 +1283,10 @@ bool gfxHarfBuzzShaper::Initialize() { hb_buffer_set_cluster_level(mBuffer, HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS); - auto* funcs = - mFont->GetFontEntry()->HasFontTable(TRUETYPE_TAG('C', 'F', 'F', ' ')) - ? sNominalGlyphFunc - : sHBFontFuncs; - mHBFont = CreateHBFont(mFont, funcs, this); + bool isCFF = + mFont->GetFontEntry()->HasFontTable(TRUETYPE_TAG('C', 'F', 'F', ' ')); + auto* funcs = isCFF ? sNominalGlyphFunc : sHBFontFuncs; + mHBFont = CreateHBFont(mFont, funcs, this, isCFF); MOZ_POP_THREAD_SAFETY @@ -1293,12 +1295,13 @@ bool gfxHarfBuzzShaper::Initialize() { hb_font_t* gfxHarfBuzzShaper::CreateHBFont(gfxFont* aFont, hb_font_funcs_t* aFontFuncs, - void* aCallbackData) { + void* aCallbackData, + bool aCreateSubfont) { auto face(aFont->GetFontEntry()->GetHBFace()); hb_font_t* result = hb_font_create(face); if (aFontFuncs && aCallbackData) { - if (aFontFuncs == sNominalGlyphFunc) { + if (aCreateSubfont) { hb_font_t* subfont = hb_font_create_sub_font(result); hb_font_destroy(result); result = subfont; ===================================== gfx/thebes/gfxHarfBuzzShaper.h ===================================== @@ -103,7 +103,8 @@ class gfxHarfBuzzShaper : public gfxFontShaper { // bounds, etc; if not, the built-in hb_ot font functions will be used. static hb_font_t* CreateHBFont(gfxFont* aFont, hb_font_funcs_t* aFontFuncs = nullptr, - void* aCallbackData = nullptr); + void* aCallbackData = nullptr, + bool aCreateSubfont = false); protected: // Initializes the shaper and returns whether this was successful. View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/1ca1b1fb... -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/1ca1b1fb... You're receiving this email because of your account on gitlab.torproject.org. Manage all notifications: https://gitlab.torproject.org/-/profile/notifications | Help: https://gitlab.torproject.org/help