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_