summaryrefslogtreecommitdiff
path: root/core/fpdfapi/parser
diff options
context:
space:
mode:
authortsepez <tsepez@chromium.org>2016-11-15 11:33:44 -0800
committerCommit bot <commit-bot@chromium.org>2016-11-15 11:33:44 -0800
commit70c4afd5c3c5c44cd24f814423a23a6ef05bba02 (patch)
treecbe593d0b6c0bfc6fd5038bf60a77a94e49c69c9 /core/fpdfapi/parser
parentf16f6b8b52277348f5d571b7641bb0bbd5239589 (diff)
downloadpdfium-70c4afd5c3c5c44cd24f814423a23a6ef05bba02.tar.xz
Make AddIndirectObject() take a unique_ptr.
Add convenience routines to create and add object in one step. Review-Url: https://codereview.chromium.org/2489283003
Diffstat (limited to 'core/fpdfapi/parser')
-rw-r--r--core/fpdfapi/parser/cfdf_document.cpp4
-rw-r--r--core/fpdfapi/parser/cpdf_array.cpp10
-rw-r--r--core/fpdfapi/parser/cpdf_array.h1
-rw-r--r--core/fpdfapi/parser/cpdf_dictionary.cpp12
-rw-r--r--core/fpdfapi/parser/cpdf_dictionary.h6
-rw-r--r--core/fpdfapi/parser/cpdf_document.cpp64
-rw-r--r--core/fpdfapi/parser/cpdf_document_unittest.cpp63
-rw-r--r--core/fpdfapi/parser/cpdf_indirect_object_holder.cpp11
-rw-r--r--core/fpdfapi/parser/cpdf_indirect_object_holder.h14
-rw-r--r--core/fpdfapi/parser/cpdf_object_unittest.cpp30
10 files changed, 123 insertions, 92 deletions
diff --git a/core/fpdfapi/parser/cfdf_document.cpp b/core/fpdfapi/parser/cfdf_document.cpp
index f54e598506..d76ae1e642 100644
--- a/core/fpdfapi/parser/cfdf_document.cpp
+++ b/core/fpdfapi/parser/cfdf_document.cpp
@@ -26,8 +26,8 @@ CFDF_Document::~CFDF_Document() {
CFDF_Document* CFDF_Document::CreateNewDoc() {
CFDF_Document* pDoc = new CFDF_Document;
- pDoc->m_pRootDict = new CPDF_Dictionary(pDoc->GetByteStringPool());
- pDoc->AddIndirectObject(pDoc->m_pRootDict);
+ pDoc->m_pRootDict =
+ pDoc->NewIndirect<CPDF_Dictionary>(pDoc->GetByteStringPool());
pDoc->m_pRootDict->SetFor("FDF",
new CPDF_Dictionary(pDoc->GetByteStringPool()));
return pDoc;
diff --git a/core/fpdfapi/parser/cpdf_array.cpp b/core/fpdfapi/parser/cpdf_array.cpp
index af9b544f0a..f8ec46acc9 100644
--- a/core/fpdfapi/parser/cpdf_array.cpp
+++ b/core/fpdfapi/parser/cpdf_array.cpp
@@ -155,8 +155,8 @@ void CPDF_Array::ConvertToIndirectObjectAt(size_t i,
if (!pObj || pObj->IsReference())
return;
- uint32_t dwObjNum = pHolder->AddIndirectObject(pObj);
- m_Objects[i] = new CPDF_Reference(pHolder, dwObjNum);
+ CPDF_Object* pNew = pHolder->AddIndirectObject(pdfium::WrapUnique(pObj));
+ m_Objects[i] = new CPDF_Reference(pHolder, pNew->GetObjNum());
}
void CPDF_Array::SetAt(size_t i, CPDF_Object* pObj) {
@@ -209,3 +209,9 @@ void CPDF_Array::AddReference(CPDF_IndirectObjectHolder* pDoc,
uint32_t objnum) {
Add(new CPDF_Reference(pDoc, objnum));
}
+
+void CPDF_Array::AddReference(CPDF_IndirectObjectHolder* pDoc,
+ CPDF_Object* pObj) {
+ ASSERT(!pObj->IsInline());
+ Add(new CPDF_Reference(pDoc, pObj->GetObjNum()));
+}
diff --git a/core/fpdfapi/parser/cpdf_array.h b/core/fpdfapi/parser/cpdf_array.h
index 5a9b10cb3c..bf4b8a626d 100644
--- a/core/fpdfapi/parser/cpdf_array.h
+++ b/core/fpdfapi/parser/cpdf_array.h
@@ -55,6 +55,7 @@ class CPDF_Array : public CPDF_Object {
void AddString(const CFX_ByteString& str);
void AddName(const CFX_ByteString& str);
void AddReference(CPDF_IndirectObjectHolder* pDoc, uint32_t objnum);
+ void AddReference(CPDF_IndirectObjectHolder* pDoc, CPDF_Object* pObj);
iterator begin() { return m_Objects.begin(); }
iterator end() { return m_Objects.end(); }
diff --git a/core/fpdfapi/parser/cpdf_dictionary.cpp b/core/fpdfapi/parser/cpdf_dictionary.cpp
index 403c29fa0d..02cdfa37da 100644
--- a/core/fpdfapi/parser/cpdf_dictionary.cpp
+++ b/core/fpdfapi/parser/cpdf_dictionary.cpp
@@ -199,8 +199,9 @@ void CPDF_Dictionary::ConvertToIndirectObjectFor(
if (it == m_Map.end() || it->second->IsReference())
return;
- uint32_t objnum = pHolder->AddIndirectObject(it->second);
- it->second = new CPDF_Reference(pHolder, objnum);
+ CPDF_Object* pObj =
+ pHolder->AddIndirectObject(pdfium::WrapUnique(it->second));
+ it->second = new CPDF_Reference(pHolder, pObj->GetObjNum());
}
void CPDF_Dictionary::RemoveFor(const CFX_ByteString& key) {
@@ -251,6 +252,13 @@ void CPDF_Dictionary::SetReferenceFor(const CFX_ByteString& key,
SetFor(key, new CPDF_Reference(pDoc, objnum));
}
+void CPDF_Dictionary::SetReferenceFor(const CFX_ByteString& key,
+ CPDF_IndirectObjectHolder* pDoc,
+ CPDF_Object* pObj) {
+ ASSERT(!pObj->IsInline());
+ SetFor(key, new CPDF_Reference(pDoc, pObj->GetObjNum()));
+}
+
void CPDF_Dictionary::SetNumberFor(const CFX_ByteString& key, FX_FLOAT f) {
SetFor(key, new CPDF_Number(f));
}
diff --git a/core/fpdfapi/parser/cpdf_dictionary.h b/core/fpdfapi/parser/cpdf_dictionary.h
index fffe03463c..ebfd7e92ee 100644
--- a/core/fpdfapi/parser/cpdf_dictionary.h
+++ b/core/fpdfapi/parser/cpdf_dictionary.h
@@ -61,6 +61,7 @@ class CPDF_Dictionary : public CPDF_Object {
// Set* functions invalidate iterators for the element with the key |key|.
void SetFor(const CFX_ByteString& key, CPDF_Object* pObj);
+ void SetBooleanFor(const CFX_ByteString& key, bool bValue);
void SetNameFor(const CFX_ByteString& key, const CFX_ByteString& name);
void SetStringFor(const CFX_ByteString& key, const CFX_ByteString& str);
void SetIntegerFor(const CFX_ByteString& key, int i);
@@ -68,9 +69,12 @@ class CPDF_Dictionary : public CPDF_Object {
void SetReferenceFor(const CFX_ByteString& key,
CPDF_IndirectObjectHolder* pDoc,
uint32_t objnum);
+ void SetReferenceFor(const CFX_ByteString& key,
+ CPDF_IndirectObjectHolder* pDoc,
+ CPDF_Object* pObj);
+
void SetRectFor(const CFX_ByteString& key, const CFX_FloatRect& rect);
void SetMatrixFor(const CFX_ByteString& key, const CFX_Matrix& matrix);
- void SetBooleanFor(const CFX_ByteString& key, bool bValue);
void ConvertToIndirectObjectFor(const CFX_ByteString& key,
CPDF_IndirectObjectHolder* pHolder);
diff --git a/core/fpdfapi/parser/cpdf_document.cpp b/core/fpdfapi/parser/cpdf_document.cpp
index ebd3156e35..35c18997b9 100644
--- a/core/fpdfapi/parser/cpdf_document.cpp
+++ b/core/fpdfapi/parser/cpdf_document.cpp
@@ -310,15 +310,16 @@ void ProcessNonbCJK(CPDF_Dictionary* pBaseDict,
pBaseDict->SetFor("Widths", pWidths);
}
-CPDF_Dictionary* CalculateFontDesc(CPDF_Document* pDoc,
- CFX_ByteString basefont,
- int flags,
- int italicangle,
- int ascend,
- int descend,
- CPDF_Array* bbox,
- int32_t stemV) {
- CPDF_Dictionary* pFontDesc = new CPDF_Dictionary(pDoc->GetByteStringPool());
+std::unique_ptr<CPDF_Dictionary> CalculateFontDesc(CPDF_Document* pDoc,
+ CFX_ByteString basefont,
+ int flags,
+ int italicangle,
+ int ascend,
+ int descend,
+ CPDF_Array* bbox,
+ int32_t stemV) {
+ auto pFontDesc =
+ pdfium::MakeUnique<CPDF_Dictionary>(pDoc->GetByteStringPool());
pFontDesc->SetNameFor("Type", "FontDescriptor");
pFontDesc->SetNameFor("FontName", basefont);
pFontDesc->SetIntegerFor("Flags", flags);
@@ -648,23 +649,21 @@ CPDF_Image* CPDF_Document::LoadImageFromPageData(uint32_t dwStreamObjNum) {
void CPDF_Document::CreateNewDoc() {
ASSERT(!m_pRootDict && !m_pInfoDict);
- m_pRootDict = new CPDF_Dictionary(m_pByteStringPool);
+ m_pRootDict = NewIndirect<CPDF_Dictionary>(m_pByteStringPool);
m_pRootDict->SetNameFor("Type", "Catalog");
- AddIndirectObject(m_pRootDict);
- CPDF_Dictionary* pPages = new CPDF_Dictionary(m_pByteStringPool);
+ CPDF_Dictionary* pPages = NewIndirect<CPDF_Dictionary>(m_pByteStringPool);
pPages->SetNameFor("Type", "Pages");
pPages->SetNumberFor("Count", 0);
pPages->SetFor("Kids", new CPDF_Array);
- m_pRootDict->SetReferenceFor("Pages", this, AddIndirectObject(pPages));
- m_pInfoDict = new CPDF_Dictionary(m_pByteStringPool);
- AddIndirectObject(m_pInfoDict);
+ m_pRootDict->SetReferenceFor("Pages", this, pPages);
+ m_pInfoDict = NewIndirect<CPDF_Dictionary>(m_pByteStringPool);
}
CPDF_Dictionary* CPDF_Document::CreateNewPage(int iPage) {
- CPDF_Dictionary* pDict = new CPDF_Dictionary(m_pByteStringPool);
+ CPDF_Dictionary* pDict = NewIndirect<CPDF_Dictionary>(m_pByteStringPool);
pDict->SetNameFor("Type", "Page");
- uint32_t dwObjNum = AddIndirectObject(pDict);
+ uint32_t dwObjNum = pDict->GetObjNum();
if (!InsertNewPage(iPage, pDict)) {
DeleteIndirectObject(dwObjNum);
return nullptr;
@@ -780,19 +779,21 @@ size_t CPDF_Document::CalculateEncodingDict(int charset,
}
if (i == FX_ArraySize(g_FX_CharsetUnicodes))
return i;
- CPDF_Dictionary* pEncodingDict = new CPDF_Dictionary(m_pByteStringPool);
+
+ CPDF_Dictionary* pEncodingDict =
+ NewIndirect<CPDF_Dictionary>(m_pByteStringPool);
pEncodingDict->SetNameFor("BaseEncoding", "WinAnsiEncoding");
+
CPDF_Array* pArray = new CPDF_Array;
pArray->AddInteger(128);
+
const uint16_t* pUnicodes = g_FX_CharsetUnicodes[i].m_pUnicodes;
for (int j = 0; j < 128; j++) {
CFX_ByteString name = PDF_AdobeNameFromUnicode(pUnicodes[j]);
pArray->AddName(name.IsEmpty() ? ".notdef" : name);
}
pEncodingDict->SetFor("Differences", pArray);
- pBaseDict->SetReferenceFor("Encoding", this,
- AddIndirectObject(pEncodingDict));
-
+ pBaseDict->SetReferenceFor("Encoding", this, pEncodingDict);
return i;
}
@@ -802,7 +803,7 @@ CPDF_Dictionary* CPDF_Document::ProcessbCJK(
bool bVert,
CFX_ByteString basefont,
std::function<void(FX_WCHAR, FX_WCHAR, CPDF_Array*)> Insert) {
- CPDF_Dictionary* pFontDict = new CPDF_Dictionary(m_pByteStringPool);
+ CPDF_Dictionary* pFontDict = NewIndirect<CPDF_Dictionary>(m_pByteStringPool);
CFX_ByteString cmap;
CFX_ByteString ordering;
int supplement = 0;
@@ -859,7 +860,7 @@ CPDF_Dictionary* CPDF_Document::ProcessbCJK(
pFontDict->SetFor("CIDSystemInfo", pCIDSysInfo);
CPDF_Array* pArray = new CPDF_Array;
pBaseDict->SetFor("DescendantFonts", pArray);
- pArray->AddReference(this, AddIndirectObject(pFontDict));
+ pArray->AddReference(this, pFontDict->GetObjNum());
return pFontDict;
}
@@ -877,7 +878,7 @@ CPDF_Font* CPDF_Document::AddFont(CFX_Font* pFont, int charset, bool bVert) {
CalculateFlags(pFont->IsBold(), pFont->IsItalic(), pFont->IsFixedWidth(),
false, false, charset == FXFONT_SYMBOL_CHARSET);
- CPDF_Dictionary* pBaseDict = new CPDF_Dictionary(m_pByteStringPool);
+ CPDF_Dictionary* pBaseDict = NewIndirect<CPDF_Dictionary>(m_pByteStringPool);
pBaseDict->SetNameFor("Type", "Font");
std::unique_ptr<CFX_UnicodeEncoding> pEncoding(
new CFX_UnicodeEncoding(pFont));
@@ -918,7 +919,6 @@ CPDF_Font* CPDF_Document::AddFont(CFX_Font* pFont, int charset, bool bVert) {
end, widthArr);
});
}
- AddIndirectObject(pBaseDict);
int italicangle =
pFont->GetSubstFont() ? pFont->GetSubstFont()->m_ItalicAngle : 0;
FX_RECT bbox;
@@ -943,11 +943,10 @@ CPDF_Font* CPDF_Document::AddFont(CFX_Font* pFont, int charset, bool bVert) {
nStemV = width;
}
}
- CPDF_Dictionary* pFontDesc =
+ CPDF_Dictionary* pFontDesc = ToDictionary(AddIndirectObject(
CalculateFontDesc(this, basefont, flags, italicangle, pFont->GetAscent(),
- pFont->GetDescent(), pBBox, nStemV);
- pFontDict->SetReferenceFor("FontDescriptor", this,
- AddIndirectObject(pFontDesc));
+ pFont->GetDescent(), pBBox, nStemV)));
+ pFontDict->SetReferenceFor("FontDescriptor", this, pFontDesc);
return LoadFont(pBaseDict);
}
@@ -1009,7 +1008,7 @@ CPDF_Font* CPDF_Document::AddWindowsFont(LOGFONTA* pLogFont,
ptm->otmrcFontBox.right, ptm->otmrcFontBox.top};
FX_Free(tm_buf);
basefont.Replace(" ", "");
- CPDF_Dictionary* pBaseDict = new CPDF_Dictionary(m_pByteStringPool);
+ CPDF_Dictionary* pBaseDict = NewIndirect<CPDF_Dictionary>(m_pByteStringPool);
pBaseDict->SetNameFor("Type", "Font");
CPDF_Dictionary* pFontDict = pBaseDict;
if (!bCJK) {
@@ -1034,16 +1033,15 @@ CPDF_Font* CPDF_Document::AddWindowsFont(LOGFONTA* pLogFont,
InsertWidthArray(hDC, start, end, widthArr);
});
}
- AddIndirectObject(pBaseDict);
CPDF_Array* pBBox = new CPDF_Array;
for (int i = 0; i < 4; i++)
pBBox->AddInteger(bbox[i]);
- CPDF_Dictionary* pFontDesc =
+ std::unique_ptr<CPDF_Dictionary> pFontDesc =
CalculateFontDesc(this, basefont, flags, italicangle, ascend, descend,
pBBox, pLogFont->lfWeight / 5);
pFontDesc->SetIntegerFor("CapHeight", capheight);
pFontDict->SetReferenceFor("FontDescriptor", this,
- AddIndirectObject(pFontDesc));
+ AddIndirectObject(std::move(pFontDesc)));
hFont = SelectObject(hDC, hFont);
DeleteObject(hFont);
DeleteDC(hDC);
diff --git a/core/fpdfapi/parser/cpdf_document_unittest.cpp b/core/fpdfapi/parser/cpdf_document_unittest.cpp
index f27e7403f6..048a9fead2 100644
--- a/core/fpdfapi/parser/cpdf_document_unittest.cpp
+++ b/core/fpdfapi/parser/cpdf_document_unittest.cpp
@@ -13,24 +13,25 @@
#include "core/fpdfapi/parser/cpdf_parser.h"
#include "core/fxcrt/fx_memory.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/base/ptr_util.h"
namespace {
-CPDF_Dictionary* CreatePageTreeNode(CPDF_Array* kids,
+CPDF_Dictionary* CreatePageTreeNode(std::unique_ptr<CPDF_Array> kids,
CPDF_Document* pDoc,
int count) {
- CPDF_Dictionary* pageNode = new CPDF_Dictionary();
+ CPDF_Array* pUnowned = pDoc->AddIndirectObject(std::move(kids))->AsArray();
+ CPDF_Dictionary* pageNode = pDoc->NewIndirect<CPDF_Dictionary>();
pageNode->SetStringFor("Type", "Pages");
- pageNode->SetReferenceFor("Kids", pDoc, pDoc->AddIndirectObject(kids));
+ pageNode->SetReferenceFor("Kids", pDoc, pUnowned);
pageNode->SetIntegerFor("Count", count);
- uint32_t pageNodeRef = pDoc->AddIndirectObject(pageNode);
- for (size_t i = 0; i < kids->GetCount(); i++)
- kids->GetDictAt(i)->SetReferenceFor("Parent", pDoc, pageNodeRef);
+ for (size_t i = 0; i < pUnowned->GetCount(); i++)
+ pUnowned->GetDictAt(i)->SetReferenceFor("Parent", pDoc, pageNode);
return pageNode;
}
-CPDF_Dictionary* CreateNumberedPage(size_t number) {
- CPDF_Dictionary* page = new CPDF_Dictionary();
+std::unique_ptr<CPDF_Dictionary> CreateNumberedPage(size_t number) {
+ auto page = pdfium::MakeUnique<CPDF_Dictionary>();
page->SetStringFor("Type", "Page");
page->SetIntegerFor("PageNumbering", number);
return page;
@@ -40,34 +41,37 @@ class CPDF_TestDocumentForPages : public CPDF_Document {
public:
CPDF_TestDocumentForPages() : CPDF_Document(nullptr) {
// Set up test
- CPDF_Array* zeroToTwo = new CPDF_Array();
+ auto zeroToTwo = pdfium::MakeUnique<CPDF_Array>();
zeroToTwo->AddReference(this, AddIndirectObject(CreateNumberedPage(0)));
zeroToTwo->AddReference(this, AddIndirectObject(CreateNumberedPage(1)));
zeroToTwo->AddReference(this, AddIndirectObject(CreateNumberedPage(2)));
- CPDF_Dictionary* branch1 = CreatePageTreeNode(zeroToTwo, this, 3);
+ CPDF_Dictionary* branch1 =
+ CreatePageTreeNode(std::move(zeroToTwo), this, 3);
- CPDF_Array* zeroToThree = new CPDF_Array();
+ auto zeroToThree = pdfium::MakeUnique<CPDF_Array>();
zeroToThree->AddReference(this, branch1->GetObjNum());
zeroToThree->AddReference(this, AddIndirectObject(CreateNumberedPage(3)));
- CPDF_Dictionary* branch2 = CreatePageTreeNode(zeroToThree, this, 4);
+ CPDF_Dictionary* branch2 =
+ CreatePageTreeNode(std::move(zeroToThree), this, 4);
- CPDF_Array* fourFive = new CPDF_Array();
+ auto fourFive = pdfium::MakeUnique<CPDF_Array>();
fourFive->AddReference(this, AddIndirectObject(CreateNumberedPage(4)));
fourFive->AddReference(this, AddIndirectObject(CreateNumberedPage(5)));
- CPDF_Dictionary* branch3 = CreatePageTreeNode(fourFive, this, 2);
+ CPDF_Dictionary* branch3 = CreatePageTreeNode(std::move(fourFive), this, 2);
- CPDF_Array* justSix = new CPDF_Array();
+ auto justSix = pdfium::MakeUnique<CPDF_Array>();
justSix->AddReference(this, AddIndirectObject(CreateNumberedPage(6)));
- CPDF_Dictionary* branch4 = CreatePageTreeNode(justSix, this, 1);
+ CPDF_Dictionary* branch4 = CreatePageTreeNode(std::move(justSix), this, 1);
- CPDF_Array* allPages = new CPDF_Array();
- allPages->AddReference(this, branch2->GetObjNum());
- allPages->AddReference(this, branch3->GetObjNum());
- allPages->AddReference(this, branch4->GetObjNum());
- CPDF_Dictionary* pagesDict = CreatePageTreeNode(allPages, this, 7);
+ auto allPages = pdfium::MakeUnique<CPDF_Array>();
+ allPages->AddReference(this, branch2);
+ allPages->AddReference(this, branch3);
+ allPages->AddReference(this, branch4);
+ CPDF_Dictionary* pagesDict =
+ CreatePageTreeNode(std::move(allPages), this, 7);
- m_pOwnedRootDict.reset(new CPDF_Dictionary());
- m_pOwnedRootDict->SetReferenceFor("Pages", this, pagesDict->GetObjNum());
+ m_pOwnedRootDict = pdfium::MakeUnique<CPDF_Dictionary>();
+ m_pOwnedRootDict->SetReferenceFor("Pages", this, pagesDict);
m_pRootDict = m_pOwnedRootDict.get();
m_PageList.SetSize(7);
}
@@ -80,13 +84,13 @@ class CPDF_TestDocumentWithPageWithoutPageNum : public CPDF_Document {
public:
CPDF_TestDocumentWithPageWithoutPageNum() : CPDF_Document(nullptr) {
// Set up test
- CPDF_Array* allPages = new CPDF_Array();
+ auto allPages = pdfium::MakeUnique<CPDF_Array>();
allPages->AddReference(this, AddIndirectObject(CreateNumberedPage(0)));
allPages->AddReference(this, AddIndirectObject(CreateNumberedPage(1)));
// Page without pageNum.
- allPages->Add(CreateNumberedPage(2));
- CPDF_Dictionary* pagesDict = CreatePageTreeNode(allPages, this, 3);
-
+ allPages->Add(CreateNumberedPage(2).release());
+ CPDF_Dictionary* pagesDict =
+ CreatePageTreeNode(std::move(allPages), this, 3);
m_pOwnedRootDict.reset(new CPDF_Dictionary());
m_pOwnedRootDict->SetReferenceFor("Pages", this, pagesDict->GetObjNum());
m_pRootDict = m_pOwnedRootDict.get();
@@ -186,15 +190,14 @@ TEST_F(cpdf_document_test, UseCachedPageObjNumIfHaveNotPagesDict) {
TestLinearized linearized(dict.get());
document.LoadLinearizedDoc(&linearized);
ASSERT_EQ(page_count, document.GetPageCount());
- CPDF_Object* page_stub = new CPDF_Dictionary();
- const uint32_t obj_num = document.AddIndirectObject(page_stub);
+ CPDF_Object* page_stub = document.NewIndirect<CPDF_Dictionary>();
+ const uint32_t obj_num = page_stub->GetObjNum();
const int test_page_num = 33;
EXPECT_FALSE(document.IsPageLoaded(test_page_num));
EXPECT_EQ(nullptr, document.GetPage(test_page_num));
document.SetPageObjNum(test_page_num, obj_num);
-
EXPECT_TRUE(document.IsPageLoaded(test_page_num));
EXPECT_EQ(page_stub, document.GetPage(test_page_num));
}
diff --git a/core/fpdfapi/parser/cpdf_indirect_object_holder.cpp b/core/fpdfapi/parser/cpdf_indirect_object_holder.cpp
index 529eda21fb..12b1e9f089 100644
--- a/core/fpdfapi/parser/cpdf_indirect_object_holder.cpp
+++ b/core/fpdfapi/parser/cpdf_indirect_object_holder.cpp
@@ -43,13 +43,14 @@ std::unique_ptr<CPDF_Object> CPDF_IndirectObjectHolder::ParseIndirectObject(
return nullptr;
}
-uint32_t CPDF_IndirectObjectHolder::AddIndirectObject(CPDF_Object* pObj) {
+CPDF_Object* CPDF_IndirectObjectHolder::AddIndirectObject(
+ std::unique_ptr<CPDF_Object> pObj) {
CHECK(!pObj->m_ObjNum);
- m_LastObjNum++;
+ CPDF_Object* pUnowned = pObj.get();
+ pObj->m_ObjNum = ++m_LastObjNum;
m_IndirectObjs[m_LastObjNum].release(); // TODO(tsepez): stop this leak.
- m_IndirectObjs[m_LastObjNum].reset(pObj);
- pObj->m_ObjNum = m_LastObjNum;
- return m_LastObjNum;
+ m_IndirectObjs[m_LastObjNum] = std::move(pObj);
+ return pUnowned;
}
bool CPDF_IndirectObjectHolder::ReplaceIndirectObjectIfHigherGeneration(
diff --git a/core/fpdfapi/parser/cpdf_indirect_object_holder.h b/core/fpdfapi/parser/cpdf_indirect_object_holder.h
index db6f4acbf4..428bfa05ec 100644
--- a/core/fpdfapi/parser/cpdf_indirect_object_holder.h
+++ b/core/fpdfapi/parser/cpdf_indirect_object_holder.h
@@ -11,6 +11,7 @@
#include <memory>
#include "core/fxcrt/fx_system.h"
+#include "third_party/base/ptr_util.h"
class CPDF_Object;
@@ -26,8 +27,17 @@ class CPDF_IndirectObjectHolder {
CPDF_Object* GetOrParseIndirectObject(uint32_t objnum);
void DeleteIndirectObject(uint32_t objnum);
- // Take ownership of |pObj|.
- uint32_t AddIndirectObject(CPDF_Object* pObj);
+ // Creates and adds a new object owned by the indirect object holder,
+ // and returns an unowned pointer to it.
+ template <typename T, typename... Args>
+ T* NewIndirect(Args... args) {
+ return static_cast<T*>(AddIndirectObject(pdfium::MakeUnique<T>(args...)));
+ }
+
+ // Takes ownership of |pObj|, returns unowned pointer to it.
+ CPDF_Object* AddIndirectObject(std::unique_ptr<CPDF_Object> pObj);
+
+ // Always takes ownership of |pObj|, return true if higher generation number.
bool ReplaceIndirectObjectIfHigherGeneration(
uint32_t objnum,
std::unique_ptr<CPDF_Object> pObj);
diff --git a/core/fpdfapi/parser/cpdf_object_unittest.cpp b/core/fpdfapi/parser/cpdf_object_unittest.cpp
index b40a8e373d..4145f248fa 100644
--- a/core/fpdfapi/parser/cpdf_object_unittest.cpp
+++ b/core/fpdfapi/parser/cpdf_object_unittest.cpp
@@ -90,16 +90,17 @@ class PDFObjectsTest : public testing::Test {
m_DirectObjs.emplace_back(objs[i]);
// Indirect references to indirect objects.
- m_ObjHolder.reset(new CPDF_IndirectObjectHolder());
- m_IndirectObjs = {
- boolean_true_obj->Clone().release(), number_int_obj->Clone().release(),
- str_spec_obj->Clone().release(), name_obj->Clone().release(),
- m_ArrayObj->Clone().release(), m_DictObj->Clone().release(),
- stream_obj->Clone().release()};
- for (size_t i = 0; i < m_IndirectObjs.size(); ++i) {
- m_ObjHolder->AddIndirectObject(m_IndirectObjs[i]);
- m_RefObjs.emplace_back(new CPDF_Reference(
- m_ObjHolder.get(), m_IndirectObjs[i]->GetObjNum()));
+ m_ObjHolder = pdfium::MakeUnique<CPDF_IndirectObjectHolder>();
+ m_IndirectObjs = {m_ObjHolder->AddIndirectObject(boolean_true_obj->Clone()),
+ m_ObjHolder->AddIndirectObject(number_int_obj->Clone()),
+ m_ObjHolder->AddIndirectObject(str_spec_obj->Clone()),
+ m_ObjHolder->AddIndirectObject(name_obj->Clone()),
+ m_ObjHolder->AddIndirectObject(m_ArrayObj->Clone()),
+ m_ObjHolder->AddIndirectObject(m_DictObj->Clone()),
+ m_ObjHolder->AddIndirectObject(stream_obj->Clone())};
+ for (CPDF_Object* pObj : m_IndirectObjs) {
+ m_RefObjs.emplace_back(
+ new CPDF_Reference(m_ObjHolder.get(), pObj->GetObjNum()));
}
}
@@ -837,14 +838,13 @@ TEST(PDFObjectTest, CloneCheckLoop) {
{
CPDF_IndirectObjectHolder objects_holder;
// Create an object with a reference loop.
- CPDF_Dictionary* dict_obj = new CPDF_Dictionary();
- CPDF_Array* arr_obj = new CPDF_Array;
- objects_holder.AddIndirectObject(dict_obj);
- EXPECT_EQ(1u, dict_obj->GetObjNum());
- dict_obj->SetFor("arr", arr_obj);
+ CPDF_Dictionary* dict_obj = objects_holder.NewIndirect<CPDF_Dictionary>();
+ std::unique_ptr<CPDF_Array> arr_obj = pdfium::MakeUnique<CPDF_Array>();
arr_obj->InsertAt(
0, new CPDF_Reference(&objects_holder, dict_obj->GetObjNum()));
CPDF_Object* elem0 = arr_obj->GetObjectAt(0);
+ dict_obj->SetFor("arr", arr_obj.release());
+ EXPECT_EQ(1u, dict_obj->GetObjNum());
ASSERT_TRUE(elem0);
ASSERT_TRUE(elem0->IsReference());
EXPECT_EQ(1u, elem0->AsReference()->GetRefObjNum());