Pass retained arguments to CPDF_Form and CPDF_Page

Bug: pdfium:1843
Change-Id: If4d0a5a155dfdb62546387ba463fa126f2eb768a
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/95410
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fpdfapi/edit/cpdf_pagecontentgenerator_unittest.cpp b/core/fpdfapi/edit/cpdf_pagecontentgenerator_unittest.cpp
index 7ebd924..c4be557 100644
--- a/core/fpdfapi/edit/cpdf_pagecontentgenerator_unittest.cpp
+++ b/core/fpdfapi/edit/cpdf_pagecontentgenerator_unittest.cpp
@@ -57,8 +57,7 @@
   pPathObj->path().AppendRect(10, 5, 13, 30);
 
   auto dummy_page_dict = pdfium::MakeRetain<CPDF_Dictionary>();
-  auto pTestPage =
-      pdfium::MakeRetain<CPDF_Page>(nullptr, dummy_page_dict.Get());
+  auto pTestPage = pdfium::MakeRetain<CPDF_Page>(nullptr, dummy_page_dict);
   CPDF_PageContentGenerator generator(pTestPage.Get());
   fxcrt::ostringstream buf;
   TestProcessPath(&generator, &buf, pPathObj.get());
@@ -96,8 +95,7 @@
                                    200000000000000.000002));
 
     auto dummy_page_dict = pdfium::MakeRetain<CPDF_Dictionary>();
-    auto pTestPage =
-        pdfium::MakeRetain<CPDF_Page>(nullptr, dummy_page_dict.Get());
+    auto pTestPage = pdfium::MakeRetain<CPDF_Page>(nullptr, dummy_page_dict);
     CPDF_PageContentGenerator generator(pTestPage.Get());
     fxcrt::ostringstream buf;
     TestProcessPath(&generator, &buf, pPathObj.get());
@@ -130,8 +128,7 @@
         CFX_PointF(53.4f, 5000000000000000000.00000000000000004),
         CFX_Path::Point::Type::kBezier);
     auto dummy_page_dict = pdfium::MakeRetain<CPDF_Dictionary>();
-    auto pTestPage =
-        pdfium::MakeRetain<CPDF_Page>(nullptr, dummy_page_dict.Get());
+    auto pTestPage = pdfium::MakeRetain<CPDF_Page>(nullptr, dummy_page_dict);
     CPDF_PageContentGenerator generator(pTestPage.Get());
     fxcrt::ostringstream buf;
 
@@ -170,8 +167,7 @@
                                        CFX_Path::Point::Type::kBezier);
 
   auto dummy_page_dict = pdfium::MakeRetain<CPDF_Dictionary>();
-  auto pTestPage =
-      pdfium::MakeRetain<CPDF_Page>(nullptr, dummy_page_dict.Get());
+  auto pTestPage = pdfium::MakeRetain<CPDF_Page>(nullptr, dummy_page_dict);
   CPDF_PageContentGenerator generator(pTestPage.Get());
   fxcrt::ostringstream buf;
   TestProcessPath(&generator, &buf, pPathObj.get());
@@ -204,7 +200,8 @@
 
   auto pDoc = std::make_unique<CPDF_TestDocument>();
   pDoc->CreateNewDoc();
-  CPDF_Dictionary* pPageDict = pDoc->CreateNewPage(0);
+
+  RetainPtr<CPDF_Dictionary> pPageDict(pDoc->CreateNewPage(0));
   auto pTestPage = pdfium::MakeRetain<CPDF_Page>(pDoc.get(), pPageDict);
   CPDF_PageContentGenerator generator(pTestPage.Get());
   fxcrt::ostringstream buf;
@@ -244,7 +241,8 @@
   // Checking font whose font dictionary is not yet indirect object.
   auto pDoc = std::make_unique<CPDF_TestDocument>();
   pDoc->CreateNewDoc();
-  CPDF_Dictionary* pPageDict = pDoc->CreateNewPage(0);
+
+  RetainPtr<CPDF_Dictionary> pPageDict(pDoc->CreateNewPage(0));
   auto pTestPage = pdfium::MakeRetain<CPDF_Page>(pDoc.get(), pPageDict);
   CPDF_PageContentGenerator generator(pTestPage.Get());
   auto pTextObj = std::make_unique<CPDF_TextObject>();
@@ -311,7 +309,7 @@
   auto pDoc = std::make_unique<CPDF_TestDocument>();
   pDoc->CreateNewDoc();
 
-  CPDF_Dictionary* pPageDict = pDoc->CreateNewPage(0);
+  RetainPtr<CPDF_Dictionary> pPageDict(pDoc->CreateNewPage(0));
   auto pTestPage = pdfium::MakeRetain<CPDF_Page>(pDoc.get(), pPageDict);
   CPDF_PageContentGenerator generator(pTestPage.Get());
 
@@ -391,8 +389,7 @@
   auto pStream = pdfium::MakeRetain<CPDF_Stream>(nullptr, 0, std::move(pDict));
 
   // Create an empty form.
-  auto pTestForm =
-      std::make_unique<CPDF_Form>(pDoc.get(), nullptr, pStream.Get());
+  auto pTestForm = std::make_unique<CPDF_Form>(pDoc.get(), nullptr, pStream);
   pTestForm->ParseContent();
   ASSERT_EQ(CPDF_PageObjectHolder::ParseState::kParsed,
             pTestForm->GetParseState());
@@ -418,8 +415,7 @@
                                                  std::move(pDict));
 
   // Create a form with a non-empty stream.
-  auto pTestForm =
-      std::make_unique<CPDF_Form>(pDoc.get(), nullptr, pStream.Get());
+  auto pTestForm = std::make_unique<CPDF_Form>(pDoc.get(), nullptr, pStream);
   pTestForm->ParseContent();
   ASSERT_EQ(CPDF_PageObjectHolder::ParseState::kParsed,
             pTestForm->GetParseState());
