b=618406 avoid crashy versions of FT_Face_GetCharVariantIndex r=jfkthame a=blocking
authorKarl Tomlinson <karlt+@karlt.net>
Tue, 14 Dec 2010 08:44:55 +1300
changeset 59160 2b3626056e132c6bb9019836c41050b1e83c9e40
parent 59159 302ec4161442fd0ce025bd00525b8350dd2a24c7
child 59161 cef32fff6f24f3f0e47a21b7698039dbc7d8f23a
child 59386 0193e46f04a659f21eef5b20dd491834883baba4
push id1
push usershaver@mozilla.com
push dateTue, 04 Jan 2011 17:58:04 +0000
reviewersjfkthame, blocking
bugs618406
milestone2.0b8pre
b=618406 avoid crashy versions of FT_Face_GetCharVariantIndex r=jfkthame a=blocking
gfx/thebes/gfxFT2Utils.cpp
gfx/thebes/gfxFT2Utils.h
--- a/gfx/thebes/gfxFT2Utils.cpp
+++ b/gfx/thebes/gfxFT2Utils.cpp
@@ -46,28 +46,16 @@
 #include FT_TRUETYPE_TABLES_H
 
 #ifdef HAVE_FONTCONFIG_FCFREETYPE_H
 #include <fontconfig/fcfreetype.h>
 #endif
 
 #include "prlink.h"
 
-static PRFuncPtr
-FindFunctionSymbol(const char *name)
-{
-    PRLibrary *lib = nsnull;
-    PRFuncPtr result = PR_FindFunctionSymbolAndLibrary(name, &lib);
-    if (lib) {
-        PR_UnloadLibrary(lib);
-    }
-
-    return result;
-}
-
 // aScale is intended for a 16.16 x/y_scale of an FT_Size_Metrics
 static inline FT_Long
 ScaleRoundDesignUnits(FT_Short aDesignMetric, FT_Fixed aScale)
 {
     FT_Long fixed26dot6 = FT_MulFix(aDesignMetric, aScale);
     return ROUND_26_6_TO_INT(fixed26dot6);
 }
 
@@ -345,20 +333,17 @@ PRUint32
 gfxFT2LockedFace::GetUVSGlyph(PRUint32 aCharCode, PRUint32 aVariantSelector)
 {
     NS_PRECONDITION(aVariantSelector, "aVariantSelector should not be NULL");
 
     if (NS_UNLIKELY(!mFace))
         return 0;
 
     // This function is available from FreeType 2.3.6 (June 2008).
-    static GetCharVariantFunction sGetCharVariantPtr =
-        reinterpret_cast<GetCharVariantFunction>
-        (FindFunctionSymbol("FT_Face_GetCharVariantIndex"));
-
+    static CharVariantFunction sGetCharVariantPtr = FindCharVariantFunction();
     if (!sGetCharVariantPtr)
         return 0;
 
 #ifdef HAVE_FONTCONFIG_FCFREETYPE_H
     // FcFreeTypeCharIndex may have changed the selected charmap.
     // FT_Face_GetCharVariantIndex needs a unicode charmap.
     if (!mFace->charmap || mFace->charmap->encoding != FT_ENCODING_UNICODE) {
         FT_Select_Charmap(mFace, FT_ENCODING_UNICODE);
@@ -403,8 +388,40 @@ gfxFT2LockedFace::GetCharExtents(char aC
 
     FT_UInt gid = mGfxFont->GetGlyph(aChar);
     if (gid) {
         mGfxFont->GetGlyphExtents(gid, aExtents);
     }
 
     return gid;
 }
+
+gfxFT2LockedFace::CharVariantFunction
+gfxFT2LockedFace::FindCharVariantFunction()
+{
+    // This function is available from FreeType 2.3.6 (June 2008).
+    PRLibrary *lib = nsnull;
+    CharVariantFunction function =
+        reinterpret_cast<CharVariantFunction>
+        (PR_FindFunctionSymbolAndLibrary("FT_Face_GetCharVariantIndex", &lib));
+    if (!lib) {
+        return nsnull;
+    }
+
+    FT_Int major;
+    FT_Int minor;
+    FT_Int patch;
+    FT_Library_Version(mFace->glyph->library, &major, &minor, &patch);
+
+    // Versions 2.4.0 to 2.4.3 crash if configured with
+    // FT_CONFIG_OPTION_OLD_INTERNALS.  Presence of the symbol FT_Alloc
+    // indicates FT_CONFIG_OPTION_OLD_INTERNALS.
+    if (major == 2 && minor == 4 && patch < 4 &&
+        PR_FindFunctionSymbol(lib, "FT_Alloc")) {
+        function = nsnull;
+    }
+
+    // Decrement the reference count incremented in
+    // PR_FindFunctionSymbolAndLibrary.
+    PR_UnloadLibrary(lib);
+
+    return function;
+}
--- a/gfx/thebes/gfxFT2Utils.h
+++ b/gfx/thebes/gfxFT2Utils.h
@@ -115,13 +115,18 @@ public:
 protected:
     /**
      * Get extents for a simple character representable by a single glyph.
      * The return value is the glyph id of that glyph or zero if no such glyph
      * exists.  aExtents is only set when this returns a non-zero glyph id.
      */
     PRUint32 GetCharExtents(char aChar, cairo_text_extents_t* aExtents);
 
+    typedef FT_UInt (*CharVariantFunction)(FT_Face  face,
+                                           FT_ULong charcode,
+                                           FT_ULong variantSelector);
+    CharVariantFunction FindCharVariantFunction();
+
     nsRefPtr<gfxFT2FontBase> mGfxFont;
     FT_Face mFace;
 };
 
 #endif /* GFX_FT2UTILS_H */