Store retained object keys in all CPDF_DocPageData maps.

Then propagate changes to callers as necessary,

Change-Id: I8dc79f86e85e5015703ed3f1a4a49df219be5535
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/98235
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/edit/cpdf_creator.cpp b/core/fpdfapi/edit/cpdf_creator.cpp
index 76c9e93..641afff 100644
--- a/core/fpdfapi/edit/cpdf_creator.cpp
+++ b/core/fpdfapi/edit/cpdf_creator.cpp
@@ -564,7 +564,8 @@
   DCHECK(!m_pIDArray);
 
   m_pIDArray = pdfium::MakeRetain<CPDF_Array>();
-  const CPDF_Array* pOldIDArray = m_pParser ? m_pParser->GetIDArray() : nullptr;
+  RetainPtr<const CPDF_Array> pOldIDArray =
+      m_pParser ? m_pParser->GetIDArray() : nullptr;
   RetainPtr<const CPDF_Object> pID1 =
       pOldIDArray ? pOldIDArray->GetObjectAt(0) : nullptr;
   if (pID1) {
diff --git a/core/fpdfapi/page/cpdf_colorspace.cpp b/core/fpdfapi/page/cpdf_colorspace.cpp
index e0a56c1..89cb55a 100644
--- a/core/fpdfapi/page/cpdf_colorspace.cpp
+++ b/core/fpdfapi/page/cpdf_colorspace.cpp
@@ -907,8 +907,7 @@
     return 0;
 
   uint32_t nComponents = static_cast<uint32_t>(nDictComponents);
-  m_pProfile =
-      CPDF_DocPageData::FromDocument(pDoc)->GetIccProfile(pStream.Get());
+  m_pProfile = CPDF_DocPageData::FromDocument(pDoc)->GetIccProfile(pStream);
   if (!m_pProfile)
     return 0;
 
diff --git a/core/fpdfapi/page/cpdf_docpagedata.cpp b/core/fpdfapi/page/cpdf_docpagedata.cpp
index 4b0277247..7ff7952 100644
--- a/core/fpdfapi/page/cpdf_docpagedata.cpp
+++ b/core/fpdfapi/page/cpdf_docpagedata.cpp
@@ -182,7 +182,7 @@
   if (!pFontDict)
     return nullptr;
 
-  auto it = m_FontMap.find(pFontDict.Get());
+  auto it = m_FontMap.find(pFontDict);
   if (it != m_FontMap.end() && it->second)
     return pdfium::WrapRetain(it->second.Get());
 
@@ -191,7 +191,7 @@
   if (!pFont)
     return nullptr;
 
-  m_FontMap[pFontDict.Get()].Reset(pFont.Get());
+  m_FontMap[std::move(pFontDict)].Reset(pFont.Get());
   return pFont;
 }
 
@@ -235,7 +235,7 @@
   if (!pFont)
     return nullptr;
 
-  m_FontMap[pDict.Get()].Reset(pFont.Get());
+  m_FontMap[std::move(pDict)].Reset(pFont.Get());
   return pFont;
 }
 
@@ -307,7 +307,7 @@
                                  pVisitedInternal);
   }
 
-  const CPDF_Array* pArray = pCSObj->AsArray();
+  RetainPtr<const CPDF_Array> pArray(pCSObj->AsArray());
   if (!pArray || pArray->IsEmpty())
     return nullptr;
 
@@ -316,21 +316,22 @@
                                  pVisited, pVisitedInternal);
   }
 
-  auto it = m_ColorSpaceMap.find(pCSObj);
+  auto it = m_ColorSpaceMap.find(pArray);
   if (it != m_ColorSpaceMap.end() && it->second)
     return pdfium::WrapRetain(it->second.Get());
 
   RetainPtr<CPDF_ColorSpace> pCS =
-      CPDF_ColorSpace::Load(GetDocument(), pArray, pVisited);
+      CPDF_ColorSpace::Load(GetDocument(), pArray.Get(), pVisited);
   if (!pCS)
     return nullptr;
 
-  m_ColorSpaceMap[pCSObj].Reset(pCS.Get());
+  m_ColorSpaceMap[std::move(pArray)].Reset(pCS.Get());
   return pCS;
 }
 