diff --git a/core/fpdfapi/font/cpdf_font.h b/core/fpdfapi/font/cpdf_font.h
index 43a0e82..4a276f0 100644
--- a/core/fpdfapi/font/cpdf_font.h
+++ b/core/fpdfapi/font/cpdf_font.h
@@ -55,8 +55,8 @@
 
     virtual std::unique_ptr<FormIface> CreateForm(
         CPDF_Document* pDocument,
-        CPDF_Dictionary* pPageResources,
-        CPDF_Stream* pFormStream) = 0;
+        RetainPtr<CPDF_Dictionary> pPageResources,
+        RetainPtr<CPDF_Stream> pFormStream) = 0;
   };
 
   static constexpr uint32_t kInvalidCharCode = static_cast<uint32_t>(-1);
diff --git a/core/fpdfapi/font/cpdf_type3font.cpp b/core/fpdfapi/font/cpdf_type3font.cpp
index a5ca94e..feb8b91 100644
--- a/core/fpdfapi/font/cpdf_type3font.cpp
+++ b/core/fpdfapi/font/cpdf_type3font.cpp
@@ -123,9 +123,8 @@
     return nullptr;
 
   std::unique_ptr<CPDF_Font::FormIface> pForm = m_pFormFactory->CreateForm(
-      m_pDocument.Get(),
-      m_pFontResources ? m_pFontResources.Get() : m_pPageResources.Get(),
-      pStream.Get());
+      m_pDocument.Get(), m_pFontResources ? m_pFontResources : m_pPageResources,
+      pStream);
 
   auto pNewChar = std::make_unique<CPDF_Type3Char>();
 
diff --git a/core/fpdfapi/page/cpdf_annotcontext.cpp b/core/fpdfapi/page/cpdf_annotcontext.cpp
index 6cc941a..205a77c 100644
--- a/core/fpdfapi/page/cpdf_annotcontext.cpp
+++ b/core/fpdfapi/page/cpdf_annotcontext.cpp
@@ -24,7 +24,7 @@
 
 CPDF_AnnotContext::~CPDF_AnnotContext() = default;
 
-void CPDF_AnnotContext::SetForm(CPDF_Stream* pStream) {
+void CPDF_AnnotContext::SetForm(RetainPtr<CPDF_Stream> pStream) {
   if (!pStream)
     return;
 
@@ -33,7 +33,7 @@
   pStream->GetMutableDict()->SetMatrixFor("Matrix", CFX_Matrix());
 
   m_pAnnotForm = std::make_unique<CPDF_Form>(
-      m_pPage->GetDocument(), m_pPage->AsPDFPage()->GetMutableResources().Get(),
+      m_pPage->GetDocument(), m_pPage->AsPDFPage()->GetMutableResources(),
       pStream);
   m_pAnnotForm->ParseContent();
 }
diff --git a/core/fpdfapi/page/cpdf_annotcontext.h b/core/fpdfapi/page/cpdf_annotcontext.h
index 3ea1840..9453a48 100644
--- a/core/fpdfapi/page/cpdf_annotcontext.h
+++ b/core/fpdfapi/page/cpdf_annotcontext.h
@@ -22,7 +22,7 @@
   CPDF_AnnotContext(RetainPtr<CPDF_Dictionary> pAnnotDict, IPDF_Page* pPage);
   ~CPDF_AnnotContext();
 
-  void SetForm(CPDF_Stream* pStream);
+  void SetForm(RetainPtr<CPDF_Stream> pStream);
   bool HasForm() const { return !!m_pAnnotForm; }
   CPDF_Form* GetForm() const { return m_pAnnotForm.get(); }
 
diff --git a/core/fpdfapi/page/cpdf_docpagedata.cpp b/core/fpdfapi/page/cpdf_docpagedata.cpp
index cf43753..221d67f 100644
--- a/core/fpdfapi/page/cpdf_docpagedata.cpp
+++ b/core/fpdfapi/page/cpdf_docpagedata.cpp
@@ -453,9 +453,10 @@
 
 std::unique_ptr<CPDF_Font::FormIface> CPDF_DocPageData::CreateForm(
     CPDF_Document* pDocument,
-    CPDF_Dictionary* pPageResources,
-    CPDF_Stream* pFormStream) {
-  return std::make_unique<CPDF_Form>(pDocument, pPageResources, pFormStream);
+    RetainPtr<CPDF_Dictionary> pPageResources,
+    RetainPtr<CPDF_Stream> pFormStream) {
+  return std::make_unique<CPDF_Form>(pDocument, std::move(pPageResources),
+                                     std::move(pFormStream));
 }
 
 RetainPtr<CPDF_Font> CPDF_DocPageData::AddStandardFont(
diff --git a/core/fpdfapi/page/cpdf_docpagedata.h b/core/fpdfapi/page/cpdf_docpagedata.h
index 30ba851..5617d60 100644
--- a/core/fpdfapi/page/cpdf_docpagedata.h
+++ b/core/fpdfapi/page/cpdf_docpagedata.h
@@ -47,8 +47,8 @@
   // CPDF_Font::FormFactoryIFace:
   std::unique_ptr<CPDF_Font::FormIface> CreateForm(
       CPDF_Document* pDocument,
-      CPDF_Dictionary* pPageResources,
-      CPDF_Stream* pFormStream) override;
+      RetainPtr<CPDF_Dictionary> pPageResources,
+      RetainPtr<CPDF_Stream> pFormStream) override;
 
   bool IsForceClear() const { return m_bForceClear; }
 
diff --git a/core/fpdfapi/page/cpdf_form.cpp b/core/fpdfapi/page/cpdf_form.cpp
index 11cfeec..daa810a 100644
--- a/core/fpdfapi/page/cpdf_form.cpp
+++ b/core/fpdfapi/page/cpdf_form.cpp
@@ -29,24 +29,27 @@
 }
 
 CPDF_Form::CPDF_Form(CPDF_Document* pDoc,
-                     CPDF_Dictionary* pPageResources,
-                     CPDF_Stream* pFormStream)
-    : CPDF_Form(pDoc, pPageResources, pFormStream, nullptr) {}
+                     RetainPtr<CPDF_Dictionary> pPageResources,
+                     RetainPtr<CPDF_Stream> pFormStream)
+    : CPDF_Form(pDoc,
+                std::move(pPageResources),
+                std::move(pFormStream),
+                nullptr) {}
 
 CPDF_Form::CPDF_Form(CPDF_Document* pDoc,
-                     CPDF_Dictionary* pPageResources,
-                     CPDF_Stream* pFormStream,
+                     RetainPtr<CPDF_Dictionary> pPageResources,
+                     RetainPtr<CPDF_Stream> pFormStream,
                      CPDF_Dictionary* pParentResources)
