Store the address of the page data map's value for proper referencing.
authorBo Xu <bo_xu@foxitsoftware.com>
Wed, 15 Oct 2014 00:10:06 +0000 (17:10 -0700)
committerBo Xu <bo_xu@foxitsoftware.com>
Wed, 15 Oct 2014 00:10:06 +0000 (17:10 -0700)
CPDF_Pattern objects are counted and maintained in m_PatternedMap.
When a CPDF_Pattern object "pattern" is deleted, it's address is marked as NULL in m_PatternMap.
This patch stores the address of CPDF_Pattern's adderss in all objects that references "pattern",
to ensure valid referencing after deletion.

BUG=416319, 419976, 418392
R=tsepez@chromium.org

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

core/include/fpdfapi/fpdf_resource.h
core/src/fpdfapi/fpdf_page/fpdf_page_colors.cpp
core/src/fpdfapi/fpdf_page/fpdf_page_doc.cpp
core/src/fpdfapi/fpdf_page/fpdf_page_pattern.cpp
core/src/fpdfapi/fpdf_page/pageint.h

index 7bad015..54e1c97 100644 (file)
@@ -38,6 +38,28 @@ class CFX_DIBitmap;
 typedef struct FT_FaceRec_* FXFT_Face;
 class CFX_CTTGSUBTable;
 class CPDF_Page;
+
+template <class ObjClass> class CPDF_CountedObject : public CFX_Object
+{
+public:
+    ObjClass   m_Obj;
+    FX_DWORD   m_nCount;
+};
+typedef CPDF_CountedObject<CPDF_Font*>          CPDF_CountedFont;
+typedef CPDF_CountedObject<CPDF_ColorSpace*>    CPDF_CountedColorSpace;
+typedef CPDF_CountedObject<CPDF_Pattern*>       CPDF_CountedPattern;
+typedef CPDF_CountedObject<CPDF_Image*>         CPDF_CountedImage;
+typedef CPDF_CountedObject<CPDF_IccProfile*>    CPDF_CountedICCProfile;
+typedef CPDF_CountedObject<CPDF_StreamAcc*>     CPDF_CountedStreamAcc;
+
+
+typedef CFX_MapPtrTemplate<CPDF_Dictionary*, CPDF_CountedFont*>     CPDF_FontMap;
+typedef CFX_MapPtrTemplate<CPDF_Object*, CPDF_CountedColorSpace*>   CPDF_ColorSpaceMap;
+typedef CFX_MapPtrTemplate<CPDF_Object*, CPDF_CountedPattern*>      CPDF_PatternMap;
+typedef CFX_MapPtrTemplate<FX_DWORD, CPDF_CountedImage*>            CPDF_ImageMap;
+typedef CFX_MapPtrTemplate<CPDF_Stream*, CPDF_CountedICCProfile*>   CPDF_IccProfileMap;
+typedef CFX_MapPtrTemplate<CPDF_Stream*, CPDF_CountedStreamAcc*>    CPDF_FontFileMap;
+
 #define PDFFONT_TYPE1                  1
 #define PDFFONT_TRUETYPE               2
 #define PDFFONT_TYPE3                  3
@@ -790,8 +812,9 @@ public:
 
     int                                        m_ShadingType;
 
-    CPDF_ColorSpace*   m_pCS;
+    CPDF_ColorSpace*   m_pCS; // Still keep m_pCS as some CPDF_ColorSpace (name object) are not managed as counted objects. Refer to CPDF_DocPageData::GetColorSpace.
 
+    CPDF_CountedColorSpace*    m_pCountedCS;
 
     CPDF_Function*             m_pFunctions[4];
 
index c522dcd..5266c1a 100644 (file)
@@ -760,6 +760,7 @@ public:
     }
     virtual void               EnableStdConversion(FX_BOOL bEnabled);
     CPDF_ColorSpace*   m_pBaseCS;