-RetainPtr<CPDF_Pattern> CPDF_DocPageData::GetPattern(CPDF_Object* pPatternObj,
-                                                     const CFX_Matrix& matrix) {
+RetainPtr<CPDF_Pattern> CPDF_DocPageData::GetPattern(
+    RetainPtr<CPDF_Object> pPatternObj,
+    const CFX_Matrix& matrix) {
   if (!pPatternObj)
     return nullptr;
 
@@ -358,7 +359,7 @@
 }
 
 RetainPtr<CPDF_ShadingPattern> CPDF_DocPageData::GetShading(
-    CPDF_Object* pPatternObj,
+    RetainPtr<CPDF_Object> pPatternObj,
     const CFX_Matrix& matrix) {
   if (!pPatternObj)
     return nullptr;
@@ -392,7 +393,7 @@
 }
 
 RetainPtr<CPDF_IccProfile> CPDF_DocPageData::GetIccProfile(
-    const CPDF_Stream* pProfileStream) {
+    RetainPtr<const CPDF_Stream> pProfileStream) {
   if (!pProfileStream)
     return nullptr;
 
@@ -400,21 +401,20 @@
   if (it != m_IccProfileMap.end() && it->second)
     return pdfium::WrapRetain(it->second.Get());
 
-  auto pAccessor =
-      pdfium::MakeRetain<CPDF_StreamAcc>(pdfium::WrapRetain(pProfileStream));
+  auto pAccessor = pdfium::MakeRetain<CPDF_StreamAcc>(pProfileStream);
   pAccessor->LoadAllDataFiltered();
 
   ByteString bsDigest = pAccessor->ComputeDigest();
   auto hash_it = m_HashProfileMap.find(bsDigest);
   if (hash_it != m_HashProfileMap.end()) {
-    auto it_copied_stream = m_IccProfileMap.find(hash_it->second.Get());
+    auto it_copied_stream = m_IccProfileMap.find(hash_it->second);
     if (it_copied_stream != m_IccProfileMap.end() && it_copied_stream->second)
       return pdfium::WrapRetain(it_copied_stream->second.Get());
   }
   auto pProfile =
       pdfium::MakeRetain<CPDF_IccProfile>(pProfileStream, pAccessor->GetSpan());
   m_IccProfileMap[pProfileStream].Reset(pProfile.Get());
-  m_HashProfileMap[bsDigest].Reset(pProfileStream);
+  m_HashProfileMap[bsDigest] = std::move(pProfileStream);
   return pProfile;
 }
 
diff --git a/core/fpdfapi/page/cpdf_docpagedata.h b/core/fpdfapi/page/cpdf_docpagedata.h
index d6fbb52..8767392 100644
--- a/core/fpdfapi/page/cpdf_docpagedata.h
+++ b/core/fpdfapi/page/cpdf_docpagedata.h
@@ -76,15 +76,16 @@
       const CPDF_Dictionary* pResources,
       std::set<const CPDF_Object*>* pVisited);
 
-  RetainPtr<CPDF_Pattern> GetPattern(CPDF_Object* pPatternObj,
+  RetainPtr<CPDF_Pattern> GetPattern(RetainPtr<CPDF_Object> pPatternObj,
                                      const CFX_Matrix& matrix);
-  RetainPtr<CPDF_ShadingPattern> GetShading(CPDF_Object* pPatternObj,
+  RetainPtr<CPDF_ShadingPattern> GetShading(RetainPtr<CPDF_Object> pPatternObj,
                                             const CFX_Matrix& matrix);
 
   RetainPtr<CPDF_Image> GetImage(uint32_t dwStreamObjNum);
   void MaybePurgeImage(uint32_t dwStreamObjNum);
 
-  RetainPtr<CPDF_IccProfile> GetIccProfile(const CPDF_Stream* pProfileStream);
+  RetainPtr<CPDF_IccProfile> GetIccProfile(
+      RetainPtr<const CPDF_Stream> pProfileStream);
 
  private:
   // Loads a colorspace in a context that might be while loading another
@@ -109,13 +110,16 @@
 
   // Specific destruction order may be required between maps.
   std::map<ByteString, RetainPtr<const CPDF_Stream>> m_HashProfileMap;
-  std::map<const CPDF_Object*, ObservedPtr<CPDF_ColorSpace>> m_ColorSpaceMap;
+  std::map<RetainPtr<const CPDF_Array>, ObservedPtr<CPDF_ColorSpace>>
+      m_ColorSpaceMap;
   std::map<RetainPtr<const CPDF_Stream>, RetainPtr<CPDF_StreamAcc>>
       m_FontFileMap;
-  std::map<const CPDF_Stream*, ObservedPtr<CPDF_IccProfile>> m_IccProfileMap;
-  std::map<const CPDF_Object*, ObservedPtr<CPDF_Pattern>> m_PatternMap;
+  std::map<RetainPtr<const CPDF_Stream>, ObservedPtr<CPDF_IccProfile>>
+      m_IccProfileMap;
+  std::map<RetainPtr<const CPDF_Object>, ObservedPtr<CPDF_Pattern>>
+      m_PatternMap;
   std::map<uint32_t, RetainPtr<CPDF_Image>> m_ImageMap;
-  std::map<const CPDF_Dictionary*, ObservedPtr<CPDF_Font>> m_FontMap;
+  std::map<RetainPtr<const CPDF_Dictionary>, ObservedPtr<CPDF_Font>> m_FontMap;
 };
 
 #endif  // CORE_FPDFAPI_PAGE_CPDF_DOCPAGEDATA_H_
diff --git a/core/fpdfapi/page/cpdf_iccprofile.cpp b/core/fpdfapi/page/cpdf_iccprofile.cpp
index 8f335cc..4a4988f 100644
--- a/core/fpdfapi/page/cpdf_iccprofile.cpp
+++ b/core/fpdfapi/page/cpdf_iccprofile.cpp
@@ -6,6 +6,8 @@
 
 #include "core/fpdfapi/page/cpdf_iccprofile.h"
 
+#include <utility>
+
 #include "core/fpdfapi/parser/cpdf_stream.h"
 #include "core/fxcodec/icc/icc_transform.h"
 
@@ -18,9 +20,9 @@
 
 }  // namespace
 