-    : CPDF_PageObjectHolder(
-          pDoc,
-          pFormStream->GetMutableDict().Get(),
-          pPageResources,
-          ChooseResourcesDict(pFormStream->GetMutableDict()
-                                  ->GetMutableDictFor("Resources")
-                                  .Get(),
-                              pParentResources,
-                              pPageResources)),
-      m_pFormStream(pFormStream) {
+    : CPDF_PageObjectHolder(pDoc,
+                            pFormStream->GetMutableDict(),
+                            pPageResources,
+                            pdfium::WrapRetain(ChooseResourcesDict(
+                                pFormStream->GetMutableDict()
+                                    ->GetMutableDictFor("Resources")
+                                    .Get(),
+                                pParentResources,
+                                pPageResources.Get()))),
+      m_pFormStream(std::move(pFormStream)) {
   LoadTransparencyInfo();
 }
 
diff --git a/core/fpdfapi/page/cpdf_form.h b/core/fpdfapi/page/cpdf_form.h
index 9de2c5e..2586407 100644
--- a/core/fpdfapi/page/cpdf_form.h
+++ b/core/fpdfapi/page/cpdf_form.h
@@ -30,11 +30,11 @@
                                               CPDF_Dictionary* pPageResources);
 
   CPDF_Form(CPDF_Document* pDocument,
-            CPDF_Dictionary* pPageResources,
-            CPDF_Stream* pFormStream);
+            RetainPtr<CPDF_Dictionary> pPageResources,
+            RetainPtr<CPDF_Stream> pFormStream);
   CPDF_Form(CPDF_Document* pDocument,
-            CPDF_Dictionary* pPageResources,
-            CPDF_Stream* pFormStream,
+            RetainPtr<CPDF_Dictionary> pPageResources,
+            RetainPtr<CPDF_Stream> pFormStream,
             CPDF_Dictionary* pParentResources);
   ~CPDF_Form() override;
 
diff --git a/core/fpdfapi/page/cpdf_page.cpp b/core/fpdfapi/page/cpdf_page.cpp
index bd5422f..ac5606d 100644
--- a/core/fpdfapi/page/cpdf_page.cpp
+++ b/core/fpdfapi/page/cpdf_page.cpp
@@ -19,12 +19,11 @@
 #include "third_party/base/check_op.h"
 #include "third_party/base/containers/contains.h"
 
-CPDF_Page::CPDF_Page(CPDF_Document* pDocument, CPDF_Dictionary* pPageDict)
-    : CPDF_PageObjectHolder(pDocument, pPageDict, nullptr, nullptr),
+CPDF_Page::CPDF_Page(CPDF_Document* pDocument,
+                     RetainPtr<CPDF_Dictionary> pPageDict)
+    : CPDF_PageObjectHolder(pDocument, std::move(pPageDict), nullptr, nullptr),
       m_PageSize(100, 100),
       m_pPDFDocument(pDocument) {
-  DCHECK(pPageDict);
-
   // Cannot initialize |m_pResources| and |m_pPageResources| via the
   // CPDF_PageObjectHolder ctor because GetPageAttr() requires
   // CPDF_PageObjectHolder to finish initializing first.
diff --git a/core/fpdfapi/page/cpdf_page.h b/core/fpdfapi/page/cpdf_page.h
index 546b106..4214ce6 100644
--- a/core/fpdfapi/page/cpdf_page.h
+++ b/core/fpdfapi/page/cpdf_page.h
@@ -98,7 +98,7 @@
   void UpdateDimensions();
 
  private:
-  CPDF_Page(CPDF_Document* pDocument, CPDF_Dictionary* pPageDict);
+  CPDF_Page(CPDF_Document* pDocument, RetainPtr<CPDF_Dictionary> pPageDict);
   ~CPDF_Page() override;
 
   RetainPtr<CPDF_Object> GetMutablePageAttr(const ByteString& name);
diff --git a/core/fpdfapi/page/cpdf_pageobjectholder.cpp b/core/fpdfapi/page/cpdf_pageobjectholder.cpp
index b820b44..cdab5b9 100644
--- a/core/fpdfapi/page/cpdf_pageobjectholder.cpp
+++ b/core/fpdfapi/page/cpdf_pageobjectholder.cpp
@@ -34,13 +34,14 @@
   return type < other.type;
 }
 
-CPDF_PageObjectHolder::CPDF_PageObjectHolder(CPDF_Document* pDoc,
-                                             CPDF_Dictionary* pDict,
-                                             CPDF_Dictionary* pPageResources,
-                                             CPDF_Dictionary* pResources)
-    : m_pPageResources(pPageResources),
-      m_pResources(pResources),
-      m_pDict(pDict),
+CPDF_PageObjectHolder::CPDF_PageObjectHolder(
+    CPDF_Document* pDoc,
+    RetainPtr<CPDF_Dictionary> pDict,
+    RetainPtr<CPDF_Dictionary> pPageResources,
+    RetainPtr<CPDF_Dictionary> pResources)
+    : m_pPageResources(std::move(pPageResources)),
+      m_pResources(std::move(pResources)),
+      m_pDict(std::move(pDict)),
       m_pDocument(pDoc) {
   DCHECK(m_pDict);
 }