+    CPDF_CountedColorSpace*     m_pCountedBaseCS;
     int                                        m_nBaseComponents;
     int                                        m_MaxIndex;
     CFX_ByteString             m_Table;
@@ -768,6 +769,7 @@ public:
 CPDF_IndexedCS::CPDF_IndexedCS()
 {
     m_pBaseCS = NULL;
+    m_pCountedBaseCS = NULL;
     m_Family = PDFCS_INDEXED;
     m_nComponents = 1;
     m_pCompMinMax = NULL;
@@ -777,6 +779,10 @@ CPDF_IndexedCS::~CPDF_IndexedCS()
     if (m_pCompMinMax) {
         FX_Free(m_pCompMinMax);
     }
+    CPDF_ColorSpace* pCS = m_pCountedBaseCS ? m_pCountedBaseCS->m_Obj : NULL;
+    if (pCS && m_pDocument) {
+        m_pDocument->GetPageData()->ReleaseColorSpace(pCS->GetArray());
+    }
 }
 FX_BOOL CPDF_IndexedCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray)
 {
@@ -792,6 +798,7 @@ FX_BOOL CPDF_IndexedCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray)
     if (m_pBaseCS == NULL) {
         return FALSE;
     }
+    m_pCountedBaseCS = pDocPageData->FindColorSpacePtr(m_pBaseCS->GetArray());
     m_nBaseComponents = m_pBaseCS->CountComponents();
     m_pCompMinMax = FX_Alloc(FX_FLOAT, m_nBaseComponents * 2);
     FX_FLOAT defvalue;
@@ -845,6 +852,7 @@ void CPDF_IndexedCS::EnableStdConversion(FX_BOOL bEnabled)
 #define MAX_PATTERN_COLORCOMPS 16
 typedef struct _PatternValue {
     CPDF_Pattern*      m_pPattern;
+    CPDF_CountedPattern*       m_pCountedPattern;
     int                                m_nComps;
     FX_FLOAT           m_Comps[MAX_PATTERN_COLORCOMPS];
 } PatternValue;
@@ -853,9 +861,14 @@ CPDF_PatternCS::CPDF_PatternCS()
     m_Family = PDFCS_PATTERN;
     m_pBaseCS = NULL;
     m_nComponents = 1;
+    m_pCountedBaseCS = NULL;
 }
 CPDF_PatternCS::~CPDF_PatternCS()
 {
+    CPDF_ColorSpace* pCS = m_pCountedBaseCS ? m_pCountedBaseCS->m_Obj : NULL;
+    if (pCS && m_pDocument) {
+           m_pDocument->GetPageData()->ReleaseColorSpace(pCS->GetArray());
+    }
 }
 FX_BOOL CPDF_PatternCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray)
 {
@@ -869,6 +882,7 @@ FX_BOOL CPDF_PatternCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray)
         if (m_pBaseCS->GetFamily() == PDFCS_PATTERN) {
             return FALSE;
         }
