Font is used after release in CPDF_TextStateData::~CPDF_TextStateData
authorJun Fang <jun_fang@foxitsoftware.com>
Mon, 18 Aug 2014 23:39:43 +0000 (16:39 -0700)
committerJun Fang <jun_fang@foxitsoftware.com>
Mon, 18 Aug 2014 23:39:43 +0000 (16:39 -0700)
BUG=400996
R=tsepez@chromium.org

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

core/include/fpdfapi/fpdf_pageobj.h
core/src/fpdfapi/fpdf_page/fpdf_page_doc.cpp
core/src/fpdfapi/fpdf_page/fpdf_page_graph_state.cpp
core/src/fpdfapi/fpdf_page/pageint.h

index 90e1b0b..307fb16 100644 (file)
@@ -220,6 +220,8 @@ public:
 
     CPDF_Font*                 m_pFont;
 
+    CPDF_Document*             m_pDocument;
+
     FX_FLOAT                   m_FontSize;
 
     FX_FLOAT                   m_CharSpace;
index 097bd61..0b52800 100644 (file)
@@ -134,6 +134,7 @@ CPDF_DocPageData::CPDF_DocPageData(CPDF_Document *pPDFDoc)
     , m_ImageMap()
     , m_IccProfileMap()
     , m_FontFileMap()
+    , m_bForceClear(FALSE)
 {
     m_FontMap.InitHashTable(64);
     m_ColorSpaceMap.InitHashTable(32);
@@ -147,99 +148,89 @@ CPDF_DocPageData::~CPDF_DocPageData()
     Clear(FALSE);
     Clear(TRUE);
 }