diff --git a/core/fpdfapi/page/cpdf_pageobjectholder.h b/core/fpdfapi/page/cpdf_pageobjectholder.h
index 518b580..3453107 100644
--- a/core/fpdfapi/page/cpdf_pageobjectholder.h
+++ b/core/fpdfapi/page/cpdf_pageobjectholder.h
@@ -56,9 +56,9 @@
       std::deque<std::unique_ptr<CPDF_PageObject>>::const_iterator;
 
   CPDF_PageObjectHolder(CPDF_Document* pDoc,
-                        CPDF_Dictionary* pDict,
-                        CPDF_Dictionary* pPageResources,
-                        CPDF_Dictionary* pResources);
+                        RetainPtr<CPDF_Dictionary> pDict,
+                        RetainPtr<CPDF_Dictionary> pPageResources,
+                        RetainPtr<CPDF_Dictionary> pResources);
   virtual ~CPDF_PageObjectHolder();
 
   virtual bool IsPage() const;
diff --git a/core/fpdfapi/page/cpdf_streamcontentparser.cpp b/core/fpdfapi/page/cpdf_streamcontentparser.cpp
index dce3dde..8523006 100644
--- a/core/fpdfapi/page/cpdf_streamcontentparser.cpp
+++ b/core/fpdfapi/page/cpdf_streamcontentparser.cpp
@@ -731,7 +731,7 @@
     return;
   }
 
-  CPDF_Stream* pXObject = ToStream(FindResourceObj("XObject", name));
+  RetainPtr<CPDF_Stream> pXObject(ToStream(FindResourceObj("XObject", name)));
   if (!pXObject)
     return;
 
@@ -740,7 +740,7 @@
     type = pXObject->GetDict()->GetStringFor("Subtype");
 
   if (type == "Form") {
-    AddForm(pXObject);
+    AddForm(std::move(pXObject));
     return;
   }
 
@@ -758,18 +758,18 @@
   }
 }
 