+        m_pCountedBaseCS = pDocPageData->FindColorSpacePtr(m_pBaseCS->GetArray());
         m_nComponents = m_pBaseCS->CountComponents() + 1;
         if (m_pBaseCS->CountComponents() > MAX_PATTERN_COLORCOMPS) {
             return FALSE;
@@ -1291,10 +1305,10 @@ void CPDF_Color::ReleaseBuffer()
     }
     if (m_pCS->GetFamily() == PDFCS_PATTERN) {
         PatternValue* pvalue = (PatternValue*)m_pBuffer;
-        CPDF_Pattern* pPattern = pvalue->m_pPattern;
+        CPDF_Pattern* pPattern = pvalue->m_pCountedPattern ? pvalue->m_pCountedPattern->m_Obj : NULL;
         if (pPattern && pPattern->m_pDocument) {
             CPDF_DocPageData *pPageData = pPattern->m_pDocument->GetPageData();
-            if (pPageData && !pPageData->IsForceClear()) {
+            if (pPageData) {
                 pPageData->ReleasePattern(pPattern->m_pPatternObj);
             }
         }
@@ -1348,10 +1362,11 @@ void CPDF_Color::SetValue(CPDF_Pattern* pPattern, FX_FLOAT* comps, int ncomps)
         m_pCS = CPDF_ColorSpace::GetStockCS(PDFCS_PATTERN);
         m_pBuffer = m_pCS->CreateBuf();
     }
+    CPDF_DocPageData *pDocPageData = NULL;
     PatternValue* pvalue = (PatternValue*)m_pBuffer;
     if (pvalue->m_pPattern && pvalue->m_pPattern->m_pDocument) {
-        CPDF_DocPageData *pDocPageData = pvalue->m_pPattern->m_pDocument->GetPageData();
-        if (pDocPageData && !pDocPageData->IsForceClear()) {
+        pDocPageData = pvalue->m_pPattern->m_pDocument->GetPageData();
+        if (pDocPageData) {
             pDocPageData->ReleasePattern(pvalue->m_pPattern->m_pPatternObj);
         }
     }
@@ -1360,6 +1375,14 @@ void CPDF_Color::SetValue(CPDF_Pattern* pPattern, FX_FLOAT* comps, int ncomps)
     if (ncomps) {
         FXSYS_memcpy32(pvalue->m_Comps, comps, ncomps * sizeof(FX_FLOAT));
     }
+    pvalue->m_pCountedPattern = NULL;\r
+    if (pPattern && pPattern->m_pDocument)\r
+    {\r
+        if (!pDocPageData) {\r
+            pDocPageData = pPattern->m_pDocument->GetPageData();\r
+        }\r
+        pvalue->m_pCountedPattern = pDocPageData->FindPatternPtr(pPattern->m_pPatternObj);\r
+    }
 }
 void CPDF_Color::Copy(const CPDF_Color* pSrc)
 {
index 8e578f6..fe5665d 100644 (file)
@@ -147,15 +147,52 @@ CPDF_DocPageData::~CPDF_DocPageData()
 {
     Clear(FALSE);
     Clear(TRUE);
+    FX_POSITION pos = m_PatternMap.GetStartPosition();\r
+    while (pos)\r
+    {\r
+        CPDF_Object* ptObj;\r
+        CPDF_CountedObject<CPDF_Pattern*>* ptData;\r
+        m_PatternMap.GetNextAssoc(pos, ptObj, ptData);\r
+        delete ptData;\r
+    }\r
+    m_PatternMap.RemoveAll();\r
+    pos = m_FontMap.GetStartPosition();\r
+    while (pos)\r
+    {\r
+        CPDF_Dictionary* fontDict;\r
+        CPDF_CountedObject<CPDF_Font*>* fontData;\r
+        m_FontMap.GetNextAssoc(pos, fontDict, fontData);\r
+        delete fontData;\r
+    }\r
+    m_FontMap.RemoveAll();\r
+    pos = m_ColorSpaceMap.GetStartPosition();\r
+    while (pos)\r
+    {\r
+        CPDF_Object* csKey;\r
+        CPDF_CountedObject<CPDF_ColorSpace*>* csData;\r
+        m_ColorSpaceMap.GetNextAssoc(pos, csKey, csData);\r
+        delete csData;\r
+    }\r
+    m_ColorSpaceMap.RemoveAll();
 }
 void CPDF_DocPageData::Clear(FX_BOOL bForceRelease)
 {
     FX_POSITION pos;
-
     m_bForceClear = bForceRelease;
-
-    // Release objects saved in the resource maps like font map and color space map.
-    // The compound objects shall be released before simple ones.
+    pos = m_PatternMap.GetStartPosition();
+    while (pos) {
+        CPDF_Object* ptObj;
+        CPDF_CountedObject<CPDF_Pattern*>* ptData;
+        m_PatternMap.GetNextAssoc(pos, ptObj, ptData);
+        if (!ptData->m_Obj) {
+            continue;
+        }
+        if (bForceRelease || ptData->m_nCount < 2) {
+            ptData->m_Obj->SetForceClear(bForceRelease);
+            delete ptData->m_Obj;
+            ptData->m_Obj = NULL;
+        }
+    }
     pos = m_FontMap.GetStartPosition();
     while (pos) {
         CPDF_Dictionary* fontDict;
@@ -203,7 +240,6 @@ void CPDF_DocPageData::Clear(FX_BOOL bForceRelease)
                 }
             }
             delete ipData->m_Obj;
-            ipData->m_Obj = NULL;
             delete ipData;
             m_IccProfileMap.RemoveKey(ipKey);
         }
@@ -218,25 +254,10 @@ void CPDF_DocPageData::Clear(FX_BOOL bForceRelease)
         }
         if (bForceRelease || ftData->m_nCount < 2) {
             delete ftData->m_Obj;
-            ftData->m_Obj = NULL;
             delete ftData;
             m_FontFileMap.RemoveKey(ftKey);
         }
     }
