Return object number from CPDF_IndirectObjectHolder::AddIndirectObject()
Avoid handing the caller an unretained reference to an object that may
get replaced during execution. Most callers are simplified since they
wanted just the object number anyways.
Change-Id: Ia17f0a7911b24f442ba046b1b07c2891a16620e9
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/100130
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
index 382d3ee..6b2b296 100644
--- a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
+++ b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
@@ -498,8 +498,8 @@
gsDict->SetNewFor<CPDF_Name>("BM",
pPageObj->m_GeneralState.GetBlendMode());
}
- CPDF_Object* pDict = m_pDocument->AddIndirectObject(gsDict);
- name = RealizeResource(pDict, "ExtGState");
+ m_pDocument->AddIndirectObject(gsDict);
+ name = RealizeResource(std::move(gsDict), "ExtGState");
m_pObjHolder->GraphicsMapInsert(graphD, name);
}
*buf << "/" << PDF_NameEncode(name) << " gs ";
@@ -529,8 +529,8 @@
gsDict->SetNewFor<CPDF_Number>("ca", defaultGraphics.fillAlpha);
gsDict->SetNewFor<CPDF_Number>("CA", defaultGraphics.strokeAlpha);
gsDict->SetNewFor<CPDF_Name>("BM", "Normal");
- CPDF_Object* pDict = m_pDocument->AddIndirectObject(gsDict);
- ByteString name = RealizeResource(pDict, "ExtGState");
+ m_pDocument->AddIndirectObject(gsDict);
+ ByteString name = RealizeResource(std::move(gsDict), "ExtGState");
m_pObjHolder->GraphicsMapInsert(defaultGraphics, name);
return name;
}
@@ -580,9 +580,10 @@
pFontDict->SetFor("Encoding",
pEncoding->Realize(m_pDocument->GetByteStringPool()));
}
- pIndirectFont = m_pDocument->AddIndirectObject(pFontDict);
+ m_pDocument->AddIndirectObject(pFontDict);
+ pIndirectFont = std::move(pFontDict);
}
- dictName = RealizeResource(pIndirectFont, "Font");
+ dictName = RealizeResource(std::move(pIndirectFont), "Font");
m_pObjHolder->FontsMapInsert(data, dictName);
}
*buf << "/" << PDF_NameEncode(dictName) << " ";
diff --git a/core/fpdfapi/page/cpdf_docpagedata.cpp b/core/fpdfapi/page/cpdf_docpagedata.cpp
index 6334b04..e27019b 100644
--- a/core/fpdfapi/page/cpdf_docpagedata.cpp
+++ b/core/fpdfapi/page/cpdf_docpagedata.cpp
@@ -552,12 +552,12 @@
nStemV = width;
}
}
- CPDF_Dictionary* pFontDesc =
- ToDictionary(GetDocument()->AddIndirectObject(CalculateFontDesc(
- GetDocument(), basefont, flags, italicangle, pFont->GetAscent(),
- pFont->GetDescent(), std::move(pBBox), nStemV)));
+ RetainPtr<CPDF_Dictionary> pFontDesc = CalculateFontDesc(
+ GetDocument(), basefont, flags, italicangle, pFont->GetAscent(),
+ pFont->GetDescent(), std::move(pBBox), nStemV);
+ uint32_t new_objnum = GetDocument()->AddIndirectObject(std::move(pFontDesc));
pFontDict->SetNewFor<CPDF_Reference>("FontDescriptor", GetDocument(),
- pFontDesc->GetObjNum());
+ new_objnum);
return GetFont(pBaseDict);
}
@@ -635,10 +635,8 @@
CalculateFontDesc(GetDocument(), basefont, flags, italicangle, ascend,
descend, std::move(pBBox), pLogFont->lfWeight / 5);
pFontDesc->SetNewFor<CPDF_Number>("CapHeight", capheight);
- pFontDict->SetFor("FontDescriptor",
- GetDocument()
- ->AddIndirectObject(std::move(pFontDesc))
- ->MakeReference(GetDocument()));
+ GetDocument()->AddIndirectObject(pFontDesc);
+ pFontDict->SetFor("FontDescriptor", pFontDesc->MakeReference(GetDocument()));
hFont = SelectObject(hDC, hFont);
DeleteObject(hFont);
DeleteDC(hDC);
diff --git a/core/fpdfapi/parser/cpdf_array.cpp b/core/fpdfapi/parser/cpdf_array.cpp
index 850d701..c9dcdb9 100644
--- a/core/fpdfapi/parser/cpdf_array.cpp
+++ b/core/fpdfapi/parser/cpdf_array.cpp
@@ -210,8 +210,8 @@
if (!m_Objects[index] || m_Objects[index]->IsReference())
return;
- CPDF_Object* pNew = pHolder->AddIndirectObject(std::move(m_Objects[index]));
- m_Objects[index] = pNew->MakeReference(pHolder);
+ pHolder->AddIndirectObject(m_Objects[index]);
+ m_Objects[index] = m_Objects[index]->MakeReference(pHolder);
}
void CPDF_Array::SetAt(size_t index, RetainPtr<CPDF_Object> pObj) {
diff --git a/core/fpdfapi/parser/cpdf_dictionary.cpp b/core/fpdfapi/parser/cpdf_dictionary.cpp
index ea03f5b..4ccd646 100644
--- a/core/fpdfapi/parser/cpdf_dictionary.cpp
+++ b/core/fpdfapi/parser/cpdf_dictionary.cpp
@@ -296,8 +296,8 @@
if (it == m_Map.end() || it->second->IsReference())
return;
- CPDF_Object* pObj = pHolder->AddIndirectObject(std::move(it->second));
- it->second = pObj->MakeReference(pHolder);
+ pHolder->AddIndirectObject(it->second);
+ it->second = it->second->MakeReference(pHolder);
}
RetainPtr<CPDF_Object> CPDF_Dictionary::RemoveFor(ByteStringView key) {
diff --git a/core/fpdfapi/parser/cpdf_document_unittest.cpp b/core/fpdfapi/parser/cpdf_document_unittest.cpp
index 9c978f9..c6029db 100644
--- a/core/fpdfapi/parser/cpdf_document_unittest.cpp
+++ b/core/fpdfapi/parser/cpdf_document_unittest.cpp
@@ -28,15 +28,14 @@
RetainPtr<CPDF_Dictionary> CreatePageTreeNode(RetainPtr<CPDF_Array> kids,
CPDF_Document* pDoc,
int count) {
- CPDF_Array* pUnowned =
- pDoc->AddIndirectObject(std::move(kids))->AsMutableArray();
+ uint32_t new_objnum = pDoc->AddIndirectObject(kids);
auto pageNode = pDoc->NewIndirect<CPDF_Dictionary>();
pageNode->SetNewFor<CPDF_Name>("Type", "Pages");
- pageNode->SetNewFor<CPDF_Reference>("Kids", pDoc, pUnowned->GetObjNum());
+ pageNode->SetNewFor<CPDF_Reference>("Kids", pDoc, new_objnum);
pageNode->SetNewFor<CPDF_Number>("Count", count);
- for (size_t i = 0; i < pUnowned->size(); i++) {
- pUnowned->GetMutableDictAt(i)->SetNewFor<CPDF_Reference>(
- "Parent", pDoc, pageNode->GetObjNum());
+ for (size_t i = 0; i < kids->size(); i++) {
+ kids->GetMutableDictAt(i)->SetNewFor<CPDF_Reference>("Parent", pDoc,
+ pageNode->GetObjNum());
}
return pageNode;
}
@@ -54,32 +53,32 @@
// Set up test
auto zeroToTwo = pdfium::MakeRetain<CPDF_Array>();
zeroToTwo->AppendNew<CPDF_Reference>(
- this, AddIndirectObject(CreateNumberedPage(0))->GetObjNum());
+ this, AddIndirectObject(CreateNumberedPage(0)));
zeroToTwo->AppendNew<CPDF_Reference>(
- this, AddIndirectObject(CreateNumberedPage(1))->GetObjNum());
+ this, AddIndirectObject(CreateNumberedPage(1)));
zeroToTwo->AppendNew<CPDF_Reference>(
- this, AddIndirectObject(CreateNumberedPage(2))->GetObjNum());
+ this, AddIndirectObject(CreateNumberedPage(2)));
RetainPtr<CPDF_Dictionary> branch1 =
CreatePageTreeNode(std::move(zeroToTwo), this, 3);
auto zeroToThree = pdfium::MakeRetain<CPDF_Array>();
zeroToThree->AppendNew<CPDF_Reference>(this, branch1->GetObjNum());
zeroToThree->AppendNew<CPDF_Reference>(
- this, AddIndirectObject(CreateNumberedPage(3))->GetObjNum());
+ this, AddIndirectObject(CreateNumberedPage(3)));
RetainPtr<CPDF_Dictionary> branch2 =
CreatePageTreeNode(std::move(zeroToThree), this, 4);
auto fourFive = pdfium::MakeRetain<CPDF_Array>();
fourFive->AppendNew<CPDF_Reference>(
- this, AddIndirectObject(CreateNumberedPage(4))->GetObjNum());
+ this, AddIndirectObject(CreateNumberedPage(4)));
fourFive->AppendNew<CPDF_Reference>(
- this, AddIndirectObject(CreateNumberedPage(5))->GetObjNum());
+ this, AddIndirectObject(CreateNumberedPage(5)));
RetainPtr<CPDF_Dictionary> branch3 =
CreatePageTreeNode(std::move(fourFive), this, 2);
auto justSix = pdfium::MakeRetain<CPDF_Array>();
justSix->AppendNew<CPDF_Reference>(
- this, AddIndirectObject(CreateNumberedPage(6))->GetObjNum());
+ this, AddIndirectObject(CreateNumberedPage(6)));
RetainPtr<CPDF_Dictionary> branch4 =
CreatePageTreeNode(std::move(justSix), this, 1);
@@ -108,9 +107,9 @@
// Set up test
auto allPages = pdfium::MakeRetain<CPDF_Array>();
allPages->AppendNew<CPDF_Reference>(
- this, AddIndirectObject(CreateNumberedPage(0))->GetObjNum());
+ this, AddIndirectObject(CreateNumberedPage(0)));
allPages->AppendNew<CPDF_Reference>(
- this, AddIndirectObject(CreateNumberedPage(1))->GetObjNum());
+ this, AddIndirectObject(CreateNumberedPage(1)));
// Page without pageNum.
inlined_page_ = CreateNumberedPage(2);
allPages->Append(inlined_page_);
@@ -226,18 +225,18 @@
auto dict_type_name_page = pdfium::MakeRetain<CPDF_Dictionary>();
dict_type_name_page->SetNewFor<CPDF_Name>("Type", "Page");
- EXPECT_TRUE(CPDF_Document::IsValidPageObject(
- document.AddIndirectObject(dict_type_name_page)));
+ document.AddIndirectObject(dict_type_name_page);
+ EXPECT_TRUE(CPDF_Document::IsValidPageObject(dict_type_name_page.Get()));
auto dict_type_string_page = pdfium::MakeRetain<CPDF_Dictionary>();
dict_type_string_page->SetNewFor<CPDF_String>("Type", "Page", false);
- EXPECT_FALSE(CPDF_Document::IsValidPageObject(
- document.AddIndirectObject(dict_type_string_page)));
+ document.AddIndirectObject(dict_type_string_page);
+ EXPECT_FALSE(CPDF_Document::IsValidPageObject(dict_type_string_page.Get()));
auto dict_type_name_font = pdfium::MakeRetain<CPDF_Dictionary>();
dict_type_name_font->SetNewFor<CPDF_Name>("Type", "Font");
- EXPECT_FALSE(CPDF_Document::IsValidPageObject(
- document.AddIndirectObject(dict_type_name_font)));
+ document.AddIndirectObject(dict_type_name_font);
+ EXPECT_FALSE(CPDF_Document::IsValidPageObject(dict_type_name_font.Get()));
auto obj_no_type = document.NewIndirect<CPDF_Dictionary>();
EXPECT_FALSE(CPDF_Document::IsValidPageObject(obj_no_type.Get()));
@@ -254,9 +253,10 @@
CPDF_TestDocumentAllowSetParser document;
{
- CPDF_Object* first_page = document.AddIndirectObject(CreateNumberedPage(0));
- DCHECK(first_page);
- int first_page_obj_num = first_page->GetObjNum();
+ auto first_page = CreateNumberedPage(0);
+ ASSERT_TRUE(first_page);
+
+ int first_page_obj_num = document.AddIndirectObject(first_page);
ASSERT_NE(kTestPageNum, first_page_obj_num);
linearization_dict->SetNewFor<CPDF_Boolean>("Linearized", true);
diff --git a/core/fpdfapi/parser/cpdf_indirect_object_holder.cpp b/core/fpdfapi/parser/cpdf_indirect_object_holder.cpp
index 59d54b9..1012bcb 100644
--- a/core/fpdfapi/parser/cpdf_indirect_object_holder.cpp
+++ b/core/fpdfapi/parser/cpdf_indirect_object_holder.cpp
@@ -84,14 +84,12 @@
return nullptr;
}
-CPDF_Object* CPDF_IndirectObjectHolder::AddIndirectObject(
+uint32_t CPDF_IndirectObjectHolder::AddIndirectObject(
RetainPtr<CPDF_Object> pObj) {
CHECK(!pObj->GetObjNum());
pObj->SetObjNum(++m_LastObjNum);
-
- auto& obj_holder = m_IndirectObjs[m_LastObjNum];
- obj_holder = std::move(pObj);
- return obj_holder.Get();
+ m_IndirectObjs[m_LastObjNum] = std::move(pObj);
+ return m_LastObjNum;
}
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 8cf4c06..3733d48 100644
--- a/core/fpdfapi/parser/cpdf_indirect_object_holder.h
+++ b/core/fpdfapi/parser/cpdf_indirect_object_holder.h
@@ -32,33 +32,31 @@
void DeleteIndirectObject(uint32_t objnum);
// Creates and adds a new object retained by the indirect object holder,
- // and returns a retained pointer to it. We have a special case to
- // handle objects that can intern strings from our ByteStringPool.
+ // and returns a retained pointer to it.
template <typename T, typename... Args>
- typename std::enable_if<!CanInternStrings<T>::value, RetainPtr<T>>::type
- NewIndirect(Args&&... args) {
- return pdfium::WrapRetain(static_cast<T*>(
- AddIndirectObject(pdfium::MakeRetain<T>(std::forward<Args>(args)...))));
- }
- template <typename T, typename... Args>
- typename std::enable_if<CanInternStrings<T>::value, RetainPtr<T>>::type
- NewIndirect(Args&&... args) {
- return pdfium::WrapRetain(
- static_cast<T*>(AddIndirectObject(pdfium::MakeRetain<T>(
- m_pByteStringPool, std::forward<Args>(args)...))));
+ RetainPtr<T> NewIndirect(Args&&... args) {
+ auto obj = New<T>(std::forward<Args>(args)...);
+ AddIndirectObject(obj);
+ return obj;
}
// Creates and adds a new object not retained by the indirect object holder,
- // but which can intern strings from it.
+ // but which can intern strings from it. We have a special cast to handle
+ // objects that can intern strings from our ByteStringPool.
template <typename T, typename... Args>
typename std::enable_if<CanInternStrings<T>::value, RetainPtr<T>>::type New(
Args&&... args) {
return pdfium::MakeRetain<T>(m_pByteStringPool,
std::forward<Args>(args)...);
}
+ template <typename T, typename... Args>
+ typename std::enable_if<!CanInternStrings<T>::value, RetainPtr<T>>::type New(
+ Args&&... args) {
+ return pdfium::MakeRetain<T>(std::forward<Args>(args)...);
+ }
- // Retains |pObj|, returns unowned pointer to it.
- CPDF_Object* AddIndirectObject(RetainPtr<CPDF_Object> pObj);
+ // Always Retains |pObj|, returns its new object number.
+ uint32_t AddIndirectObject(RetainPtr<CPDF_Object> pObj);
// If higher generation number, retains |pObj| and returns true.
bool ReplaceIndirectObjectIfHigherGeneration(uint32_t objnum,
diff --git a/core/fpdfapi/parser/cpdf_object_unittest.cpp b/core/fpdfapi/parser/cpdf_object_unittest.cpp
index 16208c4..76d9c08 100644
--- a/core/fpdfapi/parser/cpdf_object_unittest.cpp
+++ b/core/fpdfapi/parser/cpdf_object_unittest.cpp
@@ -99,16 +99,17 @@
// Indirect references to indirect objects.
m_ObjHolder = std::make_unique<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(pdfium::MakeRetain<CPDF_Reference>(
- m_ObjHolder.get(), pObj->GetObjNum()));
+ m_IndirectObjNums = {
+ 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 (uint32_t objnum : m_IndirectObjNums) {
+ m_RefObjs.emplace_back(
+ pdfium::MakeRetain<CPDF_Reference>(m_ObjHolder.get(), objnum));
}
}
@@ -194,7 +195,7 @@
RetainPtr<CPDF_Dictionary> m_DictObj;
RetainPtr<CPDF_Dictionary> m_StreamDictObj;
RetainPtr<CPDF_Array> m_ArrayObj;
- std::vector<CPDF_Object*> m_IndirectObjs;
+ std::vector<uint32_t> m_IndirectObjNums;
};
TEST_F(PDFObjectsTest, GetString) {
@@ -336,7 +337,7 @@
// Check indirect references.
for (size_t i = 0; i < m_RefObjs.size(); ++i)
- EXPECT_EQ(m_IndirectObjs[i], m_RefObjs[i]->GetDirect());
+ EXPECT_EQ(m_IndirectObjNums[i], m_RefObjs[i]->GetDirect()->GetObjNum());
}
TEST_F(PDFObjectsTest, SetString) {
diff --git a/fpdfsdk/fpdf_ppo.cpp b/fpdfsdk/fpdf_ppo.cpp
index 832826a..72c76b4 100644
--- a/fpdfsdk/fpdf_ppo.cpp
+++ b/fpdfsdk/fpdf_ppo.cpp
@@ -358,11 +358,9 @@
return 0;
}
- RetainPtr<CPDF_Object> pIndirectClone(
- dest()->AddIndirectObject(std::move(pClone)));
- dwNewObjNum = pIndirectClone->GetObjNum();
+ dwNewObjNum = dest()->AddIndirectObject(pClone);
AddObjectMapping(dwObjnum, dwNewObjNum);
- if (!UpdateReference(std::move(pIndirectClone)))
+ if (!UpdateReference(std::move(pClone)))
return 0;
return dwNewObjNum;