-void CPDF_StreamContentParser::AddForm(CPDF_Stream* pStream) {
+void CPDF_StreamContentParser::AddForm(RetainPtr<CPDF_Stream> pStream) {
   CPDF_AllStates status;
   status.m_GeneralState = m_pCurStates->m_GeneralState;
   status.m_GraphState = m_pCurStates->m_GraphState;
   status.m_ColorState = m_pCurStates->m_ColorState;
   status.m_TextState = m_pCurStates->m_TextState;
-  auto form = std::make_unique<CPDF_Form>(
-      m_pDocument.Get(), m_pPageResources.Get(), pStream, m_pResources.Get());
+  auto form =
+      std::make_unique<CPDF_Form>(m_pDocument.Get(), m_pPageResources,
+                                  std::move(pStream), m_pResources.Get());
   form->ParseContent(&status, nullptr, m_ParsedSet.Get());
 
   CFX_Matrix matrix = m_pCurStates->m_CTM * m_mtContentToUser;
-
   auto pFormObj = std::make_unique<CPDF_FormObject>(GetCurrentStreamIndex(),
                                                     std::move(form), matrix);
   if (!m_pObjectHolder->BackgroundAlphaNeeded() &&
diff --git a/core/fpdfapi/page/cpdf_streamcontentparser.h b/core/fpdfapi/page/cpdf_streamcontentparser.h
index 87243c9..8879c85 100644
--- a/core/fpdfapi/page/cpdf_streamcontentparser.h
+++ b/core/fpdfapi/page/cpdf_streamcontentparser.h
@@ -125,7 +125,7 @@
   CPDF_ImageObject* AddImage(uint32_t streamObjNum);
   CPDF_ImageObject* AddImage(const RetainPtr<CPDF_Image>& pImage);
 
-  void AddForm(CPDF_Stream* pStream);
+  void AddForm(RetainPtr<CPDF_Stream> pStream);
   void SetGraphicStates(CPDF_PageObject* pObj,
                         bool bColor,
                         bool bText,
diff --git a/core/fpdfapi/page/cpdf_tilingpattern.cpp b/core/fpdfapi/page/cpdf_tilingpattern.cpp
index 25abafc..503642c 100644
--- a/core/fpdfapi/page/cpdf_tilingpattern.cpp
+++ b/core/fpdfapi/page/cpdf_tilingpattern.cpp
@@ -42,7 +42,8 @@
     return nullptr;
 
   const CFX_Matrix& matrix = parent_matrix();
-  auto form = std::make_unique<CPDF_Form>(document(), nullptr, pStream);
+  auto form = std::make_unique<CPDF_Form>(document(), nullptr,
+                                          pdfium::WrapRetain(pStream));
 
   CPDF_AllStates allStates;
   allStates.m_ColorState.Emplace();
diff --git a/core/fpdfapi/parser/cpdf_data_avail.cpp b/core/fpdfapi/parser/cpdf_data_avail.cpp
index a17ec03..d0d6117 100644
--- a/core/fpdfapi/parser/cpdf_data_avail.cpp
+++ b/core/fpdfapi/parser/cpdf_data_avail.cpp
@@ -35,24 +35,20 @@
 
 namespace {
 
-RetainPtr<CPDF_Object> GetResourceObject(CPDF_Dictionary* pDict) {
+RetainPtr<CPDF_Object> GetResourceObject(RetainPtr<CPDF_Dictionary> pDict) {
   constexpr size_t kMaxHierarchyDepth = 64;
   size_t depth = 0;
 
-  RetainPtr<CPDF_Dictionary> dictionary_to_check(pDict);
-  while (dictionary_to_check) {
-    RetainPtr<CPDF_Object> result =
-        dictionary_to_check->GetMutableObjectFor("Resources");
+  while (pDict) {
+    RetainPtr<CPDF_Object> result = pDict->GetMutableObjectFor("Resources");
     if (result)
       return result;
-    RetainPtr<CPDF_Object> parent =
-        dictionary_to_check->GetMutableObjectFor("Parent");
-    dictionary_to_check = parent ? parent->GetMutableDict() : nullptr;
-
     if (++depth > kMaxHierarchyDepth) {
       // We have cycle in parents hierarchy.
       return nullptr;
     }
+    RetainPtr<CPDF_Object> parent = pDict->GetMutableObjectFor("Parent");
+    pDict = parent ? parent->GetMutableDict() : nullptr;
   }
   return nullptr;
 }
@@ -863,14 +859,15 @@
   if (CheckAcroForm() == kFormNotAvailable)
     return kDataNotAvailable;
 
-  auto* pPageDict = m_pDocument->GetPageDictionary(iPage);
+  RetainPtr<CPDF_Dictionary> pPageDict =
+      m_pDocument->GetMutablePageDictionary(iPage);
   if (!pPageDict)
     return kDataError;
 
   {
     auto page_num_obj = std::make_pair(
         dwPage, std::make_unique<CPDF_PageObjectAvail>(
-                    GetValidator(), m_pDocument.Get(), pPageDict));
+                    GetValidator(), m_pDocument.Get(), pPageDict.Get()));
     CPDF_PageObjectAvail* page_obj_avail =
         m_PagesObjAvail.insert(std::move(page_num_obj)).first->second.get();
     const DocAvailStatus status = page_obj_avail->CheckAvail();
@@ -878,7 +875,7 @@
       return status;
   }
 
-  const DocAvailStatus resources_status = CheckResources(pPageDict);
+  const DocAvailStatus resources_status = CheckResources(std::move(pPageDict));
   if (resources_status != kDataAvailable)
     return resources_status;
 
@@ -889,10 +886,10 @@
 }
 
 CPDF_DataAvail::DocAvailStatus CPDF_DataAvail::CheckResources(
-    CPDF_Dictionary* page) {
+    RetainPtr<CPDF_Dictionary> page) {
   DCHECK(page);
   CPDF_ReadValidator::ScopedSession read_session(GetValidator());
-  RetainPtr<CPDF_Object> resources = GetResourceObject(page);
+  RetainPtr<CPDF_Object> resources = GetResourceObject(std::move(page));
   if (GetValidator()->has_read_problems())
     return kDataNotAvailable;
 
@@ -927,7 +924,7 @@
 const CPDF_Dictionary* CPDF_DataAvail::GetPageDictionary(int index) const {
   if (!m_pDocument || index < 0 || index >= GetPageCount())
     return nullptr;
-  CPDF_Dictionary* page = m_pDocument->GetPageDictionary(index);
+  const CPDF_Dictionary* page = m_pDocument->GetPageDictionary(index);
   if (page)
     return page;
   if (!m_pLinearized || !m_pHintTables)
diff --git a/core/fpdfapi/parser/cpdf_data_avail.h b/core/fpdfapi/parser/cpdf_data_avail.h
index bbae553..3b5b46c 100644
--- a/core/fpdfapi/parser/cpdf_data_avail.h
+++ b/core/fpdfapi/parser/cpdf_data_avail.h
@@ -130,7 +130,7 @@
   bool CheckInfo();
   bool CheckPages();
   bool CheckPage();
-  DocAvailStatus CheckResources(CPDF_Dictionary* page);
+  DocAvailStatus CheckResources(RetainPtr<CPDF_Dictionary> page);
   DocFormStatus CheckAcroForm();
   bool CheckPageStatus();
 
diff --git a/core/fpdfapi/parser/cpdf_document.cpp b/core/fpdfapi/parser/cpdf_document.cpp
index c67a790..22b88c9 100644
--- a/core/fpdfapi/parser/cpdf_document.cpp
+++ b/core/fpdfapi/parser/cpdf_document.cpp
@@ -278,7 +278,7 @@
   return !!m_PageList[iPage];
 }
 
-CPDF_Dictionary* CPDF_Document::GetPageDictionary(int iPage) {
+const CPDF_Dictionary* CPDF_Document::GetPageDictionary(int iPage) {
   if (!fxcrt::IndexInBounds(m_PageList, iPage))
     return nullptr;
 
@@ -303,6 +303,11 @@
   return pPage;
 }
 
+RetainPtr<CPDF_Dictionary> CPDF_Document::GetMutablePageDictionary(int iPage) {
+  return pdfium::WrapRetain(
+      const_cast<CPDF_Dictionary*>(GetPageDictionary(iPage)));
+}
+
 void CPDF_Document::SetPageObjNum(int iPage, uint32_t objNum) {
   m_PageList[iPage] = objNum;
 }
diff --git a/core/fpdfapi/parser/cpdf_document.h b/core/fpdfapi/parser/cpdf_document.h
index 40f1d6e..24c6b06 100644
--- a/core/fpdfapi/parser/cpdf_document.h
+++ b/core/fpdfapi/parser/cpdf_document.h
@@ -98,7 +98,8 @@
   void DeletePage(int iPage);
   int GetPageCount() const;
   bool IsPageLoaded(int iPage) const;
-  CPDF_Dictionary* GetPageDictionary(int iPage);
+  const CPDF_Dictionary* GetPageDictionary(int iPage);
+  RetainPtr<CPDF_Dictionary> GetMutablePageDictionary(int iPage);
   int GetPageIndex(uint32_t objnum);
   uint32_t GetUserPermissions() const;
 
diff --git a/core/fpdfapi/parser/cpdf_document_unittest.cpp b/core/fpdfapi/parser/cpdf_document_unittest.cpp
index ed9c2ff..97e1848 100644
--- a/core/fpdfapi/parser/cpdf_document_unittest.cpp
+++ b/core/fpdfapi/parser/cpdf_document_unittest.cpp
@@ -158,22 +158,22 @@
   std::unique_ptr<CPDF_TestDocumentForPages> document =
       std::make_unique<CPDF_TestDocumentForPages>();
   for (int i = 0; i < kNumTestPages; i++) {
-    CPDF_Dictionary* page = document->GetPageDictionary(i);
+    const CPDF_Dictionary* page = document->GetPageDictionary(i);
     ASSERT_TRUE(page);
     ASSERT_TRUE(page->KeyExist("PageNumbering"));
     EXPECT_EQ(i, page->GetIntegerFor("PageNumbering"));
   }
-  CPDF_Dictionary* page = document->GetPageDictionary(kNumTestPages);
+  const CPDF_Dictionary* page = document->GetPageDictionary(kNumTestPages);
   EXPECT_FALSE(page);
 }
 
 TEST_F(DocumentTest, GetPageWithoutObjNumTwice) {
   auto document = std::make_unique<CPDF_TestDocumentWithPageWithoutPageNum>();
-  CPDF_Dictionary* page = document->GetPageDictionary(2);
+  const CPDF_Dictionary* page = document->GetPageDictionary(2);
   ASSERT_TRUE(page);
   ASSERT_EQ(document->inlined_page(), page);
 
-  CPDF_Dictionary* second_call_page = document->GetPageDictionary(2);
+  const CPDF_Dictionary* second_call_page = document->GetPageDictionary(2);
   EXPECT_TRUE(second_call_page);
   EXPECT_EQ(page, second_call_page);
 }
@@ -182,12 +182,12 @@
   std::unique_ptr<CPDF_TestDocumentForPages> document =
       std::make_unique<CPDF_TestDocumentForPages>();
   for (int i = 6; i >= 0; i--) {
-    CPDF_Dictionary* page = document->GetPageDictionary(i);
+    const CPDF_Dictionary* page = document->GetPageDictionary(i);
     ASSERT_TRUE(page);
     ASSERT_TRUE(page->KeyExist("PageNumbering"));
     EXPECT_EQ(i, page->GetIntegerFor("PageNumbering"));
   }
-  CPDF_Dictionary* page = document->GetPageDictionary(kNumTestPages);
+  const CPDF_Dictionary* page = document->GetPageDictionary(kNumTestPages);
   EXPECT_FALSE(page);
 }
 
@@ -195,7 +195,7 @@
   std::unique_ptr<CPDF_TestDocumentForPages> document =
       std::make_unique<CPDF_TestDocumentForPages>();
 
-  CPDF_Dictionary* page = document->GetPageDictionary(1);
+  const CPDF_Dictionary* page = document->GetPageDictionary(1);
   ASSERT_TRUE(page);
   ASSERT_TRUE(page->KeyExist("PageNumbering"));
   EXPECT_EQ(1, page->GetIntegerFor("PageNumbering"));
diff --git a/core/fpdfapi/render/cpdf_renderstatus.cpp b/core/fpdfapi/render/cpdf_renderstatus.cpp
index 86c7244..dacea1a 100644
--- a/core/fpdfapi/render/cpdf_renderstatus.cpp
+++ b/core/fpdfapi/render/cpdf_renderstatus.cpp
@@ -1390,7 +1390,7 @@
   matrix.Translate(-pClipRect->left, -pClipRect->top);
 
   CPDF_Form form(m_pContext->GetDocument(),
-                 m_pContext->GetMutablePageResources().Get(), pGroup.Get());
+                 m_pContext->GetMutablePageResources(), pGroup);
   form.ParseContent();
 
   CFX_DefaultRenderDevice bitmap_device;
diff --git a/core/fpdfdoc/cpdf_annot.cpp b/core/fpdfdoc/cpdf_annot.cpp
index 1b37e28..078f4ed 100644
--- a/core/fpdfdoc/cpdf_annot.cpp
+++ b/core/fpdfdoc/cpdf_annot.cpp
@@ -195,7 +195,7 @@
     return it->second.get();
 
   auto pNewForm = std::make_unique<CPDF_Form>(
-      m_pDocument.Get(), pPage->GetMutableResources().Get(), pStream.Get());
+      m_pDocument.Get(), pPage->GetMutableResources(), pStream);
   pNewForm->ParseContent();
 
   CPDF_Form* pResult = pNewForm.get();
diff --git a/fpdfsdk/cpdfsdk_interactiveform.cpp b/fpdfsdk/cpdfsdk_interactiveform.cpp
index 87f15db..0ee9117 100644
--- a/fpdfsdk/cpdfsdk_interactiveform.cpp
+++ b/fpdfsdk/cpdfsdk_interactiveform.cpp
@@ -181,7 +181,7 @@
   DCHECK(pAnnotDict);
 
   for (int i = 0, sz = pDocument->GetPageCount(); i < sz; i++) {
-    CPDF_Dictionary* pPageDict = pDocument->GetPageDictionary(i);
+    const CPDF_Dictionary* pPageDict = pDocument->GetPageDictionary(i);
     if (!pPageDict)
       continue;
 
diff --git a/fpdfsdk/fpdf_annot.cpp b/fpdfsdk/fpdf_annot.cpp
index 7cd18e8..c57861b 100644
--- a/fpdfsdk/fpdf_annot.cpp
+++ b/fpdfsdk/fpdf_annot.cpp
@@ -553,7 +553,7 @@
 
   // Get the annotation's corresponding form object for parsing its AP stream.
   if (!pAnnot->HasForm())
-    pAnnot->SetForm(pStream.Get());
+    pAnnot->SetForm(pStream);
 
   // Check that the object did not come from the same annotation. If this check
   // succeeds, then it is assumed that the object came from
@@ -589,7 +589,7 @@
     if (!pStream)
       return 0;
 
-    pAnnot->SetForm(pStream.Get());
+    pAnnot->SetForm(std::move(pStream));
   }
   return pdfium::base::checked_cast<int>(
       pAnnot->GetForm()->GetPageObjectCount());
@@ -608,7 +608,7 @@
     if (!pStream)
       return nullptr;
 
-    pAnnot->SetForm(pStream.Get());
+    pAnnot->SetForm(std::move(pStream));
   }
 
   return FPDFPageObjectFromCPDFPageObject(
diff --git a/fpdfsdk/fpdf_editpage.cpp b/fpdfsdk/fpdf_editpage.cpp
index 39f419a..a6fa591 100644
--- a/fpdfsdk/fpdf_editpage.cpp
+++ b/fpdfsdk/fpdf_editpage.cpp
@@ -207,7 +207,7 @@
     return nullptr;
 
   page_index = pdfium::clamp(page_index, 0, pDoc->GetPageCount());
-  CPDF_Dictionary* pPageDict = pDoc->CreateNewPage(page_index);
+  RetainPtr<CPDF_Dictionary> pPageDict(pDoc->CreateNewPage(page_index));
   if (!pPageDict)
     return nullptr;
 
diff --git a/fpdfsdk/fpdf_flatten.cpp b/fpdfsdk/fpdf_flatten.cpp
index fdcec66..b5eb7e2 100644
--- a/fpdfsdk/fpdf_flatten.cpp
+++ b/fpdfsdk/fpdf_flatten.cpp
@@ -54,7 +54,7 @@
 }
 
 void GetContentsRect(CPDF_Document* pDoc,
-                     CPDF_Dictionary* pDict,
+                     RetainPtr<CPDF_Dictionary> pDict,
                      std::vector<CFX_FloatRect>* pRectArray) {
   auto pPDFPage = pdfium::MakeRetain<CPDF_Page>(pDoc, pDict);
   pPDFPage->ParseContent();
@@ -85,7 +85,7 @@
 }
 
 int ParserAnnots(CPDF_Document* pSourceDoc,
-                 CPDF_Dictionary* pPageDic,
+                 RetainPtr<CPDF_Dictionary> pPageDic,
                  std::vector<CFX_FloatRect>* pRectArray,
                  std::vector<CPDF_Dictionary*>* pObjectArray,
                  int nUsage) {
@@ -119,7 +119,7 @@
     else
       bParseStream = !!(nAnnotFlag & pdfium::annotation_flags::kPrint);
     if (bParseStream)
-      ParserStream(pPageDic, pAnnotDict.Get(), pRectArray, pObjectArray);
+      ParserStream(pPageDic.Get(), pAnnotDict.Get(), pRectArray, pObjectArray);
   }
   return FLATTEN_SUCCESS;
 }