-    pos = m_PatternMap.GetStartPosition();
-    while (pos) {
-        CPDF_Object* ptObj;
-        CPDF_CountedObject<CPDF_Pattern*>* ptData;
-        m_PatternMap.GetNextAssoc(pos, ptObj, ptData);
-        if (!ptData->m_Obj) {
-            continue;
-        }
-        if (bForceRelease || ptData->m_nCount < 2) {
-            ptData->m_Obj->SetForceClear(bForceRelease);
-            delete ptData->m_Obj;
-            ptData->m_Obj = NULL;
-        }
-    }
     pos = m_ImageMap.GetStartPosition();
     while (pos) {
         FX_DWORD objNum;
@@ -247,7 +268,6 @@ void CPDF_DocPageData::Clear(FX_BOOL bForceRelease)
         }
         if (bForceRelease || imageData->m_nCount < 2) {
             delete imageData->m_Obj;
-            imageData->m_Obj = NULL;
             delete imageData;
             m_ImageMap.RemoveKey(objNum);
         }
@@ -653,4 +673,24 @@ void CPDF_DocPageData::ReleaseFontFileStreamAcc(CPDF_Stream* pFontStream, FX_BOO
         return;
     }
     PDF_DocPageData_Release<CPDF_Stream*, CPDF_StreamAcc*>(m_FontFileMap, pFontStream, NULL, bForce);
+}\r
+CPDF_CountedColorSpace* CPDF_DocPageData::FindColorSpacePtr(CPDF_Object* pCSObj) const\r
+{\r
+    if (!pCSObj) return NULL;\r
+    CPDF_CountedObject<CPDF_ColorSpace*>* csData;\r
+    if (m_ColorSpaceMap.Lookup(pCSObj, csData))\r
+    {\r
+        return csData;\r
+    }\r
+    return NULL;\r
 }
+CPDF_CountedPattern* CPDF_DocPageData::FindPatternPtr(CPDF_Object* pPatternObj) const\r
+{\r
+    if (!pPatternObj) return NULL;\r
+    CPDF_CountedObject<CPDF_Pattern*>* ptData;\r
+    if (m_PatternMap.Lookup(pPatternObj, ptData))\r
+    {\r
+        return ptData;\r
+    }\r
+    return NULL;\r
+}\r
index 67ea4fe..467ef9b 100644 (file)
@@ -83,6 +83,7 @@ CPDF_ShadingPattern::CPDF_ShadingPattern(CPDF_Document* pDoc, CPDF_Object* pPatt
     for (int i = 0; i < 4; i ++) {
         m_pFunctions[i] = NULL;
     }
+    m_pCountedCS = NULL;
 }
 CPDF_ShadingPattern::~CPDF_ShadingPattern()
 {
@@ -96,12 +97,13 @@ void CPDF_ShadingPattern::Clear()
         }
         m_pFunctions[i] = NULL;
     }
