Fix an issue 'heap use after free'
authorJUN FANG <jun_fang@foxitsoftware.com>
Fri, 17 Apr 2015 18:46:08 +0000 (11:46 -0700)
committerJUN FANG <jun_fang@foxitsoftware.com>
Fri, 17 Apr 2015 18:46:08 +0000 (11:46 -0700)
This fix is for covering more scenarios. Some faces like Foxit defined faces and MM faces are managed in built-in manager. They are released in built-in manager not in fontMgr.

BUG=452793
R=tsepez@chromium.org

Review URL: https://codereview.chromium.org/1095733003

core/include/fxge/fx_font.h
core/src/fxge/ge/fx_ge_fontmap.cpp

index 1199147..06b55cf 100644 (file)
@@ -292,38 +292,42 @@ class CFX_FontMapper : public IFX_FontMapper
 public:
     CFX_FontMapper();
     virtual ~CFX_FontMapper();
-    void                               SetSystemFontInfo(IFX_SystemFontInfo* pFontInfo);
-    IFX_SystemFontInfo*        GetSystemFontInfo()
+    void                        SetSystemFontInfo(IFX_SystemFontInfo* pFontInfo);
+    IFX_SystemFontInfo*         GetSystemFontInfo()
     {
         return m_pFontInfo;
     }
-    void                               AddInstalledFont(const CFX_ByteString& name, int charset);
-    void                               LoadInstalledFonts();
-    CFX_ByteStringArray        m_InstalledTTFonts;
-    void                               SetFontEnumerator(IFX_FontEnumerator* pFontEnumerator)
+    void                        AddInstalledFont(const CFX_ByteString& name, int charset);
+    void                        LoadInstalledFonts();
+    CFX_ByteStringArray         m_InstalledTTFonts;
+    void                        SetFontEnumerator(IFX_FontEnumerator* pFontEnumerator)
     {
         m_pFontEnumerator = pFontEnumerator;
     }
-    IFX_FontEnumerator*        GetFontEnumerator() const
+    IFX_FontEnumerator*         GetFontEnumerator() const
     {
         return m_pFontEnumerator;
     }
-    virtual FXFT_Face  FindSubstFont(const CFX_ByteString& face_name, FX_BOOL bTrueType, FX_DWORD flags,
-                                      int weight, int italic_angle, int CharsetCP, CFX_SubstFont* pSubstFont);
-    FXFT_Face  FindSubstFontByUnicode(FX_DWORD dwUnicode, FX_DWORD flags, int weight, int italic_angle);\r
+    virtual FXFT_Face           FindSubstFont(const CFX_ByteString& face_name, FX_BOOL bTrueType, FX_DWORD flags,
+                                              int weight, int italic_angle, int CharsetCP, CFX_SubstFont* pSubstFont);
+    FXFT_Face                   FindSubstFontByUnicode(FX_DWORD dwUnicode, FX_DWORD flags, int weight, int italic_angle);\r
+    FX_BOOL                     IsBuiltinFace(const FXFT_Face face) const;
+
 private:
-    CFX_ByteString             GetPSNameFromTT(void* hFont);
-    CFX_ByteString             MatchInstalledFonts(const CFX_ByteString& norm_name);
-    FXFT_Face                  UseInternalSubst(CFX_SubstFont* pSubstFont, int iBaseFont, int italic_angle, int weight, int picthfamily);
-
-    FX_BOOL                            m_bListLoaded;
-    FXFT_Face                  m_MMFaces[2];
-    CFX_ByteString             m_LastFamily;
-    CFX_DWordArray             m_CharsetArray;
-    CFX_ByteStringArray        m_FaceArray;
-    IFX_SystemFontInfo*        m_pFontInfo;
-    FXFT_Face                  m_FoxitFaces[14];
-    IFX_FontEnumerator*                m_pFontEnumerator;
+    const static size_t         MM_FACE_COUNT = 2;
+    const static size_t         FOXIT_FACE_COUNT = 14;
+    CFX_ByteString              GetPSNameFromTT(void* hFont);
+    CFX_ByteString              MatchInstalledFonts(const CFX_ByteString& norm_name);
+    FXFT_Face                   UseInternalSubst(CFX_SubstFont* pSubstFont, int iBaseFont, int italic_angle, int weight, int picthfamily);
+
+    FX_BOOL                     m_bListLoaded;
+    FXFT_Face                   m_MMFaces[MM_FACE_COUNT];
+    CFX_ByteString              m_LastFamily;
+    CFX_DWordArray              m_CharsetArray;
+    CFX_ByteStringArray         m_FaceArray;
+    IFX_SystemFontInfo*         m_pFontInfo;
+    FXFT_Face                   m_FoxitFaces[FOXIT_FACE_COUNT];
+    IFX_FontEnumerator*         m_pFontEnumerator;
 };
 class IFX_SystemFontInfo 
 {
index 3230ea0..9a8380b 100644 (file)
@@ -36,11 +36,11 @@ CTTFontDesc::~CTTFontDesc()
         FX_Free(m_pFontData);
     }
 }
-FX_BOOL CTTFontDesc::ReleaseFace(FXFT_Face face)
+FX_INT32 CTTFontDesc::ReleaseFace(FXFT_Face face)
 {
     if (m_Type == 1) {
         if (m_SingleFace.m_pFace != face) {
-            return FALSE;
+            return -1;
         }
     } else if (m_Type == 2) {
         int i;
@@ -49,15 +49,15 @@ FX_BOOL CTTFontDesc::ReleaseFace(FXFT_Face face)
                 break;
             }
         if (i == 16) {
-            return FALSE;
+            return -1;
         }
     }
     m_RefCount --;
     if (m_RefCount) {
-        return FALSE;
+        return m_RefCount;
     }
     delete this;
-    return TRUE;
+    return 0;
 }
 CFX_FontMgr::CFX_FontMgr()
 {
@@ -394,18 +394,21 @@ void CFX_FontMgr::ReleaseFace(FXFT_Face face)
     if (face == NULL) {
         return;
     }
-    FX_BOOL bFaceDone = FALSE;
     FX_POSITION pos = m_FaceMap.GetStartPosition();
+    FX_BOOL bNeedFaceDone = TRUE;
     while(pos) {
         CFX_ByteString Key;
         CTTFontDesc* ttface;
         m_FaceMap.GetNextAssoc(pos, Key, (void*&)ttface);
-        if (ttface->ReleaseFace(face)) {
+        int nRet = ttface->ReleaseFace(face);
+        if (nRet == 0) {
             m_FaceMap.RemoveKey(Key);
-            bFaceDone = TRUE;
+            bNeedFaceDone = FALSE;
+        } else if (nRet > 0) {
+            bNeedFaceDone = FALSE;
         }
     }
-    if (!bFaceDone) {
+    if (bNeedFaceDone && !m_pBuiltinMapper->IsBuiltinFace(face)) {
         FXFT_Done_Face(face);
     }
 }
@@ -1341,6 +1344,21 @@ FXFT_Face CFX_FontMapper::FindSubstFontByUnicode(FX_DWORD dwUnicode, FX_DWORD fl
     m_pFontInfo->DeleteFont(hFont);\r
     return face;\r
 }\r
+
+FX_BOOL CFX_FontMapper::IsBuiltinFace(const FXFT_Face face) const
+{
+    for (int i = 0; i < MM_FACE_COUNT; ++i) {
+        if (m_MMFaces[i] == face) {
+            return TRUE;
+        }
+    }
+    for (int i = 0; i < FOXIT_FACE_COUNT; ++i) {
+        if (m_FoxitFaces[i] == face) {
+            return TRUE;
+        }
+    }
+    return FALSE;
+} 
 extern "C" {
     unsigned long _FTStreamRead(FXFT_Stream stream, unsigned long offset,
                                 unsigned char* buffer, unsigned long count);