@@ -265,7 +265,7 @@
   std::vector<CPDF_Dictionary*> ObjectArray;
   std::vector<CFX_FloatRect> RectArray;
   int iRet =
-      ParserAnnots(pDocument, pPageDict.Get(), &RectArray, &ObjectArray, nFlag);
+      ParserAnnots(pDocument, pPageDict, &RectArray, &ObjectArray, nFlag);
   if (iRet == FLATTEN_NOTHINGTODO || iRet == FLATTEN_FAIL)
     return iRet;
 
diff --git a/fpdfsdk/fpdf_ppo.cpp b/fpdfsdk/fpdf_ppo.cpp
index 50a37cd..92708a8 100644
--- a/fpdfsdk/fpdf_ppo.cpp
+++ b/fpdfsdk/fpdf_ppo.cpp
@@ -554,7 +554,8 @@
     size_t iInnerPageMax =
         std::min(iOuterPage + nPagesPerSheet, pageIndices.size());
     for (size_t i = iOuterPage; i < iInnerPageMax; ++i) {
-      auto* pSrcPageDict = src()->GetPageDictionary(pageIndices[i]);
+      RetainPtr<CPDF_Dictionary> pSrcPageDict =
+          src()->GetMutablePageDictionary(pageIndices[i]);
       if (!pSrcPageDict)
         return false;
 
@@ -653,7 +654,8 @@
 
 std::unique_ptr<XObjectContext>
 CPDF_NPageToOneExporter::CreateXObjectContextFromPage(int src_page_index) {
-  CPDF_Dictionary* src_page_dict = src()->GetPageDictionary(src_page_index);
+  RetainPtr<CPDF_Dictionary> src_page_dict =
+      src()->GetMutablePageDictionary(src_page_index);
   if (!src_page_dict)
     return nullptr;
 
@@ -810,7 +812,7 @@
   // Build toolchain bug?
   constexpr int kNoContentStream = CPDF_PageObject::kNoContentStream;
   auto form = std::make_unique<CPDF_Form>(xobj->dest_doc, nullptr,
-                                          xobj->xobject.Get(), nullptr);
+                                          xobj->xobject, nullptr);
   auto form_object = std::make_unique<CPDF_FormObject>(
       kNoContentStream, std::move(form), CFX_Matrix());
   return FPDFPageObjectFromCPDFPageObject(form_object.release());
diff --git a/fpdfsdk/fpdf_view.cpp b/fpdfsdk/fpdf_view.cpp
index 894370e..facb084 100644
--- a/fpdfsdk/fpdf_view.cpp
+++ b/fpdfsdk/fpdf_view.cpp
@@ -364,11 +364,11 @@
   }
 #endif  // PDF_ENABLE_XFA
 
