From 7c3220c9c442d008a78009a6c6214f02e165c987 Mon Sep 17 00:00:00 2001 From: Bo Xu Date: Tue, 14 Oct 2014 17:10:06 -0700 Subject: 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 --- core/include/fpdfapi/fpdf_resource.h | 25 +++++++- core/src/fpdfapi/fpdf_page/fpdf_page_colors.cpp | 31 +++++++-- core/src/fpdfapi/fpdf_page/fpdf_page_doc.cpp | 82 ++++++++++++++++++------ core/src/fpdfapi/fpdf_page/fpdf_page_pattern.cpp | 9 ++- 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 CPDF_CountedObject : public CFX_Object +{ +public: + ObjClass m_Obj; + FX_DWORD m_nCount; +}; +typedef CPDF_CountedObject CPDF_CountedFont; +typedef CPDF_CountedObject CPDF_CountedColorSpace; +typedef CPDF_CountedObject CPDF_CountedPattern; +typedef CPDF_CountedObject CPDF_CountedImage; +typedef CPDF_CountedObject CPDF_CountedICCProfile; +typedef CPDF_CountedObject CPDF_CountedStreamAcc; + + +typedef CFX_MapPtrTemplate CPDF_FontMap; +typedef CFX_MapPtrTemplate CPDF_ColorSpaceMap; +typedef CFX_MapPtrTemplate CPDF_PatternMap; +typedef CFX_MapPtrTemplate CPDF_ImageMap; +typedef CFX_MapPtrTemplate CPDF_IccProfileMap; +typedef CFX_MapPtrTemplate 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* ptData; + m_PatternMap.GetNextAssoc(pos, ptObj, ptData); + delete ptData; + } + m_PatternMap.RemoveAll(); + pos = m_FontMap.GetStartPosition(); + while (pos) + { + CPDF_Dictionary* fontDict; + CPDF_CountedObject* fontData; + m_FontMap.GetNextAssoc(pos, fontDict, fontData); + delete fontData; + } + m_FontMap.RemoveAll(); + pos = m_ColorSpaceMap.GetStartPosition(); + while (pos) + { + CPDF_Object* csKey; + CPDF_CountedObject* 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* 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* 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(m_FontFileMap, pFontStream, NULL, bForce); +} +CPDF_CountedColorSpace* CPDF_DocPageData::FindColorSpacePtr(CPDF_Object* pCSObj) const +{ + if (!pCSObj) return NULL; + CPDF_CountedObject* 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* 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 CPDF_CountedObject : public CFX_Object -{ -public: - ObjClass m_Obj; - FX_DWORD m_nCount; -}; -typedef CFX_MapPtrTemplate*> CPDF_FontMap; -typedef CFX_MapPtrTemplate*> CPDF_ColorSpaceMap; -typedef CFX_MapPtrTemplate*> CPDF_PatternMap; -typedef CFX_MapPtrTemplate*> CPDF_ImageMap; -typedef CFX_MapPtrTemplate*> CPDF_IccProfileMap; -typedef CFX_MapPtrTemplate*> CPDF_FontFileMap; + template KeyType PDF_DocPageData_FindValue(const CFX_MapPtrTemplate*> &map, ValueType findValue, CPDF_CountedObject*& 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 -- cgit v1.2.3