-    CPDF_ColorSpace* pCS = m_pCS;
-    if (!m_bForceClear && pCS && m_pDocument) {
+    CPDF_ColorSpace* pCS = m_pCountedCS ? m_pCountedCS->m_Obj : NULL;
+    if (pCS && m_pDocument) {
         m_pDocument->GetPageData()->ReleaseColorSpace(pCS->GetArray());
     }
     m_ShadingType = 0;
     m_pCS = NULL;
+    m_pCountedCS = NULL;
     m_nFuncs = 0;
 }
 FX_BOOL CPDF_ShadingPattern::Load()
@@ -141,6 +143,9 @@ FX_BOOL CPDF_ShadingPattern::Load()
     }
     CPDF_DocPageData* pDocPageData = m_pDocument->GetPageData();
     m_pCS = pDocPageData->GetColorSpace(pCSObj, NULL);
+    if (m_pCS) {\r
+        m_pCountedCS = pDocPageData->FindColorSpacePtr(m_pCS->GetArray());
+    }
     m_ShadingType = pShadingDict->GetInteger(FX_BSTRC("ShadingType"));
     return TRUE;
 }
index f79b8d3..cc35dbe 100644 (file)
@@ -364,18 +364,7 @@ public:
     FX_FLOAT                           m_TextX, m_TextY, m_TextLineX, m_TextLineY;
     FX_FLOAT                           m_TextLeading, m_TextRise, m_TextHorzScale;
 };
-template <class ObjClass> class CPDF_CountedObject : public CFX_Object
-{
-public:
-    ObjClass   m_Obj;
-    FX_DWORD   m_nCount;
-};
-typedef CFX_MapPtrTemplate<CPDF_Dictionary*, CPDF_CountedObject<CPDF_Font*>*>          CPDF_FontMap;
-typedef CFX_MapPtrTemplate<CPDF_Object*, CPDF_CountedObject<CPDF_ColorSpace*>*>                CPDF_ColorSpaceMap;
-typedef CFX_MapPtrTemplate<CPDF_Object*, CPDF_CountedObject<CPDF_Pattern*>*>           CPDF_PatternMap;
-typedef CFX_MapPtrTemplate<FX_DWORD, CPDF_CountedObject<CPDF_Image*>*>                         CPDF_ImageMap;
-typedef CFX_MapPtrTemplate<CPDF_Stream*, CPDF_CountedObject<CPDF_IccProfile*>*>                CPDF_IccProfileMap;
-typedef CFX_MapPtrTemplate<CPDF_Stream*, CPDF_CountedObject<CPDF_StreamAcc*>*>         CPDF_FontFileMap;
+
 template <class KeyType, class ValueType>
 KeyType PDF_DocPageData_FindValue(const CFX_MapPtrTemplate<KeyType, CPDF_CountedObject<ValueType>*> &map, ValueType findValue, CPDF_CountedObject<ValueType>*& findData)
 {
@@ -430,7 +419,9 @@ public:
     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;}
+    FX_BOOL                     IsForceClear() const {return m_bForceClear;}\r
+    CPDF_CountedColorSpace*     FindColorSpacePtr(CPDF_Object* pCSObj) const;\r
+    CPDF_CountedPattern*        FindPatternPtr(CPDF_Object* pPatternObj) const;
 
     CPDF_Document*              m_pPDFDoc;
     CPDF_FontMap                m_FontMap;
@@ -497,6 +488,7 @@ public:
         return m_pBaseCS;
     }
     CPDF_ColorSpace*   m_pBaseCS;
+    CPDF_CountedColorSpace*    m_pCountedBaseCS;
 };
 #define        MAX_PAGE_OBJECTS_UNIFY_NAMING                           4096
 class CPDF_ResourceNaming : public CFX_Object