-  CPDF_Dictionary* pDict = pDoc->GetPageDictionary(page_index);
+  RetainPtr<CPDF_Dictionary> pDict = pDoc->GetMutablePageDictionary(page_index);
   if (!pDict)
     return nullptr;
 
-  auto pPage = pdfium::MakeRetain<CPDF_Page>(pDoc, pDict);
+  auto pPage = pdfium::MakeRetain<CPDF_Page>(pDoc, std::move(pDict));
   pPage->SetRenderCache(std::make_unique<CPDF_PageRenderCache>(pPage.Get()));
   pPage->ParseContent();
   return FPDFPageFromIPDFPage(pPage.Leak());
@@ -920,11 +920,11 @@
   }
 #endif  // PDF_ENABLE_XFA
 
-  CPDF_Dictionary* pDict = pDoc->GetPageDictionary(page_index);
+  RetainPtr<CPDF_Dictionary> pDict = pDoc->GetMutablePageDictionary(page_index);
   if (!pDict)
     return false;
 
-  auto page = pdfium::MakeRetain<CPDF_Page>(pDoc, pDict);
+  auto page = pdfium::MakeRetain<CPDF_Page>(pDoc, std::move(pDict));
   page->SetRenderCache(std::make_unique<CPDF_PageRenderCache>(page.Get()));
   size->width = page->GetPageWidth();
   size->height = page->GetPageHeight();
