diff options
author | Bo Xu <bo_xu@foxitsoftware.com> | 2014-10-14 17:10:06 -0700 |
---|---|---|
committer | Bo Xu <bo_xu@foxitsoftware.com> | 2014-10-31 10:12:21 -0700 |
commit | 7c3220c9c442d008a78009a6c6214f02e165c987 (patch) | |
tree | 4b900317c158584e90de7ecfe04132791c350f56 | |
parent | 0bd0f5e2a5a79d4f81c7bab20a0f8552da4a6b00 (diff) | |
download | pdfium-7c3220c9c442d008a78009a6c6214f02e165c987.tar.xz |
Store the address of the page data map's value for proper referencing.
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
-rw-r--r-- | core/include/fpdfapi/fpdf_resource.h | 25 | ||||
-rw-r--r-- | core/src/fpdfapi/fpdf_page/fpdf_page_colors.cpp | 31 | ||||
-rw-r--r-- | core/src/fpdfapi/fpdf_page/fpdf_page_doc.cpp | 82 | ||||
-rw-r--r-- | core/src/fpdfapi/fpdf_page/fpdf_page_pattern.cpp | 9 | ||||
-rw-r--r-- | core/src/fpdfapi/fpdf_page/pageint.h | 18 |
5 files changed, 124 insertions, 41 deletions
diff --git a/core/include/fpdfapi/fpdf_resource.h b/core/include/fpdfapi/fpdf_resource.h index 937024c94e..a4d9f1448f 100644 --- a/core/include/fpdfapi/fpdf_resource.h +++ b/core/include/fpdfapi/fpdf_resource.h @@ -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 @@ -788,8 +810,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]; diff --git a/core/src/fpdfapi/fpdf_page/fpdf_page_colors.cpp b/core/src/fpdfapi/fpdf_page/fpdf_page_colors.cpp index c522dcdc84..5266c1a052 100644 --- a/core/src/fpdfapi/fpdf_page/fpdf_page_colors.cpp +++ b/core/src/fpdfapi/fpdf_page/fpdf_page_colors.cpp @@ -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;
+ if (pPattern && pPattern->m_pDocument)
+ {
+ if (!pDocPageData) {
+ pDocPageData = pPattern->m_pDocument->GetPageData();
+ }
+ pvalue->m_pCountedPattern = pDocPageData->FindPatternPtr(pPattern->m_pPatternObj);
+ } } void CPDF_Color::Copy(const CPDF_Color* pSrc) { diff --git a/core/src/fpdfapi/fpdf_page/fpdf_page_doc.cpp b/core/src/fpdfapi/fpdf_page/fpdf_page_doc.cpp index 8e578f6f8f..fe5665d1fb 100644 --- a/core/src/fpdfapi/fpdf_page/fpdf_page_doc.cpp +++ b/core/src/fpdfapi/fpdf_page/fpdf_page_doc.cpp @@ -147,15 +147,52 @@ CPDF_DocPageData::~CPDF_DocPageData() { Clear(FALSE); Clear(TRUE); + FX_POSITION pos = m_PatternMap.GetStartPosition();
+ while (pos)
+ {
+ CPDF_Object* ptObj;
+ CPDF_CountedObject<CPDF_Pattern*>* ptData;
+ m_PatternMap.GetNextAssoc(pos, ptObj, ptData);
+ delete ptData;
+ }
+ m_PatternMap.RemoveAll();
+ pos = m_FontMap.GetStartPosition();
+ while (pos)
+ {
+ CPDF_Dictionary* fontDict;
+ CPDF_CountedObject<CPDF_Font*>* fontData;
+ m_FontMap.GetNextAssoc(pos, fontDict, fontData);
+ delete fontData;
+ }
+ m_FontMap.RemoveAll();
+ pos = m_ColorSpaceMap.GetStartPosition();
+ while (pos)
+ {
+ CPDF_Object* csKey;
+ CPDF_CountedObject<CPDF_ColorSpace*>* csData;
+ m_ColorSpaceMap.GetNextAssoc(pos, csKey, csData);
+ delete csData;
+ }
+ 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); +}
+CPDF_CountedColorSpace* CPDF_DocPageData::FindColorSpacePtr(CPDF_Object* pCSObj) const
+{
+ if (!pCSObj) return NULL;
+ CPDF_CountedObject<CPDF_ColorSpace*>* csData;
+ if (m_ColorSpaceMap.Lookup(pCSObj, csData))
+ {
+ return csData;
+ }
+ return NULL;
} +CPDF_CountedPattern* CPDF_DocPageData::FindPatternPtr(CPDF_Object* pPatternObj) const
+{
+ if (!pPatternObj) return NULL;
+ CPDF_CountedObject<CPDF_Pattern*>* ptData;
+ if (m_PatternMap.Lookup(pPatternObj, ptData))
+ {
+ return ptData;
+ }
+ return NULL;
+}
diff --git a/core/src/fpdfapi/fpdf_page/fpdf_page_pattern.cpp b/core/src/fpdfapi/fpdf_page/fpdf_page_pattern.cpp index 67ea4fee65..467ef9b3f6 100644 --- a/core/src/fpdfapi/fpdf_page/fpdf_page_pattern.cpp +++ b/core/src/fpdfapi/fpdf_page/fpdf_page_pattern.cpp @@ -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) {
+ m_pCountedCS = pDocPageData->FindColorSpacePtr(m_pCS->GetArray()); + } m_ShadingType = pShadingDict->GetInteger(FX_BSTRC("ShadingType")); return TRUE; } diff --git a/core/src/fpdfapi/fpdf_page/pageint.h b/core/src/fpdfapi/fpdf_page/pageint.h index f79b8d38f3..cc35dbe744 100644 --- a/core/src/fpdfapi/fpdf_page/pageint.h +++ b/core/src/fpdfapi/fpdf_page/pageint.h @@ -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;}
+ CPDF_CountedColorSpace* FindColorSpacePtr(CPDF_Object* pCSObj) const;
+ 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 |