-CPDF_IccProfile::CPDF_IccProfile(const CPDF_Stream* pStream,
+CPDF_IccProfile::CPDF_IccProfile(RetainPtr<const CPDF_Stream> pStream,
                                  pdfium::span<const uint8_t> span)
-    : m_bsRGB(DetectSRGB(span)), m_pStream(pStream) {
+    : m_bsRGB(DetectSRGB(span)), m_pStream(std::move(pStream)) {
   if (m_bsRGB) {
     m_nSrcComponents = 3;
     return;
diff --git a/core/fpdfapi/page/cpdf_iccprofile.h b/core/fpdfapi/page/cpdf_iccprofile.h
index 5db7b06..3ff9421 100644
--- a/core/fpdfapi/page/cpdf_iccprofile.h
+++ b/core/fpdfapi/page/cpdf_iccprofile.h
@@ -39,7 +39,8 @@
 
  private:
   // Keeps stream alive for the duration of the CPDF_IccProfile.
-  CPDF_IccProfile(const CPDF_Stream* pStream, pdfium::span<const uint8_t> span);
+  CPDF_IccProfile(RetainPtr<const CPDF_Stream> pStream,
+                  pdfium::span<const uint8_t> span);
   ~CPDF_IccProfile() override;
 
   const bool m_bsRGB;
diff --git a/core/fpdfapi/page/cpdf_pattern.cpp b/core/fpdfapi/page/cpdf_pattern.cpp
index 5477b06..ce7c767 100644
--- a/core/fpdfapi/page/cpdf_pattern.cpp
+++ b/core/fpdfapi/page/cpdf_pattern.cpp
@@ -6,13 +6,17 @@
 
 #include "core/fpdfapi/page/cpdf_pattern.h"
 
+#include <utility>
+
 #include "core/fpdfapi/parser/cpdf_dictionary.h"
 #include "third_party/base/check.h"
 
 CPDF_Pattern::CPDF_Pattern(CPDF_Document* pDoc,
-                           CPDF_Object* pObj,
+                           RetainPtr<CPDF_Object> pObj,
                            const CFX_Matrix& parentMatrix)
-    : m_pDocument(pDoc), m_pPatternObj(pObj), m_ParentMatrix(parentMatrix) {
+    : m_pDocument(pDoc),
+      m_pPatternObj(std::move(pObj)),
+      m_ParentMatrix(parentMatrix) {
   DCHECK(m_pDocument);
   DCHECK(m_pPatternObj);
 }
diff --git a/core/fpdfapi/page/cpdf_pattern.h b/core/fpdfapi/page/cpdf_pattern.h
index f455f77..36d64ad 100644
--- a/core/fpdfapi/page/cpdf_pattern.h
+++ b/core/fpdfapi/page/cpdf_pattern.h
@@ -35,7 +35,7 @@
 
  protected:
   CPDF_Pattern(CPDF_Document* pDoc,
-               CPDF_Object* pObj,
+               RetainPtr<CPDF_Object> pObj,
                const CFX_Matrix& parentMatrix);
 
   void SetPatternToFormMatrix();
diff --git a/core/fpdfapi/page/cpdf_shadingpattern.cpp b/core/fpdfapi/page/cpdf_shadingpattern.cpp
index e58c88b..aa73f5d 100644
--- a/core/fpdfapi/page/cpdf_shadingpattern.cpp
+++ b/core/fpdfapi/page/cpdf_shadingpattern.cpp
@@ -7,6 +7,7 @@
 #include "core/fpdfapi/page/cpdf_shadingpattern.h"
 
 #include <algorithm>
+#include <utility>
 
 #include "core/fpdfapi/page/cpdf_docpagedata.h"
 #include "core/fpdfapi/page/cpdf_function.h"
@@ -30,10 +31,11 @@
 }  // namespace
 
 CPDF_ShadingPattern::CPDF_ShadingPattern(CPDF_Document* pDoc,
-                                         CPDF_Object* pPatternObj,
+                                         RetainPtr<CPDF_Object> pPatternObj,
                                          bool bShading,
                                          const CFX_Matrix& parentMatrix)
-    : CPDF_Pattern(pDoc, pPatternObj, parentMatrix), m_bShading(bShading) {
+    : CPDF_Pattern(pDoc, std::move(pPatternObj), parentMatrix),
+      m_bShading(bShading) {
   DCHECK(document());
   if (!bShading)
     SetPatternToFormMatrix();
diff --git a/core/fpdfapi/page/cpdf_shadingpattern.h b/core/fpdfapi/page/cpdf_shadingpattern.h
index 4e5608b..2a99d4e 100644
--- a/core/fpdfapi/page/cpdf_shadingpattern.h
+++ b/core/fpdfapi/page/cpdf_shadingpattern.h
@@ -62,7 +62,7 @@
 
  private:
   CPDF_ShadingPattern(CPDF_Document* pDoc,
-                      CPDF_Object* pPatternObj,
+                      RetainPtr<CPDF_Object> pPatternObj,
                       bool bShading,
                       const CFX_Matrix& parentMatrix);
   CPDF_ShadingPattern(const CPDF_ShadingPattern&) = delete;
diff --git a/core/fpdfapi/page/cpdf_streamcontentparser.cpp b/core/fpdfapi/page/cpdf_streamcontentparser.cpp
index 0094d40..89e8692 100644
--- a/core/fpdfapi/page/cpdf_streamcontentparser.cpp
+++ b/core/fpdfapi/page/cpdf_streamcontentparser.cpp
@@ -586,10 +586,11 @@
 
   if (pProperty->IsName()) {
     ByteString property_name = pProperty->GetString();
-    CPDF_Dictionary* pHolder = FindResourceHolder("Properties");
+    RetainPtr<CPDF_Dictionary> pHolder = FindResourceHolder("Properties");
     if (!pHolder || !pHolder->GetDictFor(property_name))
       return;
-    new_marks->AddMarkWithPropertiesHolder(tag, pHolder, property_name);
+    // TODO(tsepez): pass retained argument.
+    new_marks->AddMarkWithPropertiesHolder(tag, pHolder.Get(), property_name);
   } else if (pProperty->IsDictionary()) {
     new_marks->AddMarkWithDirectDict(tag, pProperty->AsMutableDictionary());
   } else {
@@ -629,7 +630,7 @@
     if (pCSObj->IsName()) {
       ByteString name = pCSObj->GetString();
       if (name != "DeviceRGB" && name != "DeviceGray" && name != "DeviceCMYK") {
-        pCSObj.Reset(FindResourceObj("ColorSpace", name));
+        pCSObj = FindResourceObj("ColorSpace", name);
         if (pCSObj && pCSObj->IsInline())
           pDict->SetFor("ColorSpace", pCSObj->Clone());
       }
@@ -886,11 +887,12 @@
 
 void CPDF_StreamContentParser::Handle_SetExtendGraphState() {
   ByteString name = GetString(0);
-  CPDF_Dictionary* pGS = ToDictionary(FindResourceObj("ExtGState", name));
+  RetainPtr<CPDF_Dictionary> pGS =
+      ToDictionary(FindResourceObj("ExtGState", name));
   if (!pGS)
     return;
 
-  m_pCurStates->ProcessExtGS(pGS, this);
+  m_pCurStates->ProcessExtGS(pGS.Get(), this);
 }
 
 void CPDF_StreamContentParser::Handle_ClosePath() {
@@ -1113,26 +1115,26 @@
     m_pCurStates->m_TextState.SetFont(std::move(pFont));
 }
 
-CPDF_Dictionary* CPDF_StreamContentParser::FindResourceHolder(
+RetainPtr<CPDF_Dictionary> CPDF_StreamContentParser::FindResourceHolder(
     const ByteString& type) {
   if (!m_pResources)
     return nullptr;
 
   RetainPtr<CPDF_Dictionary> pDict = m_pResources->GetMutableDictFor(type);
   if (pDict)
-    return pDict.Get();  // TODO(tsepez): return retained and below.
+    return pDict;
 
   if (m_pResources == m_pPageResources || !m_pPageResources)
     return nullptr;
 
-  return m_pPageResources->GetMutableDictFor(type).Get();
+  return m_pPageResources->GetMutableDictFor(type);
 }
 
-// TODO(tsepez): return retained reference.
-CPDF_Object* CPDF_StreamContentParser::FindResourceObj(const ByteString& type,
-                                                       const ByteString& name) {
-  CPDF_Dictionary* pHolder = FindResourceHolder(type);
-  return pHolder ? pHolder->GetMutableDirectObjectFor(name).Get() : nullptr;
+RetainPtr<CPDF_Object> CPDF_StreamContentParser::FindResourceObj(
+    const ByteString& type,
+    const ByteString& name) {
+  RetainPtr<CPDF_Dictionary> pHolder = FindResourceHolder(type);
+  return pHolder ? pHolder->GetMutableDirectObjectFor(name) : nullptr;
 }
 
 RetainPtr<CPDF_Font> CPDF_StreamContentParser::FindFont(
@@ -1160,7 +1162,8 @@
   if (name == "DeviceGray" || name == "DeviceCMYK" || name == "DeviceRGB") {
     ByteString defname = "Default";
     defname += name.Last(name.GetLength() - 7);
-    const CPDF_Object* pDefObj = FindResourceObj("ColorSpace", defname);
+    RetainPtr<const CPDF_Object> pDefObj =
+        FindResourceObj("ColorSpace", defname);
     if (!pDefObj) {
       if (name == "DeviceGray") {
         return CPDF_ColorSpace::GetStockCS(
@@ -1171,32 +1174,33 @@
 
       return CPDF_ColorSpace::GetStockCS(CPDF_ColorSpace::Family::kDeviceCMYK);
     }
+    // TODO(tsepez); pass retained argument.
     return CPDF_DocPageData::FromDocument(m_pDocument.Get())
-        ->GetColorSpace(pDefObj, nullptr);
+        ->GetColorSpace(pDefObj.Get(), nullptr);
   }
-  const CPDF_Object* pCSObj = FindResourceObj("ColorSpace", name);
+  RetainPtr<const CPDF_Object> pCSObj = FindResourceObj("ColorSpace", name);
   if (!pCSObj)
     return nullptr;
   return CPDF_DocPageData::FromDocument(m_pDocument.Get())
-      ->GetColorSpace(pCSObj, nullptr);
+      ->GetColorSpace(pCSObj.Get(), nullptr);
 }
 
 RetainPtr<CPDF_Pattern> CPDF_StreamContentParser::FindPattern(
     const ByteString& name) {
-  CPDF_Object* pPattern = FindResourceObj("Pattern", name);
+  RetainPtr<CPDF_Object> pPattern = FindResourceObj("Pattern", name);
   if (!pPattern || (!pPattern->IsDictionary() && !pPattern->IsStream()))
     return nullptr;
   return CPDF_DocPageData::FromDocument(m_pDocument.Get())
-      ->GetPattern(pPattern, m_pCurStates->m_ParentMatrix);
+      ->GetPattern(std::move(pPattern), m_pCurStates->m_ParentMatrix);
 }
 
 RetainPtr<CPDF_ShadingPattern> CPDF_StreamContentParser::FindShading(
     const ByteString& name) {
-  CPDF_Object* pPattern = FindResourceObj("Shading", name);
+  RetainPtr<CPDF_Object> pPattern = FindResourceObj("Shading", name);
   if (!pPattern || (!pPattern->IsDictionary() && !pPattern->IsStream()))
     return nullptr;
   return CPDF_DocPageData::FromDocument(m_pDocument.Get())
-      ->GetShading(pPattern, m_pCurStates->m_ParentMatrix);
+      ->GetShading(std::move(pPattern), m_pCurStates->m_ParentMatrix);
 }
 
 void CPDF_StreamContentParser::AddTextObject(const ByteString* pStrs,
diff --git a/core/fpdfapi/page/cpdf_streamcontentparser.h b/core/fpdfapi/page/cpdf_streamcontentparser.h
index 09c3587..5409163 100644
--- a/core/fpdfapi/page/cpdf_streamcontentparser.h
+++ b/core/fpdfapi/page/cpdf_streamcontentparser.h
@@ -133,8 +133,9 @@
   RetainPtr<CPDF_ColorSpace> FindColorSpace(const ByteString& name);
   RetainPtr<CPDF_Pattern> FindPattern(const ByteString& name);
   RetainPtr<CPDF_ShadingPattern> FindShading(const ByteString& name);
-  CPDF_Dictionary* FindResourceHolder(const ByteString& type);
-  CPDF_Object* FindResourceObj(const ByteString& type, const ByteString& name);
+  RetainPtr<CPDF_Dictionary> FindResourceHolder(const ByteString& type);
+  RetainPtr<CPDF_Object> FindResourceObj(const ByteString& type,
+                                         const ByteString& name);
 
   // Takes ownership of |pImageObj|, returns unowned pointer to it.
   CPDF_ImageObject* AddImageObject(std::unique_ptr<CPDF_ImageObject> pImageObj);
diff --git a/core/fpdfapi/page/cpdf_tilingpattern.cpp b/core/fpdfapi/page/cpdf_tilingpattern.cpp
index 1fd7fa8..5be1c0b 100644
--- a/core/fpdfapi/page/cpdf_tilingpattern.cpp
+++ b/core/fpdfapi/page/cpdf_tilingpattern.cpp
@@ -8,6 +8,8 @@
 
 #include <math.h>
 
+#include <utility>
+
 #include "core/fpdfapi/page/cpdf_allstates.h"
 #include "core/fpdfapi/page/cpdf_form.h"
 #include "core/fpdfapi/page/cpdf_pageobject.h"
@@ -17,9 +19,9 @@
 #include "third_party/base/check.h"
 
 CPDF_TilingPattern::CPDF_TilingPattern(CPDF_Document* pDoc,
-                                       CPDF_Object* pPatternObj,
+                                       RetainPtr<CPDF_Object> pPatternObj,
                                        const CFX_Matrix& parentMatrix)
-    : CPDF_Pattern(pDoc, pPatternObj, parentMatrix) {
+    : CPDF_Pattern(pDoc, std::move(pPatternObj), parentMatrix) {
   DCHECK(document());
   m_bColored = pattern_obj()->GetDict()->GetIntegerFor("PaintType") == 1;
   SetPatternToFormMatrix();
diff --git a/core/fpdfapi/page/cpdf_tilingpattern.h b/core/fpdfapi/page/cpdf_tilingpattern.h
index 94fd7c6..e36a563 100644
--- a/core/fpdfapi/page/cpdf_tilingpattern.h
+++ b/core/fpdfapi/page/cpdf_tilingpattern.h
@@ -35,7 +35,7 @@
 
  private:
   CPDF_TilingPattern(CPDF_Document* pDoc,
-                     CPDF_Object* pPatternObj,
+                     RetainPtr<CPDF_Object> pPatternObj,
                      const CFX_Matrix& parentMatrix);
   CPDF_TilingPattern(const CPDF_TilingPattern&) = delete;
   CPDF_TilingPattern& operator=(const CPDF_TilingPattern&) = delete;
diff --git a/core/fpdfapi/parser/cpdf_document.cpp b/core/fpdfapi/parser/cpdf_document.cpp
index 4796b32..be8e867 100644
--- a/core/fpdfapi/parser/cpdf_document.cpp
+++ b/core/fpdfapi/parser/cpdf_document.cpp
@@ -491,9 +491,9 @@
   return true;
 }
 
-CPDF_Dictionary* CPDF_Document::GetInfo() {
+RetainPtr<CPDF_Dictionary> CPDF_Document::GetInfo() {
   if (m_pInfoDict)
-    return m_pInfoDict.Get();
+    return m_pInfoDict;
 
   if (!m_pParser)
     return nullptr;
@@ -504,10 +504,10 @@
 
   auto ref = pdfium::MakeRetain<CPDF_Reference>(this, info_obj_num);
   m_pInfoDict = ToDictionary(ref->GetMutableDirect());
-  return m_pInfoDict.Get();
+  return m_pInfoDict;
 }
 
-const CPDF_Array* CPDF_Document::GetFileIdentifier() const {
+RetainPtr<const CPDF_Array> CPDF_Document::GetFileIdentifier() const {
   return m_pParser ? m_pParser->GetIDArray() : nullptr;
 }
 
diff --git a/core/fpdfapi/parser/cpdf_document.h b/core/fpdfapi/parser/cpdf_document.h
index 04cdd3b..6ebc541 100644
--- a/core/fpdfapi/parser/cpdf_document.h
+++ b/core/fpdfapi/parser/cpdf_document.h
@@ -92,8 +92,8 @@
   CPDF_Parser* GetParser() const { return m_pParser.get(); }
   const CPDF_Dictionary* GetRoot() const { return m_pRootDict.Get(); }
   RetainPtr<CPDF_Dictionary> GetMutableRoot() { return m_pRootDict; }
-  CPDF_Dictionary* GetInfo();
-  const CPDF_Array* GetFileIdentifier() const;
+  RetainPtr<CPDF_Dictionary> GetInfo();
+  RetainPtr<const CPDF_Array> GetFileIdentifier() const;
 
   void DeletePage(int iPage);
   int GetPageCount() const;
diff --git a/core/fpdfapi/parser/cpdf_parser.cpp b/core/fpdfapi/parser/cpdf_parser.cpp
index e7751e3..d734fcc 100644
--- a/core/fpdfapi/parser/cpdf_parser.cpp
+++ b/core/fpdfapi/parser/cpdf_parser.cpp
@@ -851,9 +851,8 @@
   m_CrossRefTable->AddCompressed(obj_num, archive_obj_num, archive_obj_index);
 }
 
-// TODO(tsepez): return retained object.
-const CPDF_Array* CPDF_Parser::GetIDArray() const {
-  return GetTrailer() ? GetTrailer()->GetArrayFor("ID").Get() : nullptr;
+RetainPtr<const CPDF_Array> CPDF_Parser::GetIDArray() const {
+  return GetTrailer() ? GetTrailer()->GetArrayFor("ID") : nullptr;
 }
 
 // TODO(tsepez): return retained object, though not clear if it can change.
diff --git a/core/fpdfapi/parser/cpdf_parser.h b/core/fpdfapi/parser/cpdf_parser.h
index a68346d..b39c749 100644
--- a/core/fpdfapi/parser/cpdf_parser.h
+++ b/core/fpdfapi/parser/cpdf_parser.h
@@ -88,9 +88,8 @@
   uint32_t GetPermissions() const;
   uint32_t GetRootObjNum() const;
   uint32_t GetInfoObjNum() const;
-  const CPDF_Array* GetIDArray() const;
+  RetainPtr<const CPDF_Array> GetIDArray() const;
   const CPDF_Dictionary* GetRoot() const;
-
   const CPDF_Dictionary* GetEncryptDict() const;
 
   RetainPtr<CPDF_Object> ParseIndirectObject(uint32_t objnum);
diff --git a/core/fpdfapi/parser/cpdf_security_handler.cpp b/core/fpdfapi/parser/cpdf_security_handler.cpp
index 6701687..db102bb 100644
--- a/core/fpdfapi/parser/cpdf_security_handler.cpp
+++ b/core/fpdfapi/parser/cpdf_security_handler.cpp
@@ -189,7 +189,7 @@
 CPDF_SecurityHandler::~CPDF_SecurityHandler() = default;
 
 bool CPDF_SecurityHandler::OnInit(const CPDF_Dictionary* pEncryptDict,
-                                  const CPDF_Array* pIdArray,
+                                  RetainPtr<const CPDF_Array> pIdArray,
                                   const ByteString& password) {
   if (pIdArray)
     m_FileId = pIdArray->GetByteStringAt(0);
diff --git a/core/fpdfapi/parser/cpdf_security_handler.h b/core/fpdfapi/parser/cpdf_security_handler.h
index 9da342e..ace4854 100644
--- a/core/fpdfapi/parser/cpdf_security_handler.h
+++ b/core/fpdfapi/parser/cpdf_security_handler.h
@@ -24,7 +24,7 @@
   CONSTRUCT_VIA_MAKE_RETAIN;
 
   bool OnInit(const CPDF_Dictionary* pEncryptDict,
-              const CPDF_Array* pIdArray,
+              RetainPtr<const CPDF_Array> pIdArray,
               const ByteString& password);
   void OnCreate(CPDF_Dictionary* pEncryptDict,
                 const CPDF_Array* pIdArray,
diff --git a/fpdfsdk/fpdf_doc.cpp b/fpdfsdk/fpdf_doc.cpp
index c7c6499..c6c396e 100644
--- a/fpdfsdk/fpdf_doc.cpp
+++ b/fpdfsdk/fpdf_doc.cpp
@@ -470,7 +470,7 @@
   if (id_type != FILEIDTYPE_PERMANENT && id_type != FILEIDTYPE_CHANGING)
     return 0;
 
-  const CPDF_Array* pFileId = pDoc->GetFileIdentifier();
+  RetainPtr<const CPDF_Array> pFileId = pDoc->GetFileIdentifier();
   if (!pFileId)
     return 0;
 
@@ -494,9 +494,10 @@
   if (!pDoc)
     return 0;
 
-  const CPDF_Dictionary* pInfo = pDoc->GetInfo();
+  RetainPtr<const CPDF_Dictionary> pInfo = pDoc->GetInfo();
   if (!pInfo)
     return 0;
+
   WideString text = pInfo->GetUnicodeTextFor(tag);
   return Utf16EncodeMaybeCopyAndReturnLength(text, buffer, buflen);
 }
diff --git a/fpdfsdk/fpdf_editpage.cpp b/fpdfsdk/fpdf_editpage.cpp
index 8352117..c88ecfb 100644
--- a/fpdfsdk/fpdf_editpage.cpp
+++ b/fpdfsdk/fpdf_editpage.cpp
@@ -172,7 +172,7 @@
     }
   }
 
-  CPDF_Dictionary* pInfoDict = pDoc->GetInfo();
+  RetainPtr<CPDF_Dictionary> pInfoDict = pDoc->GetInfo();
   if (pInfoDict) {
     if (IsPDFSandboxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS))
       pInfoDict->SetNewFor<CPDF_String>("CreationDate", DateStr, false);
diff --git a/fpdfsdk/fpdf_ppo.cpp b/fpdfsdk/fpdf_ppo.cpp
index fa2ce50..4a50cf7 100644
--- a/fpdfsdk/fpdf_ppo.cpp
+++ b/fpdfsdk/fpdf_ppo.cpp
@@ -255,7 +255,7 @@
   if (!pNewRoot)
     return false;
 
-  CPDF_Dictionary* pDocInfoDict = dest()->GetInfo();
+  RetainPtr<CPDF_Dictionary> pDocInfoDict = dest()->GetInfo();
   if (!pDocInfoDict)
     return false;
 
diff --git a/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.cpp b/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.cpp
index 7f2d1fa..7aab490 100644
--- a/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.cpp
+++ b/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.cpp
@@ -396,10 +396,14 @@
 }
 
 WideString CPDFXFA_DocEnvironment::GetTitle(const CXFA_FFDoc* hDoc) const {
-  if (hDoc != m_pContext->GetXFADoc() || !m_pContext->GetPDFDoc())
+  if (hDoc != m_pContext->GetXFADoc())
     return WideString();
 
-  const CPDF_Dictionary* pInfoDict = m_pContext->GetPDFDoc()->GetInfo();
+  CPDF_Document* pPDFDoc = m_pContext->GetPDFDoc();
+  if (!pPDFDoc)
+    return WideString();
+
+  RetainPtr<const CPDF_Dictionary> pInfoDict = pPDFDoc->GetInfo();
   if (!pInfoDict)
     return WideString();
 
@@ -409,10 +413,14 @@
 
 void CPDFXFA_DocEnvironment::SetTitle(CXFA_FFDoc* hDoc,
                                       const WideString& wsTitle) {
-  if (hDoc != m_pContext->GetXFADoc() || !m_pContext->GetPDFDoc())
+  if (hDoc != m_pContext->GetXFADoc())
     return;
 
-  CPDF_Dictionary* pInfoDict = m_pContext->GetPDFDoc()->GetInfo();
+  CPDF_Document* pPDFDoc = m_pContext->GetPDFDoc();
+  if (!pPDFDoc)
+    return;
+
+  RetainPtr<CPDF_Dictionary> pInfoDict = pPDFDoc->GetInfo();
   if (pInfoDict)
     pInfoDict->SetNewFor<CPDF_String>("Title", wsTitle.AsStringView());
 }
diff --git a/fxjs/cjs_document.cpp b/fxjs/cjs_document.cpp
index 3e19969..946fa95 100644
--- a/fxjs/cjs_document.cpp
+++ b/fxjs/cjs_document.cpp
@@ -660,7 +660,8 @@
   if (!m_pFormFillEnv)
     return CJS_Result::Failure(JSMessage::kBadObjectError);
 
-  const auto* pDictionary = m_pFormFillEnv->GetPDFDocument()->GetInfo();
+  RetainPtr<const CPDF_Dictionary> pDictionary =
+      m_pFormFillEnv->GetPDFDocument()->GetInfo();
   if (!pDictionary)
     return CJS_Result::Failure(JSMessage::kBadObjectError);
 
@@ -726,9 +727,11 @@
   if (!m_pFormFillEnv)
     return CJS_Result::Failure(JSMessage::kBadObjectError);
 
-  CPDF_Dictionary* pDictionary = m_pFormFillEnv->GetPDFDocument()->GetInfo();
+  RetainPtr<CPDF_Dictionary> pDictionary =
+      m_pFormFillEnv->GetPDFDocument()->GetInfo();
   if (!pDictionary)
     return CJS_Result::Failure(JSMessage::kBadObjectError);
+
   return CJS_Result::Success(pRuntime->NewString(
       pDictionary->GetUnicodeTextFor(propName).AsStringView()));
 }