summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBo Xu <bo_xu@foxitsoftware.com>2014-10-14 17:10:06 -0700
committerBo Xu <bo_xu@foxitsoftware.com>2014-10-14 17:10:06 -0700
commite1177425a656f915657f948d965193a019702a52 (patch)
treeb3213672a9af719ffe6b9b519a828d587886f289
parent35d720aff01c5ea778c16ac1e31c56f68490f10b (diff)
downloadpdfium-e1177425a656f915657f948d965193a019702a52.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.h25
-rw-r--r--core/src/fpdfapi/fpdf_page/fpdf_page_colors.cpp31
-rw-r--r--core/src/fpdfapi/fpdf_page/fpdf_page_doc.cpp82
-rw-r--r--core/src/fpdfapi/fpdf_page/fpdf_page_pattern.cpp9
-rw-r--r--core/src/fpdfapi/fpdf_page/pageint.h18
5 files changed, 124 insertions, 41 deletions
diff --git a/core/include/fpdfapi/fpdf_resource.h b/core/include/fpdfapi/fpdf_resource.h
index 7bad01501a..54e1c97ee7 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
@@ -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];
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