Retain CPDF_Dictionary in CPDF_LinkList::m_PageMap Because we can. There isn't any indication that there is a path to free the underlying dictionary, but holding an additional reference to it won't hurt since there are no cycles. Change-Id: If26bb1f38fcbb6e636afcea5d60789821d506571 Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/78950 Reviewed-by: Lei Zhang <thestig@chromium.org> Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fpdfdoc/cpdf_linklist.cpp b/core/fpdfdoc/cpdf_linklist.cpp index 746bbab..cb7ca0e 100644 --- a/core/fpdfdoc/cpdf_linklist.cpp +++ b/core/fpdfdoc/cpdf_linklist.cpp
@@ -14,7 +14,7 @@ CPDF_LinkList::~CPDF_LinkList() = default; -const std::vector<CPDF_Dictionary*>* CPDF_LinkList::GetPageLinks( +const std::vector<RetainPtr<CPDF_Dictionary>>* CPDF_LinkList::GetPageLinks( CPDF_Page* pPage) { uint32_t objnum = pPage->GetDict()->GetObjNum(); if (objnum == 0) @@ -25,7 +25,7 @@ return &it->second; // std::map::operator[] forces the creation of a map entry. - std::vector<CPDF_Dictionary*>& page_link_list = m_PageMap[objnum]; + auto& page_link_list = m_PageMap[objnum]; LoadPageLinks(pPage, &page_link_list); return &page_link_list; } @@ -33,13 +33,14 @@ CPDF_Link CPDF_LinkList::GetLinkAtPoint(CPDF_Page* pPage, const CFX_PointF& point, int* z_order) { - const std::vector<CPDF_Dictionary*>* pPageLinkList = GetPageLinks(pPage); + const std::vector<RetainPtr<CPDF_Dictionary>>* pPageLinkList = + GetPageLinks(pPage); if (!pPageLinkList) return CPDF_Link(); for (size_t i = pPageLinkList->size(); i > 0; --i) { size_t annot_index = i - 1; - CPDF_Dictionary* pAnnot = (*pPageLinkList)[annot_index]; + CPDF_Dictionary* pAnnot = (*pPageLinkList)[annot_index].Get(); if (!pAnnot) continue; @@ -54,8 +55,9 @@ return CPDF_Link(); } -void CPDF_LinkList::LoadPageLinks(CPDF_Page* pPage, - std::vector<CPDF_Dictionary*>* pList) { +void CPDF_LinkList::LoadPageLinks( + CPDF_Page* pPage, + std::vector<RetainPtr<CPDF_Dictionary>>* pList) { CPDF_Array* pAnnotList = pPage->GetDict()->GetArrayFor("Annots"); if (!pAnnotList) return; @@ -64,6 +66,6 @@ CPDF_Dictionary* pAnnot = pAnnotList->GetDictAt(i); bool add_link = (pAnnot && pAnnot->GetStringFor("Subtype") == "Link"); // Add non-links as nullptrs to preserve z-order. - pList->push_back(add_link ? pAnnot : nullptr); + pList->emplace_back(add_link ? pAnnot : nullptr); } }
diff --git a/core/fpdfdoc/cpdf_linklist.h b/core/fpdfdoc/cpdf_linklist.h index 442f66c..32320d0 100644 --- a/core/fpdfdoc/cpdf_linklist.h +++ b/core/fpdfdoc/cpdf_linklist.h
@@ -13,6 +13,7 @@ #include "core/fpdfapi/parser/cpdf_document.h" #include "core/fpdfdoc/cpdf_link.h" #include "core/fxcrt/fx_system.h" +#include "core/fxcrt/retain_ptr.h" class CPDF_Page; class CPDF_Dictionary; @@ -27,10 +28,11 @@ int* z_order); private: - const std::vector<CPDF_Dictionary*>* GetPageLinks(CPDF_Page* pPage); - void LoadPageLinks(CPDF_Page* pPage, std::vector<CPDF_Dictionary*>* pList); + const std::vector<RetainPtr<CPDF_Dictionary>>* GetPageLinks(CPDF_Page* pPage); + void LoadPageLinks(CPDF_Page* pPage, + std::vector<RetainPtr<CPDF_Dictionary>>* pList); - std::map<uint32_t, std::vector<CPDF_Dictionary*>> m_PageMap; + std::map<uint32_t, std::vector<RetainPtr<CPDF_Dictionary>>> m_PageMap; }; #endif // CORE_FPDFDOC_CPDF_LINKLIST_H_