diff --git a/fpdfsdk/fpdfxfa/cpdfxfa_page.cpp b/fpdfsdk/fpdfxfa/cpdfxfa_page.cpp
index 907efb5..8b6461b 100644
--- a/fpdfsdk/fpdfxfa/cpdfxfa_page.cpp
+++ b/fpdfsdk/fpdfxfa/cpdfxfa_page.cpp
@@ -7,6 +7,7 @@
 #include "fpdfsdk/fpdfxfa/cpdfxfa_page.h"
 
 #include <memory>
+#include <utility>
 
 #include "core/fpdfapi/page/cpdf_page.h"
 #include "core/fpdfapi/parser/cpdf_document.h"
@@ -90,13 +91,13 @@
 }
 
 bool CPDFXFA_Page::LoadPDFPage() {
-  CPDF_Document* pPDFDoc = GetDocument();
-  CPDF_Dictionary* pDict = pPDFDoc->GetPageDictionary(m_iPageIndex);
+  RetainPtr<CPDF_Dictionary> pDict =
+      GetDocument()->GetMutablePageDictionary(m_iPageIndex);
   if (!pDict)
     return false;
 
   if (!m_pPDFPage || m_pPDFPage->GetDict() != pDict)
-    LoadPDFPageFromDict(pDict);
+    LoadPDFPageFromDict(std::move(pDict));
 
   return true;
 }
@@ -119,9 +120,10 @@
   }
 }
 
-void CPDFXFA_Page::LoadPDFPageFromDict(CPDF_Dictionary* pPageDict) {
+void CPDFXFA_Page::LoadPDFPageFromDict(RetainPtr<CPDF_Dictionary> pPageDict) {
   DCHECK(pPageDict);
-  m_pPDFPage = pdfium::MakeRetain<CPDF_Page>(GetDocument(), pPageDict);
+  m_pPDFPage =
+      pdfium::MakeRetain<CPDF_Page>(GetDocument(), std::move(pPageDict));
   m_pPDFPage->SetRenderCache(
       std::make_unique<CPDF_PageRenderCache>(m_pPDFPage.Get()));
   m_pPDFPage->ParseContent();
diff --git a/fpdfsdk/fpdfxfa/cpdfxfa_page.h b/fpdfsdk/fpdfxfa/cpdfxfa_page.h
index 5b22946..3b12328 100644
--- a/fpdfsdk/fpdfxfa/cpdfxfa_page.h
+++ b/fpdfsdk/fpdfxfa/cpdfxfa_page.h
@@ -42,7 +42,7 @@
       const CFX_PointF& page_point) const override;
 
   bool LoadPage();
-  void LoadPDFPageFromDict(CPDF_Dictionary* pPageDict);
+  void LoadPDFPageFromDict(RetainPtr<CPDF_Dictionary> pPageDict);
   int GetPageIndex() const { return m_iPageIndex; }
   void SetXFAPageViewIndex(int index) { m_iPageIndex = index; }
   CXFA_FFPageView* GetXFAPageView() const;
diff --git a/fxjs/cjs_document.cpp b/fxjs/cjs_document.cpp
index d06db72..9e61366 100644
--- a/fxjs/cjs_document.cpp
+++ b/fxjs/cjs_document.cpp
@@ -1241,11 +1241,12 @@
   if (nPageNo < 0 || nPageNo >= pDocument->GetPageCount())
     return CJS_Result::Failure(JSMessage::kValueError);
 
-  CPDF_Dictionary* pPageDict = pDocument->GetPageDictionary(nPageNo);
+  RetainPtr<CPDF_Dictionary> pPageDict =
+      pDocument->GetMutablePageDictionary(nPageNo);
   if (!pPageDict)
     return CJS_Result::Failure(JSMessage::kBadObjectError);
 
-  auto page = pdfium::MakeRetain<CPDF_Page>(pDocument, pPageDict);
+  auto page = pdfium::MakeRetain<CPDF_Page>(pDocument, std::move(pPageDict));
   page->SetRenderCache(std::make_unique<CPDF_PageRenderCache>(page.Get()));
   page->ParseContent();
 
@@ -1296,11 +1297,12 @@
   if (nPageNo < 0 || nPageNo >= pDocument->GetPageCount())
     return CJS_Result::Failure(JSMessage::kValueError);
 
-  CPDF_Dictionary* pPageDict = pDocument->GetPageDictionary(nPageNo);
+  RetainPtr<CPDF_Dictionary> pPageDict =
+      pDocument->GetMutablePageDictionary(nPageNo);
   if (!pPageDict)
     return CJS_Result::Failure(JSMessage::kBadObjectError);
 
-  auto page = pdfium::MakeRetain<CPDF_Page>(pDocument, pPageDict);
+  auto page = pdfium::MakeRetain<CPDF_Page>(pDocument, std::move(pPageDict));
   page->SetRenderCache(std::make_unique<CPDF_PageRenderCache>(page.Get()));
   page->ParseContent();