-void CPDF_DocPageData::Clear(FX_BOOL bRelease)
+void CPDF_DocPageData::Clear(FX_BOOL bForceRelease)
 {
     FX_POSITION pos;
     FX_DWORD   nCount;
-    {
-        pos = m_PatternMap.GetStartPosition();
-        while (pos) {
-            CPDF_Object* ptObj;
-            CPDF_CountedObject<CPDF_Pattern*>* ptData;
-            m_PatternMap.GetNextAssoc(pos, ptObj, ptData);
-            nCount = ptData->m_nCount;
-            if (bRelease || nCount < 2) {
-                delete ptData->m_Obj;
-                ptData->m_Obj = NULL;
-            }
+
+    m_bForceClear = bForceRelease;
+    pos = m_PatternMap.GetStartPosition();
+    while (pos) {
+        CPDF_Object* ptObj;
+        CPDF_CountedObject<CPDF_Pattern*>* ptData;
+        m_PatternMap.GetNextAssoc(pos, ptObj, ptData);
+        nCount = ptData->m_nCount;
+        if (bForceRelease || nCount < 2) {
+            delete ptData->m_Obj;
+            ptData->m_Obj = NULL;
         }
     }
-    {
-        pos = m_FontMap.GetStartPosition();
-        while (pos) {
-            CPDF_Dictionary* fontDict;
-            CPDF_CountedObject<CPDF_Font*>* fontData;
-            m_FontMap.GetNextAssoc(pos, fontDict, fontData);
-            nCount = fontData->m_nCount;
-            if (bRelease || nCount < 2) {
-                delete fontData->m_Obj;
-                fontData->m_Obj = NULL;
-            }
+    pos = m_FontMap.GetStartPosition();
+    while (pos) {
+        CPDF_Dictionary* fontDict;
+        CPDF_CountedObject<CPDF_Font*>* fontData;
+        m_FontMap.GetNextAssoc(pos, fontDict, fontData);
+        nCount = fontData->m_nCount;
+        if (bForceRelease || nCount < 2) {
+            delete fontData->m_Obj;
+            fontData->m_Obj = NULL;
         }
     }
-    {
-        pos = m_ImageMap.GetStartPosition();
-        while (pos) {
-            FX_DWORD objNum;
-            CPDF_CountedObject<CPDF_Image*>* imageData;
-            m_ImageMap.GetNextAssoc(pos, objNum, imageData);
-            nCount = imageData->m_nCount;
-            if (bRelease || nCount < 2) {
-                delete imageData->m_Obj;
-                delete imageData;
-                m_ImageMap.RemoveKey(objNum);
-            }
+    pos = m_ImageMap.GetStartPosition();
+    while (pos) {
+        FX_DWORD objNum;
+        CPDF_CountedObject<CPDF_Image*>* imageData;
+        m_ImageMap.GetNextAssoc(pos, objNum, imageData);
+        nCount = imageData->m_nCount;
+        if (bForceRelease || nCount < 2) {
+            delete imageData->m_Obj;
+            delete imageData;
+            m_ImageMap.RemoveKey(objNum);
         }
     }
-    {
-        pos = m_ColorSpaceMap.GetStartPosition();
-        while (pos) {
-            CPDF_Object* csKey;
-            CPDF_CountedObject<CPDF_ColorSpace*>* csData;
-            m_ColorSpaceMap.GetNextAssoc(pos, csKey, csData);
-            nCount = csData->m_nCount;
-            if (bRelease || nCount < 2) {
-                csData->m_Obj->ReleaseCS();
-                csData->m_Obj = NULL;
-            }
+    pos = m_ColorSpaceMap.GetStartPosition();
+    while (pos) {
+        CPDF_Object* csKey;
+        CPDF_CountedObject<CPDF_ColorSpace*>* csData;
+        m_ColorSpaceMap.GetNextAssoc(pos, csKey, csData);
+        nCount = csData->m_nCount;
+        if (bForceRelease || nCount < 2) {
+            csData->m_Obj->ReleaseCS();
+            csData->m_Obj = NULL;
         }
     }
-    {
-        pos = m_IccProfileMap.GetStartPosition();
-        while (pos) {
-            CPDF_Stream* ipKey;
-            CPDF_CountedObject<CPDF_IccProfile*>* ipData;
-            m_IccProfileMap.GetNextAssoc(pos, ipKey, ipData);
-            nCount = ipData->m_nCount;
-            if (bRelease || nCount < 2) {
-                FX_POSITION pos2 = m_HashProfileMap.GetStartPosition();
-                while (pos2) {
-                    CFX_ByteString bsKey;
-                    CPDF_Stream* pFindStream = NULL;
-                    m_HashProfileMap.GetNextAssoc(pos2, bsKey, (void*&)pFindStream);
-                    if (ipKey == pFindStream) {
-                        m_HashProfileMap.RemoveKey(bsKey);
-                        break;
-                    }
+    pos = m_IccProfileMap.GetStartPosition();
+    while (pos) {
+        CPDF_Stream* ipKey;
+        CPDF_CountedObject<CPDF_IccProfile*>* ipData;
+        m_IccProfileMap.GetNextAssoc(pos, ipKey, ipData);
+        nCount = ipData->m_nCount;
+        if (bForceRelease || nCount < 2) {
+            FX_POSITION pos2 = m_HashProfileMap.GetStartPosition();
+            while (pos2) {
+                CFX_ByteString bsKey;
+                CPDF_Stream* pFindStream = NULL;
+                m_HashProfileMap.GetNextAssoc(pos2, bsKey, (void*&)pFindStream);
+                if (ipKey == pFindStream) {
+                    m_HashProfileMap.RemoveKey(bsKey);
+                    break;
                 }
-                delete ipData->m_Obj;
-                delete ipData;
-                m_IccProfileMap.RemoveKey(ipKey);
             }
+            delete ipData->m_Obj;
+            delete ipData;
+            m_IccProfileMap.RemoveKey(ipKey);
         }
     }
-    {
-        pos = m_FontFileMap.GetStartPosition();
-        while (pos) {
-            CPDF_Stream* ftKey;
-            CPDF_CountedObject<CPDF_StreamAcc*>* ftData;
-            m_FontFileMap.GetNextAssoc(pos, ftKey, ftData);
-            nCount = ftData->m_nCount;
-            if (bRelease || nCount < 2) {
-                delete ftData->m_Obj;
-                delete ftData;
-                m_FontFileMap.RemoveKey(ftKey);
-            }
+    pos = m_FontFileMap.GetStartPosition();
+    while (pos) {
+        CPDF_Stream* ftKey;
+        CPDF_CountedObject<CPDF_StreamAcc*>* ftData;
+        m_FontFileMap.GetNextAssoc(pos, ftKey, ftData);
+        nCount = ftData->m_nCount;
+        if (bForceRelease || nCount < 2) {
+            delete ftData->m_Obj;
+            delete ftData;
+            m_FontFileMap.RemoveKey(ftKey);
         }
     }
 }
index 8053718..99bb5b8 100644 (file)
@@ -285,6 +285,7 @@ void CPDF_ColorState::SetStrokePattern(CPDF_Pattern* pPattern, FX_FLOAT* pValue,
 CPDF_TextStateData::CPDF_TextStateData()
 {
     m_pFont = NULL;
+    m_pDocument = NULL;
     m_FontSize = 1.0f;
     m_WordSpace = 0;
     m_CharSpace = 0;
@@ -296,27 +297,35 @@ CPDF_TextStateData::CPDF_TextStateData()
 }
 CPDF_TextStateData::CPDF_TextStateData(const CPDF_TextStateData& src)
 {
+    if (this == &src) {
+        return;
+    }
     FXSYS_memcpy32(this, &src, sizeof(CPDF_TextStateData));
-    if (m_pFont && m_pFont->m_pDocument) {
-        m_pFont = m_pFont->m_pDocument->GetPageData()->GetFont(m_pFont->GetFontDict(), FALSE);
+    if (m_pDocument && m_pFont) {
+        m_pFont = m_pDocument->GetPageData()->GetFont(m_pFont->GetFontDict(), FALSE);
     }
 }
 CPDF_TextStateData::~CPDF_TextStateData()
 {
-    CPDF_Font* pFont = m_pFont;
-    if (pFont && pFont->m_pDocument) {
-        pFont->m_pDocument->GetPageData()->ReleaseFont(pFont->GetFontDict());
+    if (m_pDocument && m_pFont) {
+        CPDF_DocPageData *pPageData = m_pDocument->GetPageData();
+        if (pPageData && !pPageData->IsForceClear()) {
+            pPageData->ReleaseFont(m_pFont->GetFontDict());
+        }
     }
 }
 void CPDF_TextState::SetFont(CPDF_Font* pFont)
 {
-    CPDF_Font*& pStateFont = GetModify()->m_pFont;
-    CPDF_DocPageData* pDocPageData = NULL;
-    if (pStateFont && pStateFont->m_pDocument) {
-        pDocPageData = pStateFont->m_pDocument->GetPageData();
-        pDocPageData->ReleaseFont(pStateFont->GetFontDict());
+    CPDF_TextStateData* pStateData = GetModify();
+    if (pStateData) {
+        CPDF_Document* pDoc = pStateData->m_pDocument;
+        CPDF_DocPageData *pPageData = pDoc ? pDoc->GetPageData() : NULL;
+        if (pPageData && pStateData->m_pFont && !pPageData->IsForceClear()) {
+            pPageData->ReleaseFont(pStateData->m_pFont->GetFontDict());
+        }
+        pStateData->m_pDocument = pFont ? pFont->m_pDocument : NULL;
+        pStateData->m_pFont = pFont;
     }
-    pStateFont = pFont;
 }
 FX_FLOAT CPDF_TextState::GetFontSizeV() const
 {
index 52aded0..625e5df 100644 (file)
@@ -415,29 +415,32 @@ class CPDF_DocPageData : public CFX_Object
 public:
     CPDF_DocPageData(CPDF_Document *pPDFDoc);
     ~CPDF_DocPageData();
-    void                                       Clear(FX_BOOL bRelease = FALSE);
-    CPDF_Font*                         GetFont(CPDF_Dictionary* pFontDict, FX_BOOL findOnly);
-    CPDF_Font*                         GetStandardFont(FX_BSTR fontName, CPDF_FontEncoding* pEncoding);
-    void                                       ReleaseFont(CPDF_Dictionary* pFontDict);
-    CPDF_ColorSpace*           GetColorSpace(CPDF_Object* pCSObj, CPDF_Dictionary* pResources);
-    CPDF_ColorSpace*           GetCopiedColorSpace(CPDF_Object* pCSObj);
-    void                                       ReleaseColorSpace(CPDF_Object* pColorSpace);
-    CPDF_Pattern*                      GetPattern(CPDF_Object* pPatternObj, FX_BOOL bShading, const CFX_AffineMatrix* matrix);
-    void                                       ReleasePattern(CPDF_Object* pPatternObj);
-    CPDF_Image*                                GetImage(CPDF_Object* pImageStream);
-    void                                       ReleaseImage(CPDF_Object* pImageStream);
-    CPDF_IccProfile*           GetIccProfile(CPDF_Stream* pIccProfileStream, FX_INT32 nComponents);
-    void                                       ReleaseIccProfile(CPDF_Stream* pIccProfileStream, CPDF_IccProfile* pIccProfile);
-    CPDF_StreamAcc*                    GetFontFileStreamAcc(CPDF_Stream* pFontStream);
-    void                                       ReleaseFontFileStreamAcc(CPDF_Stream* pFontStream, FX_BOOL bForce = FALSE);
-    CPDF_Document*                     m_pPDFDoc;
-    CPDF_FontMap                       m_FontMap;
-    CPDF_ColorSpaceMap         m_ColorSpaceMap;
-    CPDF_PatternMap                    m_PatternMap;
-    CPDF_ImageMap                      m_ImageMap;
-    CPDF_IccProfileMap         m_IccProfileMap;
-    CFX_MapByteStringToPtr     m_HashProfileMap;
-    CPDF_FontFileMap           m_FontFileMap;
+    void                        Clear(FX_BOOL bRelease = FALSE);
+    CPDF_Font*                  GetFont(CPDF_Dictionary* pFontDict, FX_BOOL findOnly);
+    CPDF_Font*                  GetStandardFont(FX_BSTR fontName, CPDF_FontEncoding* pEncoding);
+    void                        ReleaseFont(CPDF_Dictionary* pFontDict);
+    CPDF_ColorSpace*            GetColorSpace(CPDF_Object* pCSObj, CPDF_Dictionary* pResources);
+    CPDF_ColorSpace*            GetCopiedColorSpace(CPDF_Object* pCSObj);
+    void                        ReleaseColorSpace(CPDF_Object* pColorSpace);
+    CPDF_Pattern*               GetPattern(CPDF_Object* pPatternObj, FX_BOOL bShading, const CFX_AffineMatrix* matrix);
+    void                        ReleasePattern(CPDF_Object* pPatternObj);
+    CPDF_Image*                 GetImage(CPDF_Object* pImageStream);
+    void                        ReleaseImage(CPDF_Object* pImageStream);
+    CPDF_IccProfile*            GetIccProfile(CPDF_Stream* pIccProfileStream, FX_INT32 nComponents);
+    void                        ReleaseIccProfile(CPDF_Stream* pIccProfileStream, CPDF_IccProfile* pIccProfile);
+    CPDF_StreamAcc*             GetFontFileStreamAcc(CPDF_Stream* pFontStream);
+    void                        ReleaseFontFileStreamAcc(CPDF_Stream* pFontStream, FX_BOOL bForce = FALSE);
+    FX_BOOL                     IsForceClear() const {return m_bForceClear;}
+
+    CPDF_Document*              m_pPDFDoc;
+    CPDF_FontMap                m_FontMap;
+    CPDF_ColorSpaceMap          m_ColorSpaceMap;
+    CPDF_PatternMap             m_PatternMap;
+    CPDF_ImageMap               m_ImageMap;
+    CPDF_IccProfileMap          m_IccProfileMap;
+    CFX_MapByteStringToPtr      m_HashProfileMap;
+    CPDF_FontFileMap            m_FontFileMap;
+    FX_BOOL                     m_bForceClear;
 };
 class CPDF_Function : public CFX_Object
 {