summaryrefslogtreecommitdiff
path: root/core/fpdfapi
diff options
context:
space:
mode:
authordsinclair <dsinclair@chromium.org>2016-08-17 12:45:26 -0700
committerCommit bot <commit-bot@chromium.org>2016-08-17 12:45:26 -0700
commit260f5fbf3553a96fa49b029cc050220039c30e2a (patch)
treebd2cb6ee2909cb33f0b78969086ec3aaf83e548a /core/fpdfapi
parent70ba38a9a1af0240529a96904dfdb8868b868719 (diff)
downloadpdfium-260f5fbf3553a96fa49b029cc050220039c30e2a.tar.xz
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
Diffstat (limited to 'core/fpdfapi')
-rw-r--r--core/fpdfapi/fpdf_edit/fpdf_edit_create.cpp15
-rw-r--r--core/fpdfapi/fpdf_parser/cfdf_document.cpp21
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_array_unittest.cpp4
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_data_avail.cpp6
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_document.cpp27
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_indirect_object_holder.cpp74
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_object_unittest.cpp9
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_parser.cpp11
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_reference.cpp3
-rw-r--r--core/fpdfapi/fpdf_parser/include/cfdf_document.h2
-rw-r--r--core/fpdfapi/fpdf_parser/include/cpdf_document.h4
-rw-r--r--core/fpdfapi/fpdf_parser/include/cpdf_indirect_object_holder.h22
-rw-r--r--core/fpdfapi/fpdf_parser/include/cpdf_object.h7
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<</Root " << m_pRootDict->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<CPDF_IndirectObjectHolder> 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<CPDF_IndirectObjectHolder> 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<uint32_t, CPDF_Object*>::iterator;
using const_iterator = std::map<uint32_t, CPDF_Object*>::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<uint32_t, CPDF_Object*> 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) {}
};