Replace non-const CPDF_Array::Get*At() with GetMutable*At().
Force mutators to hold a retained reference to the object under
mutation, or use const pointers when not mutating. Then return
retained references as needed to satisfy compilation constraint.
First in a series to replace the non-const getter overloads.
Change-Id: I2c7c84f61f36532d13fd31a64033b4a0dacaf77c
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/94490
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fpdfapi/parser/cpdf_array.cpp b/core/fpdfapi/parser/cpdf_array.cpp
index 6aa6f30..bda93d6 100644
--- a/core/fpdfapi/parser/cpdf_array.cpp
+++ b/core/fpdfapi/parser/cpdf_array.cpp
@@ -155,18 +155,7 @@
}
RetainPtr<CPDF_Dictionary> CPDF_Array::GetMutableDictAt(size_t index) {
- return pdfium::WrapRetain(GetDictAt(index));
-}
-
-CPDF_Dictionary* CPDF_Array::GetDictAt(size_t index) {
- CPDF_Object* p = GetDirectObjectAt(index);
- if (!p)
- return nullptr;
- if (CPDF_Dictionary* pDict = p->AsDictionary())
- return pDict;
- if (CPDF_Stream* pStream = p->AsStream())
- return pStream->GetDict();
- return nullptr;
+ return pdfium::WrapRetain(const_cast<CPDF_Dictionary*>(GetDictAt(index)));
}
const CPDF_Dictionary* CPDF_Array::GetDictAt(size_t index) const {
@@ -180,16 +169,16 @@
return nullptr;
}
-CPDF_Stream* CPDF_Array::GetStreamAt(size_t index) {
- return ToStream(GetDirectObjectAt(index));
+RetainPtr<CPDF_Stream> CPDF_Array::GetMutableStreamAt(size_t index) {
+ return pdfium::WrapRetain(const_cast<CPDF_Stream*>(GetStreamAt(index)));
}
const CPDF_Stream* CPDF_Array::GetStreamAt(size_t index) const {
return ToStream(GetDirectObjectAt(index));
}
-CPDF_Array* CPDF_Array::GetArrayAt(size_t index) {
- return ToArray(GetDirectObjectAt(index));
+RetainPtr<CPDF_Array> CPDF_Array::GetMutableArrayAt(size_t index) {
+ return pdfium::WrapRetain(const_cast<CPDF_Array*>(GetArrayAt(index)));
}
const CPDF_Array* CPDF_Array::GetArrayAt(size_t index) const {
diff --git a/core/fpdfapi/parser/cpdf_array.h b/core/fpdfapi/parser/cpdf_array.h
index 223cd59..e039cd7 100644
--- a/core/fpdfapi/parser/cpdf_array.h
+++ b/core/fpdfapi/parser/cpdf_array.h
@@ -63,11 +63,10 @@
int GetIntegerAt(size_t index) const;
float GetNumberAt(size_t index) const;
RetainPtr<CPDF_Dictionary> GetMutableDictAt(size_t index);
- CPDF_Dictionary* GetDictAt(size_t index); // prefer previous form.
const CPDF_Dictionary* GetDictAt(size_t index) const;
- CPDF_Stream* GetStreamAt(size_t index);
+ RetainPtr<CPDF_Stream> GetMutableStreamAt(size_t index);
const CPDF_Stream* GetStreamAt(size_t index) const;
- CPDF_Array* GetArrayAt(size_t index);
+ RetainPtr<CPDF_Array> GetMutableArrayAt(size_t index);
const CPDF_Array* GetArrayAt(size_t index) const;
CFX_FloatRect GetRect() const;
diff --git a/core/fpdfapi/parser/cpdf_document.cpp b/core/fpdfapi/parser/cpdf_document.cpp
index 44fa2a1..e493fdc 100644
--- a/core/fpdfapi/parser/cpdf_document.cpp
+++ b/core/fpdfapi/parser/cpdf_document.cpp
@@ -37,13 +37,13 @@
return 0;
count = 0;
for (size_t i = 0; i < pKidList->size(); i++) {
- CPDF_Dictionary* pKid = pKidList->GetDictAt(i);
- if (!pKid || pdfium::Contains(*visited_pages, pKid))
+ RetainPtr<CPDF_Dictionary> pKid = pKidList->GetMutableDictAt(i);
+ if (!pKid || pdfium::Contains(*visited_pages, pKid.Get()))
continue;
if (pKid->KeyExist("Kids")) {
// Use |visited_pages| to help detect circular references of pages.
- ScopedSetInsertion<CPDF_Dictionary*> local_add(visited_pages, pKid);
- count += CountPages(pKid, visited_pages);
+ ScopedSetInsertion<CPDF_Dictionary*> local_add(visited_pages, pKid.Get());
+ count += CountPages(pKid.Get(), visited_pages);
} else {
// This page is a leaf node.
count++;
@@ -202,12 +202,12 @@
m_bReachedMaxPageLevel = true;
return nullptr;
}
- CPDF_Dictionary* page = nullptr;
+ RetainPtr<CPDF_Dictionary> page;
for (size_t i = m_pTreeTraversal[level].second; i < pKidList->size(); i++) {
if (*nPagesToGo == 0)
break;
pKidList->ConvertToIndirectObjectAt(i, this);
- CPDF_Dictionary* pKid = pKidList->GetDictAt(i);
+ RetainPtr<CPDF_Dictionary> pKid = pKidList->GetMutableDictAt(i);
if (!pKid) {
(*nPagesToGo)--;
m_pTreeTraversal[level].second++;
@@ -228,7 +228,7 @@
} else {
// If the vector has size level+1, the child is not in yet
if (m_pTreeTraversal.size() == level + 1)
- m_pTreeTraversal.push_back(std::make_pair(pKid, 0));
+ m_pTreeTraversal.push_back(std::make_pair(pKid.Get(), 0));
// Now m_pTreeTraversal[level+1] should exist and be equal to pKid.
CPDF_Dictionary* pageKid = TraversePDFPages(iPage, nPagesToGo, level + 1);
// Check if child was completely processed, i.e. it popped itself out
@@ -244,7 +244,7 @@
}
if (m_pTreeTraversal[level].second == pKidList->size())
m_pTreeTraversal.pop_back();
- return page;
+ return page.Get();
}
void CPDF_Document::ResetTraversal() {
@@ -411,7 +411,7 @@
return false;
for (size_t i = 0; i < pKidList->size(); i++) {
- CPDF_Dictionary* pKid = pKidList->GetDictAt(i);
+ RetainPtr<CPDF_Dictionary> pKid = pKidList->GetMutableDictAt(i);
if (pKid->GetNameFor("Type") == "Page") {
if (nPagesToGo != 0) {
nPagesToGo--;
@@ -437,10 +437,11 @@
if (pdfium::Contains(*pVisited, pKid))
return false;
- ScopedSetInsertion<CPDF_Dictionary*> insertion(pVisited, pKid);
- if (!InsertDeletePDFPage(pKid, nPagesToGo, pPageDict, bInsert, pVisited))
+ ScopedSetInsertion<CPDF_Dictionary*> insertion(pVisited, pKid.Get());
+ if (!InsertDeletePDFPage(pKid.Get(), nPagesToGo, pPageDict, bInsert,
+ pVisited)) {
return false;
-
+ }
pPages->SetNewFor<CPDF_Number>(
"Count", pPages->GetIntegerFor("Count") + (bInsert ? 1 : -1));
break;
diff --git a/core/fpdfapi/parser/cpdf_document_unittest.cpp b/core/fpdfapi/parser/cpdf_document_unittest.cpp
index 306e043..cc6e100 100644
--- a/core/fpdfapi/parser/cpdf_document_unittest.cpp
+++ b/core/fpdfapi/parser/cpdf_document_unittest.cpp
@@ -34,8 +34,8 @@
pageNode->SetNewFor<CPDF_Reference>("Kids", pDoc, pUnowned->GetObjNum());
pageNode->SetNewFor<CPDF_Number>("Count", count);
for (size_t i = 0; i < pUnowned->size(); i++) {
- pUnowned->GetDictAt(i)->SetNewFor<CPDF_Reference>("Parent", pDoc,
- pageNode->GetObjNum());
+ pUnowned->GetMutableDictAt(i)->SetNewFor<CPDF_Reference>(
+ "Parent", pDoc, pageNode->GetObjNum());
}
return pageNode;
}
diff --git a/core/fpdfdoc/cpdf_interactiveform.cpp b/core/fpdfdoc/cpdf_interactiveform.cpp
index b7bb38e..98971e3 100644
--- a/core/fpdfdoc/cpdf_interactiveform.cpp
+++ b/core/fpdfdoc/cpdf_interactiveform.cpp
@@ -540,7 +540,7 @@
return;
for (size_t i = 0; i < pFields->size(); ++i)
- LoadField(pFields->GetDictAt(i), 0);
+ LoadField(pFields->GetMutableDictAt(i).Get(), 0);
}
CPDF_InteractiveForm::~CPDF_InteractiveForm() = default;
@@ -766,10 +766,10 @@
if (pFirstKid->KeyExist(pdfium::form_fields::kT) ||
pFirstKid->KeyExist(pdfium::form_fields::kKids)) {
for (size_t i = 0; i < pKids->size(); i++) {
- CPDF_Dictionary* pChildDict = pKids->GetDictAt(i);
+ RetainPtr<CPDF_Dictionary> pChildDict = pKids->GetMutableDictAt(i);
if (pChildDict) {
if (pChildDict->GetObjNum() != dwParentObjNum)
- LoadField(pChildDict, nLevel + 1);
+ LoadField(pChildDict.Get(), nLevel + 1);
}
}
} else {
@@ -783,9 +783,9 @@
return;
for (size_t i = 0; i < pAnnots->size(); i++) {
- CPDF_Dictionary* pAnnot = pAnnots->GetDictAt(i);
+ RetainPtr<CPDF_Dictionary> pAnnot = pAnnots->GetMutableDictAt(i);
if (pAnnot && pAnnot->GetNameFor("Subtype") == "Widget")
- LoadField(pAnnot, 0);
+ LoadField(pAnnot.Get(), 0);
}
}
@@ -848,9 +848,9 @@
CPDF_Array* pKids = pFieldDict->GetArrayFor(pdfium::form_fields::kKids);
if (pKids) {
for (size_t i = 0; i < pKids->size(); i++) {
- CPDF_Dictionary* pKid = pKids->GetDictAt(i);
+ RetainPtr<CPDF_Dictionary> pKid = pKids->GetMutableDictAt(i);
if (pKid && pKid->GetNameFor("Subtype") == "Widget")
- AddControl(pField, pKid);
+ AddControl(pField, pKid.Get());
}
} else {
if (pFieldDict->GetNameFor("Subtype") == "Widget")
diff --git a/core/fpdfdoc/cpdf_linklist.cpp b/core/fpdfdoc/cpdf_linklist.cpp
index 23b324e..568e363 100644
--- a/core/fpdfdoc/cpdf_linklist.cpp
+++ b/core/fpdfdoc/cpdf_linklist.cpp
@@ -57,7 +57,7 @@
return page_link_list;
for (size_t i = 0; i < pAnnotList->size(); ++i) {
- CPDF_Dictionary* pAnnot = pAnnotList->GetDictAt(i);
+ RetainPtr<CPDF_Dictionary> pAnnot = pAnnotList->GetMutableDictAt(i);
bool add_link = (pAnnot && pAnnot->GetStringFor("Subtype") == "Link");
// Add non-links as nullptrs to preserve z-order.
page_link_list->emplace_back(add_link ? pAnnot : nullptr);
diff --git a/core/fpdfdoc/cpdf_nametree.cpp b/core/fpdfdoc/cpdf_nametree.cpp
index e818e1c..539b0fd 100644
--- a/core/fpdfdoc/cpdf_nametree.cpp
+++ b/core/fpdfdoc/cpdf_nametree.cpp
@@ -130,12 +130,13 @@
// Loop through the kids to find the leaf array |pFind|.
for (size_t i = 0; i < pKids->size(); ++i) {
- CPDF_Dictionary* pKid = pKids->GetDictAt(i);
+ RetainPtr<CPDF_Dictionary> pKid = pKids->GetMutableDictAt(i);
if (!pKid)
continue;
- if (!UpdateNodesAndLimitsUponDeletion(pKid, pFind, csName, nLevel + 1))
+ if (!UpdateNodesAndLimitsUponDeletion(pKid.Get(), pFind, csName,
+ nLevel + 1)) {
continue;
-
+ }
// Remove this child node if it's empty.
if ((pKid->KeyExist("Names") && pKid->GetArrayFor("Names")->IsEmpty()) ||
(pKid->KeyExist("Kids") && pKid->GetArrayFor("Kids")->IsEmpty())) {
@@ -300,11 +301,11 @@
return absl::nullopt;
for (size_t i = 0; i < pKids->size(); i++) {
- CPDF_Dictionary* pKid = pKids->GetDictAt(i);
+ RetainPtr<CPDF_Dictionary> pKid = pKids->GetMutableDictAt(i);
if (!pKid)
continue;
absl::optional<IndexSearchResult> result = SearchNameNodeByIndexInternal(
- pKid, nTargetPairIndex, nLevel + 1, nCurPairIndex);
+ pKid.Get(), nTargetPairIndex, nLevel + 1, nCurPairIndex);
if (result.has_value())
return result;
}
diff --git a/core/fpdfdoc/cpdf_nametree_unittest.cpp b/core/fpdfdoc/cpdf_nametree_unittest.cpp
index 36617e7..3b9fa3b 100644
--- a/core/fpdfdoc/cpdf_nametree_unittest.cpp
+++ b/core/fpdfdoc/cpdf_nametree_unittest.cpp
@@ -130,9 +130,11 @@
// elements.
auto pRootDict = pdfium::MakeRetain<CPDF_Dictionary>();
FillNameTreeDict(pRootDict.Get());
- CPDF_Dictionary* pKid1 = pRootDict->GetArrayFor("Kids")->GetDictAt(0);
- CPDF_Dictionary* pGrandKid3 = pKid1->GetArrayFor("Kids")->GetDictAt(1);
- CPDF_Array* pLimits = pGrandKid3->GetArrayFor("Limits");
+ RetainPtr<CPDF_Dictionary> pKid1 =
+ pRootDict->GetArrayFor("Kids")->GetMutableDictAt(0);
+ RetainPtr<CPDF_Dictionary> pGrandKid3 =
+ pKid1->GetArrayFor("Kids")->GetMutableDictAt(1);
+ RetainPtr<CPDF_Array> pLimits = pGrandKid3->GetMutableArrayFor("Limits");
ASSERT_EQ(2u, pLimits->size());
pLimits->AppendNew<CPDF_Number>(5);
pLimits->AppendNew<CPDF_Number>(6);
@@ -143,8 +145,8 @@
const CPDF_Number* pNumber = ToNumber(name_tree->LookupValue(L"9.txt"));
ASSERT_TRUE(pNumber);
EXPECT_EQ(999, pNumber->GetInteger());
- CheckLimitsArray(pKid1, "1.txt", "9.txt");
- CheckLimitsArray(pGrandKid3, "9.txt", "9.txt");
+ CheckLimitsArray(pKid1.Get(), "1.txt", "9.txt");
+ CheckLimitsArray(pGrandKid3.Get(), "9.txt", "9.txt");
}
TEST(cpdf_nametree, AddIntoNames) {