From 260f5fbf3553a96fa49b029cc050220039c30e2a Mon Sep 17 00:00:00 2001 From: dsinclair Date: Wed, 17 Aug 2016 12:45:26 -0700 Subject: Move parser pointer to CPDF_Document The CPDF_IndirectObjectHolder has two subclasses, CPDF_Document and CFDF_Document. The CPDF document requires the parser and the CFDF document does not. This cl moves the parser pointer up to CPDF_Document. Review-Url: https://codereview.chromium.org/2253723002 --- core/fpdfapi/fpdf_edit/fpdf_edit_create.cpp | 15 ++--- core/fpdfapi/fpdf_parser/cfdf_document.cpp | 21 +++--- core/fpdfapi/fpdf_parser/cpdf_array_unittest.cpp | 4 +- core/fpdfapi/fpdf_parser/cpdf_data_avail.cpp | 6 +- core/fpdfapi/fpdf_parser/cpdf_document.cpp | 27 +++++--- .../fpdf_parser/cpdf_indirect_object_holder.cpp | 74 ++++++++++++---------- core/fpdfapi/fpdf_parser/cpdf_object_unittest.cpp | 9 +-- core/fpdfapi/fpdf_parser/cpdf_parser.cpp | 11 +++- core/fpdfapi/fpdf_parser/cpdf_reference.cpp | 3 +- core/fpdfapi/fpdf_parser/include/cfdf_document.h | 2 +- core/fpdfapi/fpdf_parser/include/cpdf_document.h | 4 +- .../include/cpdf_indirect_object_holder.h | 22 +++++-- core/fpdfapi/fpdf_parser/include/cpdf_object.h | 7 +- 13 files changed, 118 insertions(+), 87 deletions(-) diff --git a/core/fpdfapi/fpdf_edit/fpdf_edit_create.cpp b/core/fpdfapi/fpdf_edit/fpdf_edit_create.cpp index c20a483764..eb3f156b2d 100644 --- a/core/fpdfapi/fpdf_edit/fpdf_edit_create.cpp +++ b/core/fpdfapi/fpdf_edit/fpdf_edit_create.cpp @@ -1233,13 +1233,12 @@ int32_t CPDF_Creator::WriteOldIndirectObject(uint32_t objnum) { return 0; m_ObjectOffset[objnum] = m_Offset; - FX_BOOL bExistInMap = - pdfium::ContainsKey(m_pDocument->m_IndirectObjs, objnum); + FX_BOOL bExistInMap = !!m_pDocument->GetIndirectObject(objnum); const uint8_t object_type = m_pParser->GetObjectType(objnum); bool bObjStm = (object_type == 2) && m_pEncryptDict && !m_pXRefStream; if (m_pParser->IsVersionUpdated() || m_bSecurityChanged || bExistInMap || bObjStm) { - CPDF_Object* pObj = m_pDocument->GetIndirectObject(objnum); + CPDF_Object* pObj = m_pDocument->GetOrParseIndirectObject(objnum); if (!pObj) { m_ObjectOffset[objnum] = 0; return 0; @@ -1320,13 +1319,13 @@ int32_t CPDF_Creator::WriteNewObjs(FX_BOOL bIncremental, IFX_Pause* pPause) { int32_t index = (int32_t)(uintptr_t)m_Pos; while (index < iCount) { uint32_t objnum = m_NewObjNumArray.ElementAt(index); - auto it = m_pDocument->m_IndirectObjs.find(objnum); - if (it == m_pDocument->m_IndirectObjs.end()) { + CPDF_Object* pObj = m_pDocument->GetIndirectObject(objnum); + if (!pObj) { ++index; continue; } m_ObjectOffset[objnum] = m_Offset; - if (WriteIndirectObj(it->second)) { + if (WriteIndirectObj(pObj)) { return -1; } index++; @@ -1363,7 +1362,7 @@ void CPDF_Creator::InitOldObjNumOffsets() { void CPDF_Creator::InitNewObjNumOffsets() { FX_BOOL bIncremental = (m_dwFlags & FPDFCREATE_INCREMENTAL) != 0; FX_BOOL bNoOriginal = (m_dwFlags & FPDFCREATE_NO_ORIGINAL) != 0; - for (const auto& pair : m_pDocument->m_IndirectObjs) { + for (const auto& pair : *m_pDocument) { const uint32_t objnum = pair.first; const CPDF_Object* pObj = pair.second; if (bIncremental || pObj->GetObjNum() == CPDF_Object::kInvalidObjNum) @@ -1703,7 +1702,7 @@ int32_t CPDF_Creator::WriteDoc_Stage4(IFX_Pause* pPause) { return -1; } } else { - if (m_File.AppendDWord(m_pDocument->m_LastObjNum + 1) < 0) { + if (m_File.AppendDWord(m_pDocument->GetLastObjNum() + 1) < 0) { return -1; } if (m_File.AppendString(" 0 obj <<") < 0) { diff --git a/core/fpdfapi/fpdf_parser/cfdf_document.cpp b/core/fpdfapi/fpdf_parser/cfdf_document.cpp index c039871401..f286346d70 100644 --- a/core/fpdfapi/fpdf_parser/cfdf_document.cpp +++ b/core/fpdfapi/fpdf_parser/cfdf_document.cpp @@ -10,16 +10,17 @@ #include "core/fpdfapi/fpdf_parser/cpdf_syntax_parser.h" #include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h" -CFDF_Document::CFDF_Document() : CPDF_IndirectObjectHolder(nullptr) { - m_pRootDict = nullptr; - m_pFile = nullptr; - m_bOwnFile = FALSE; -} +CFDF_Document::CFDF_Document() + : CPDF_IndirectObjectHolder(), + m_pRootDict(nullptr), + m_pFile(nullptr), + m_bOwnFile(FALSE) {} + CFDF_Document::~CFDF_Document() { - if (m_bOwnFile && m_pFile) { + if (m_bOwnFile && m_pFile) m_pFile->Release(); - } } + CFDF_Document* CFDF_Document::CreateNewDoc() { CFDF_Document* pDoc = new CFDF_Document; pDoc->m_pRootDict = new CPDF_Dictionary; @@ -65,7 +66,7 @@ void CFDF_Document::ParseStream(IFX_FileRead* pFile, FX_BOOL bOwnFile) { if (!pObj) break; - InsertIndirectObject(objnum, pObj); + ReplaceIndirectObjectIfHigherGeneration(objnum, pObj); word = parser.GetNextWord(nullptr); if (word != "endobj") break; @@ -88,9 +89,9 @@ FX_BOOL CFDF_Document::WriteBuf(CFX_ByteTextBuf& buf) const { return FALSE; } buf << "%FDF-1.2\r\n"; - for (const auto& pair : m_IndirectObjs) { + for (const auto& pair : *this) buf << pair.first << " 0 obj\r\n" << pair.second << "\r\nendobj\r\n\r\n"; - } + buf << "trailer\r\n<GetObjNum() << " 0 R>>\r\n%%EOF\r\n"; return TRUE; diff --git a/core/fpdfapi/fpdf_parser/cpdf_array_unittest.cpp b/core/fpdfapi/fpdf_parser/cpdf_array_unittest.cpp index 12a36d921a..58a47a4ab7 100644 --- a/core/fpdfapi/fpdf_parser/cpdf_array_unittest.cpp +++ b/core/fpdfapi/fpdf_parser/cpdf_array_unittest.cpp @@ -109,14 +109,14 @@ TEST(cpdf_array, Clone) { ScopedArray arr(new CPDF_Array); // Indirect references to indirect objects. std::unique_ptr obj_holder( - new CPDF_IndirectObjectHolder(nullptr)); + new CPDF_IndirectObjectHolder()); for (size_t i = 0; i < kNumOfRows; ++i) { CPDF_Array* arr_elem = new CPDF_Array; for (size_t j = 0; j < kNumOfRowElems; ++j) { CPDF_Number* obj = new CPDF_Number(elems[i][j]); // Starts object number from 1. int obj_num = i * kNumOfRowElems + j + 1; - obj_holder->InsertIndirectObject(obj_num, obj); + obj_holder->ReplaceIndirectObjectIfHigherGeneration(obj_num, obj); arr_elem->InsertAt(j, new CPDF_Reference(obj_holder.get(), obj_num), obj_holder.get()); } diff --git a/core/fpdfapi/fpdf_parser/cpdf_data_avail.cpp b/core/fpdfapi/fpdf_parser/cpdf_data_avail.cpp index 94795fd60e..58b69257ad 100644 --- a/core/fpdfapi/fpdf_parser/cpdf_data_avail.cpp +++ b/core/fpdfapi/fpdf_parser/cpdf_data_avail.cpp @@ -176,7 +176,7 @@ FX_BOOL CPDF_DataAvail::IsObjectsAvail( } else if (!pdfium::ContainsKey(m_ObjectSet, dwNum)) { m_ObjectSet.insert(dwNum); CPDF_Object* pReferred = - m_pDocument->GetIndirectObject(pRef->GetRefObjNum()); + m_pDocument->GetOrParseIndirectObject(pRef->GetRefObjNum()); if (pReferred) new_obj_array.Add(pReferred); } @@ -1788,8 +1788,10 @@ CPDF_Dictionary* CPDF_DataAvail::GetPage(int index) { if (!pPageDict) return nullptr; - if (!m_pDocument->InsertIndirectObject(dwObjNum, pPageDict)) + if (!m_pDocument->ReplaceIndirectObjectIfHigherGeneration(dwObjNum, + pPageDict)) { return nullptr; + } return pPageDict->GetDict(); } } diff --git a/core/fpdfapi/fpdf_parser/cpdf_document.cpp b/core/fpdfapi/fpdf_parser/cpdf_document.cpp index bf1f93f887..1f04373e3b 100644 --- a/core/fpdfapi/fpdf_parser/cpdf_document.cpp +++ b/core/fpdfapi/fpdf_parser/cpdf_document.cpp @@ -482,24 +482,32 @@ int CountPages(CPDF_Dictionary* pPages, } // namespace CPDF_Document::CPDF_Document(CPDF_Parser* pParser) - : CPDF_IndirectObjectHolder(pParser), + : CPDF_IndirectObjectHolder(), + m_pParser(pParser), m_pRootDict(nullptr), m_pInfoDict(nullptr), m_bLinearized(false), m_iFirstPageNo(0), m_dwFirstPageObjNum(0), m_pDocPage(new CPDF_DocPageData(this)), - m_pDocRender(new CPDF_DocRenderData(this)) {} + m_pDocRender(new CPDF_DocRenderData(this)) { + if (pParser) + SetLastObjNum(m_pParser->GetLastObjNum()); +} CPDF_Document::~CPDF_Document() { delete m_pDocPage; CPDF_ModuleMgr::Get()->GetPageModule()->ClearStockFont(this); } +CPDF_Object* CPDF_Document::ParseIndirectObject(uint32_t objnum) { + return m_pParser ? m_pParser->ParseIndirectObject(this, objnum) : nullptr; +} + void CPDF_Document::LoadDocInternal() { - m_LastObjNum = m_pParser->GetLastObjNum(); + SetLastObjNum(m_pParser->GetLastObjNum()); - CPDF_Object* pRootObj = GetIndirectObject(m_pParser->GetRootObjNum()); + CPDF_Object* pRootObj = GetOrParseIndirectObject(m_pParser->GetRootObjNum()); if (!pRootObj) return; @@ -507,7 +515,7 @@ void CPDF_Document::LoadDocInternal() { if (!m_pRootDict) return; - CPDF_Object* pInfoObj = GetIndirectObject(m_pParser->GetInfoObjNum()); + CPDF_Object* pInfoObj = GetOrParseIndirectObject(m_pParser->GetInfoObjNum()); if (pInfoObj) m_pInfoDict = pInfoObj->GetDict(); if (CPDF_Array* pIDArray = m_pParser->GetIDArray()) { @@ -587,14 +595,14 @@ CPDF_Dictionary* CPDF_Document::GetPage(int iPage) { if (m_bLinearized && (iPage == m_iFirstPageNo)) { if (CPDF_Dictionary* pDict = - ToDictionary(GetIndirectObject(m_dwFirstPageObjNum))) { + ToDictionary(GetOrParseIndirectObject(m_dwFirstPageObjNum))) { return pDict; } } int objnum = m_PageList.GetAt(iPage); if (objnum) { - if (CPDF_Dictionary* pDict = ToDictionary(GetIndirectObject(objnum))) + if (CPDF_Dictionary* pDict = ToDictionary(GetOrParseIndirectObject(objnum))) return pDict; } @@ -727,9 +735,8 @@ uint32_t CPDF_Document::GetUserPermissions() const { } FX_BOOL CPDF_Document::IsFormStream(uint32_t objnum, FX_BOOL& bForm) const { - auto it = m_IndirectObjs.find(objnum); - if (it != m_IndirectObjs.end()) { - CPDF_Stream* pStream = it->second->AsStream(); + if (CPDF_Object* pObj = GetIndirectObject(objnum)) { + CPDF_Stream* pStream = pObj->AsStream(); bForm = pStream && pStream->GetDict()->GetStringBy("Subtype") == "Form"; return TRUE; } diff --git a/core/fpdfapi/fpdf_parser/cpdf_indirect_object_holder.cpp b/core/fpdfapi/fpdf_parser/cpdf_indirect_object_holder.cpp index 33f45a53bf..0d3e68e86f 100644 --- a/core/fpdfapi/fpdf_parser/cpdf_indirect_object_holder.cpp +++ b/core/fpdfapi/fpdf_parser/cpdf_indirect_object_holder.cpp @@ -9,39 +9,38 @@ #include "core/fpdfapi/fpdf_parser/include/cpdf_object.h" #include "core/fpdfapi/fpdf_parser/include/cpdf_parser.h" -CPDF_IndirectObjectHolder::CPDF_IndirectObjectHolder(CPDF_Parser* pParser) - : m_pParser(pParser), m_LastObjNum(0) { - if (pParser) - m_LastObjNum = m_pParser->GetLastObjNum(); -} +CPDF_IndirectObjectHolder::CPDF_IndirectObjectHolder() : m_LastObjNum(0) {} CPDF_IndirectObjectHolder::~CPDF_IndirectObjectHolder() { for (const auto& pair : m_IndirectObjs) pair.second->Destroy(); } -CPDF_Object* CPDF_IndirectObjectHolder::GetIndirectObject(uint32_t objnum) { +CPDF_Object* CPDF_IndirectObjectHolder::GetIndirectObject( + uint32_t objnum) const { if (objnum == 0) return nullptr; auto it = m_IndirectObjs.find(objnum); - if (it != m_IndirectObjs.end()) - return it->second->GetObjNum() != CPDF_Object::kInvalidObjNum ? it->second - : nullptr; + return it != m_IndirectObjs.end() ? it->second : nullptr; +} - if (!m_pParser) - return nullptr; +CPDF_Object* CPDF_IndirectObjectHolder::ParseIndirectObject(uint32_t objnum) { + return nullptr; +} - CPDF_Object* pObj = m_pParser->ParseIndirectObject(this, objnum); +CPDF_Object* CPDF_IndirectObjectHolder::GetOrParseIndirectObject( + uint32_t objnum) { + CPDF_Object* pObj = GetIndirectObject(objnum); + if (pObj) + return pObj->GetObjNum() != CPDF_Object::kInvalidObjNum ? pObj : nullptr; + + pObj = ParseIndirectObject(objnum); if (!pObj) return nullptr; pObj->m_ObjNum = objnum; - m_LastObjNum = std::max(m_LastObjNum, objnum); - if (m_IndirectObjs[objnum]) - m_IndirectObjs[objnum]->Destroy(); - - m_IndirectObjs[objnum] = pObj; + ReplaceIndirectObject(pObj); return pObj; } @@ -50,36 +49,41 @@ uint32_t CPDF_IndirectObjectHolder::AddIndirectObject(CPDF_Object* pObj) { return pObj->m_ObjNum; m_LastObjNum++; - m_IndirectObjs[m_LastObjNum] = pObj; pObj->m_ObjNum = m_LastObjNum; + ReplaceIndirectObject(pObj); return m_LastObjNum; } void CPDF_IndirectObjectHolder::ReleaseIndirectObject(uint32_t objnum) { - auto it = m_IndirectObjs.find(objnum); - if (it == m_IndirectObjs.end() || - it->second->GetObjNum() == CPDF_Object::kInvalidObjNum) { + CPDF_Object* pObj = GetIndirectObject(objnum); + if (!pObj || pObj->m_ObjNum == CPDF_Object::kInvalidObjNum) return; - } - it->second->Destroy(); - m_IndirectObjs.erase(it); + + pObj->Destroy(); + m_IndirectObjs.erase(objnum); } -bool CPDF_IndirectObjectHolder::InsertIndirectObject(uint32_t objnum, - CPDF_Object* pObj) { +bool CPDF_IndirectObjectHolder::ReplaceIndirectObjectIfHigherGeneration( + uint32_t objnum, + CPDF_Object* pObj) { if (!objnum || !pObj) return false; - auto it = m_IndirectObjs.find(objnum); - if (it != m_IndirectObjs.end()) { - if (pObj->GetGenNum() <= it->second->GetGenNum()) { - pObj->Destroy(); - return false; - } - it->second->Destroy(); + CPDF_Object* pOldObj = GetIndirectObject(objnum); + if (pOldObj && pObj->GetGenNum() <= pOldObj->GetGenNum()) { + pObj->Destroy(); + return false; } + pObj->m_ObjNum = objnum; - m_IndirectObjs[objnum] = pObj; - m_LastObjNum = std::max(m_LastObjNum, objnum); + ReplaceIndirectObject(pObj); return true; } + +void CPDF_IndirectObjectHolder::ReplaceIndirectObject(CPDF_Object* pObj) { + m_LastObjNum = std::max(m_LastObjNum, pObj->m_ObjNum); + if (m_IndirectObjs[pObj->m_ObjNum]) + m_IndirectObjs[pObj->m_ObjNum]->Destroy(); + + m_IndirectObjs[pObj->m_ObjNum] = pObj; +} diff --git a/core/fpdfapi/fpdf_parser/cpdf_object_unittest.cpp b/core/fpdfapi/fpdf_parser/cpdf_object_unittest.cpp index a77f022c40..8fbaa482bf 100644 --- a/core/fpdfapi/fpdf_parser/cpdf_object_unittest.cpp +++ b/core/fpdfapi/fpdf_parser/cpdf_object_unittest.cpp @@ -92,7 +92,7 @@ class PDFObjectsTest : public testing::Test { m_DirectObjs.emplace_back(objs[i]); // Indirect references to indirect objects. - m_ObjHolder.reset(new CPDF_IndirectObjectHolder(nullptr)); + m_ObjHolder.reset(new CPDF_IndirectObjectHolder()); m_IndirectObjs = {boolean_true_obj, number_int_obj, str_spec_obj, name_obj, m_ArrayObj, m_DictObj, stream_obj}; for (size_t i = 0; i < m_IndirectObjs.size(); ++i) { @@ -710,7 +710,7 @@ TEST(PDFArrayTest, AddStringAndName) { TEST(PDFArrayTest, AddReferenceAndGetObjectAt) { std::unique_ptr holder( - new CPDF_IndirectObjectHolder(nullptr)); + new CPDF_IndirectObjectHolder()); CPDF_Boolean* boolean_obj = new CPDF_Boolean(true); CPDF_Number* int_obj = new CPDF_Number(-1234); CPDF_Number* float_obj = new CPDF_Number(2345.089f); @@ -725,13 +725,14 @@ TEST(PDFArrayTest, AddReferenceAndGetObjectAt) { // Create two arrays of references by different AddReference() APIs. for (size_t i = 0; i < FX_ArraySize(indirect_objs); ++i) { // All the indirect objects inserted will be owned by holder. - holder->InsertIndirectObject(obj_nums[i], indirect_objs[i]); + holder->ReplaceIndirectObjectIfHigherGeneration(obj_nums[i], + indirect_objs[i]); arr->AddReference(holder.get(), obj_nums[i]); arr1->AddReference(holder.get(), indirect_objs[i]); } // Check indirect objects. for (size_t i = 0; i < FX_ArraySize(obj_nums); ++i) - EXPECT_EQ(indirect_objs[i], holder->GetIndirectObject(obj_nums[i])); + EXPECT_EQ(indirect_objs[i], holder->GetOrParseIndirectObject(obj_nums[i])); // Check arrays. EXPECT_EQ(arr->GetCount(), arr1->GetCount()); for (size_t i = 0; i < arr->GetCount(); ++i) { diff --git a/core/fpdfapi/fpdf_parser/cpdf_parser.cpp b/core/fpdfapi/fpdf_parser/cpdf_parser.cpp index b2f1a4be3f..ffd3f79a62 100644 --- a/core/fpdfapi/fpdf_parser/cpdf_parser.cpp +++ b/core/fpdfapi/fpdf_parser/cpdf_parser.cpp @@ -267,7 +267,7 @@ CPDF_Parser::Error CPDF_Parser::SetEncryptHandler() { if (CPDF_Dictionary* pEncryptDict = pEncryptObj->AsDictionary()) { SetEncryptDictionary(pEncryptDict); } else if (CPDF_Reference* pRef = pEncryptObj->AsReference()) { - pEncryptObj = m_pDocument->GetIndirectObject(pRef->GetRefObjNum()); + pEncryptObj = m_pDocument->GetOrParseIndirectObject(pRef->GetRefObjNum()); if (pEncryptObj) SetEncryptDictionary(pEncryptObj->GetDict()); } @@ -982,12 +982,16 @@ FX_BOOL CPDF_Parser::LoadCrossRefV5(FX_FILESIZE* pos, FX_BOOL bMainXRef) { if (m_pDocument) { CPDF_Dictionary* pRootDict = m_pDocument->GetRoot(); if (pRootDict && pRootDict->GetObjNum() == pObject->m_ObjNum) { + // If |pObject| has an objnum assigned then this will leak as Release() + // will early exit. if (pObject->IsStream()) pObject->Release(); return FALSE; } - if (!m_pDocument->InsertIndirectObject(pObject->m_ObjNum, pObject)) + if (!m_pDocument->ReplaceIndirectObjectIfHigherGeneration(pObject->m_ObjNum, + pObject)) { return FALSE; + } } CPDF_Stream* pStream = pObject->AsStream(); @@ -1230,7 +1234,8 @@ CPDF_StreamAcc* CPDF_Parser::GetObjectStream(uint32_t objnum) { if (!m_pDocument) return nullptr; - const CPDF_Stream* pStream = ToStream(m_pDocument->GetIndirectObject(objnum)); + const CPDF_Stream* pStream = + ToStream(m_pDocument->GetOrParseIndirectObject(objnum)); if (!pStream) return nullptr; diff --git a/core/fpdfapi/fpdf_parser/cpdf_reference.cpp b/core/fpdfapi/fpdf_parser/cpdf_reference.cpp index 007423e5fb..afda50c324 100644 --- a/core/fpdfapi/fpdf_parser/cpdf_reference.cpp +++ b/core/fpdfapi/fpdf_parser/cpdf_reference.cpp @@ -63,5 +63,6 @@ void CPDF_Reference::SetRef(CPDF_IndirectObjectHolder* pDoc, uint32_t objnum) { } CPDF_Object* CPDF_Reference::GetDirect() const { - return m_pObjList ? m_pObjList->GetIndirectObject(m_RefObjNum) : nullptr; + return m_pObjList ? m_pObjList->GetOrParseIndirectObject(m_RefObjNum) + : nullptr; } diff --git a/core/fpdfapi/fpdf_parser/include/cfdf_document.h b/core/fpdfapi/fpdf_parser/include/cfdf_document.h index 18b9442fa9..834aecd1ba 100644 --- a/core/fpdfapi/fpdf_parser/include/cfdf_document.h +++ b/core/fpdfapi/fpdf_parser/include/cfdf_document.h @@ -19,7 +19,7 @@ class CFDF_Document : public CPDF_IndirectObjectHolder { static CFDF_Document* ParseFile(IFX_FileRead* pFile, FX_BOOL bOwnFile = FALSE); static CFDF_Document* ParseMemory(const uint8_t* pData, uint32_t size); - ~CFDF_Document(); + ~CFDF_Document() override; FX_BOOL WriteBuf(CFX_ByteTextBuf& buf) const; CPDF_Dictionary* GetRoot() const { return m_pRootDict; } diff --git a/core/fpdfapi/fpdf_parser/include/cpdf_document.h b/core/fpdfapi/fpdf_parser/include/cpdf_document.h index 4a12ea97dc..adb8587f4f 100644 --- a/core/fpdfapi/fpdf_parser/include/cpdf_document.h +++ b/core/fpdfapi/fpdf_parser/include/cpdf_document.h @@ -40,7 +40,7 @@ class JBig2_DocumentContext; class CPDF_Document : public CPDF_IndirectObjectHolder { public: explicit CPDF_Document(CPDF_Parser* pParser); - ~CPDF_Document(); + ~CPDF_Document() override; CPDF_Parser* GetParser() const { return m_pParser; } CPDF_Dictionary* GetRoot() const { return m_pRootDict; } @@ -125,7 +125,9 @@ class CPDF_Document : public CPDF_IndirectObjectHolder { int& index, int level = 0); FX_BOOL CheckOCGVisible(CPDF_Dictionary* pOCG, FX_BOOL bPrinting); + CPDF_Object* ParseIndirectObject(uint32_t objnum) override; + CPDF_Parser* m_pParser; CPDF_Dictionary* m_pRootDict; CPDF_Dictionary* m_pInfoDict; CFX_ByteString m_ID1; diff --git a/core/fpdfapi/fpdf_parser/include/cpdf_indirect_object_holder.h b/core/fpdfapi/fpdf_parser/include/cpdf_indirect_object_holder.h index c29746fdd7..63fadf19d6 100644 --- a/core/fpdfapi/fpdf_parser/include/cpdf_indirect_object_holder.h +++ b/core/fpdfapi/fpdf_parser/include/cpdf_indirect_object_holder.h @@ -19,24 +19,32 @@ class CPDF_IndirectObjectHolder { using iterator = std::map::iterator; using const_iterator = std::map::const_iterator; - explicit CPDF_IndirectObjectHolder(CPDF_Parser* pParser); - ~CPDF_IndirectObjectHolder(); + CPDF_IndirectObjectHolder(); + virtual ~CPDF_IndirectObjectHolder(); + + CPDF_Object* GetIndirectObject(uint32_t objnum) const; + CPDF_Object* GetOrParseIndirectObject(uint32_t objnum); - CPDF_Object* GetIndirectObject(uint32_t objnum); - uint32_t AddIndirectObject(CPDF_Object* pObj); void ReleaseIndirectObject(uint32_t objnum); - // Takes ownership of |pObj|. - bool InsertIndirectObject(uint32_t objnum, CPDF_Object* pObj); + // The following take ownership of |pObj|. + uint32_t AddIndirectObject(CPDF_Object* pObj); + void ReplaceIndirectObject(CPDF_Object* pObj); + bool ReplaceIndirectObjectIfHigherGeneration(uint32_t objnum, + CPDF_Object* pObj); uint32_t GetLastObjNum() const { return m_LastObjNum; } + void SetLastObjNum(uint32_t objnum) { m_LastObjNum = objnum; } + iterator begin() { return m_IndirectObjs.begin(); } const_iterator begin() const { return m_IndirectObjs.begin(); } iterator end() { return m_IndirectObjs.end(); } const_iterator end() const { return m_IndirectObjs.end(); } protected: - CPDF_Parser* m_pParser; + virtual CPDF_Object* ParseIndirectObject(uint32_t objnum); + + private: uint32_t m_LastObjNum; std::map m_IndirectObjs; }; diff --git a/core/fpdfapi/fpdf_parser/include/cpdf_object.h b/core/fpdfapi/fpdf_parser/include/cpdf_object.h index f637e36667..86f3879ce1 100644 --- a/core/fpdfapi/fpdf_parser/include/cpdf_object.h +++ b/core/fpdfapi/fpdf_parser/include/cpdf_object.h @@ -79,6 +79,10 @@ class CPDF_Object { virtual const CPDF_String* AsString() const; protected: + friend class CPDF_Document; + friend class CPDF_IndirectObjectHolder; + friend class CPDF_Parser; + CPDF_Object() : m_ObjNum(0), m_GenNum(0) {} virtual ~CPDF_Object(); void Destroy() { delete this; } @@ -86,9 +90,6 @@ class CPDF_Object { uint32_t m_ObjNum; uint32_t m_GenNum; - friend class CPDF_IndirectObjectHolder; - friend class CPDF_Parser; - private: CPDF_Object(const CPDF_Object& src) {} }; -- cgit v1.2.3