Add CPDF_Document::GetMutableRoot().

Change-Id: Ic5af52a4417618c4c78123e33eae06af85c6ff37
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/94673
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fpdfapi/parser/cpdf_data_avail.cpp b/core/fpdfapi/parser/cpdf_data_avail.cpp
index 3cde64b..4f08c30 100644
--- a/core/fpdfapi/parser/cpdf_data_avail.cpp
+++ b/core/fpdfapi/parser/cpdf_data_avail.cpp
@@ -972,11 +972,11 @@
   }
 
   if (!m_pFormAvail) {
-    CPDF_Dictionary* pRoot = m_pDocument->GetRoot();
+    const CPDF_Dictionary* pRoot = m_pDocument->GetRoot();
     if (!pRoot)
       return kFormAvailable;
 
-    CPDF_Object* pAcroForm = pRoot->GetObjectFor("AcroForm");
+    const CPDF_Object* pAcroForm = pRoot->GetObjectFor("AcroForm");
     if (!pAcroForm)
       return kFormNotExist;
 
diff --git a/core/fpdfapi/parser/cpdf_document.cpp b/core/fpdfapi/parser/cpdf_document.cpp
index d090efa..8f323f2 100644
--- a/core/fpdfapi/parser/cpdf_document.cpp
+++ b/core/fpdfapi/parser/cpdf_document.cpp
@@ -450,7 +450,7 @@
 }
 
 bool CPDF_Document::InsertNewPage(int iPage, CPDF_Dictionary* pPageDict) {
-  CPDF_Dictionary* pRoot = GetRoot();
+  RetainPtr<CPDF_Dictionary> pRoot = GetMutableRoot();
   if (!pRoot)
     return false;
 
diff --git a/core/fpdfapi/parser/cpdf_document.h b/core/fpdfapi/parser/cpdf_document.h
index d5b59aa..40f1d6e 100644
--- a/core/fpdfapi/parser/cpdf_document.h
+++ b/core/fpdfapi/parser/cpdf_document.h
@@ -12,6 +12,7 @@
 #include <utility>
 #include <vector>
 
+#include "core/fpdfapi/parser/cpdf_dictionary.h"
 #include "core/fpdfapi/parser/cpdf_parser.h"
 #include "core/fxcrt/fx_memory.h"
 #include "core/fxcrt/observed_ptr.h"
@@ -89,7 +90,8 @@
   }
 
   CPDF_Parser* GetParser() const { return m_pParser.get(); }
-  CPDF_Dictionary* GetRoot() const { return m_pRootDict.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;
 
diff --git a/core/fpdfapi/parser/cpdf_document_unittest.cpp b/core/fpdfapi/parser/cpdf_document_unittest.cpp
index cc6e100..ed9c2ff 100644
--- a/core/fpdfapi/parser/cpdf_document_unittest.cpp
+++ b/core/fpdfapi/parser/cpdf_document_unittest.cpp
@@ -88,12 +88,13 @@
         CreatePageTreeNode(std::move(allPages), this, kNumTestPages);
 
     SetRootForTesting(NewIndirect<CPDF_Dictionary>());
-    GetRoot()->SetNewFor<CPDF_Reference>("Pages", this, pagesDict->GetObjNum());
+    GetMutableRoot()->SetNewFor<CPDF_Reference>("Pages", this,
+                                                pagesDict->GetObjNum());
     ResizePageListForTesting(kNumTestPages);
   }
 
   void SetTreeSize(int size) {
-    GetRoot()->SetNewFor<CPDF_Number>("Count", size);
+    GetMutableRoot()->SetNewFor<CPDF_Number>("Count", size);
     ResizePageListForTesting(size);
   }
 };
@@ -112,7 +113,8 @@
     CPDF_Dictionary* pagesDict =
         CreatePageTreeNode(std::move(allPages), this, 3);
     SetRootForTesting(NewIndirect<CPDF_Dictionary>());
-    GetRoot()->SetNewFor<CPDF_Reference>("Pages", this, pagesDict->GetObjNum());
+    GetMutableRoot()->SetNewFor<CPDF_Reference>("Pages", this,
+                                                pagesDict->GetObjNum());
     ResizePageListForTesting(3);
   }
 
@@ -136,7 +138,8 @@
     pagesDict->SetNewFor<CPDF_Number>("Count", 3);
     ResizePageListForTesting(10);
     SetRootForTesting(NewIndirect<CPDF_Dictionary>());
-    GetRoot()->SetNewFor<CPDF_Reference>("Pages", this, pagesDict->GetObjNum());
+    GetMutableRoot()->SetNewFor<CPDF_Reference>("Pages", this,
+                                                pagesDict->GetObjNum());
   }
 };
 
diff --git a/core/fpdfapi/parser/cpdf_object_avail.cpp b/core/fpdfapi/parser/cpdf_object_avail.cpp
index 13afd63..73e3833 100644
--- a/core/fpdfapi/parser/cpdf_object_avail.cpp
+++ b/core/fpdfapi/parser/cpdf_object_avail.cpp
@@ -17,7 +17,7 @@
 CPDF_ObjectAvail::CPDF_ObjectAvail(
     const RetainPtr<CPDF_ReadValidator>& validator,
     CPDF_IndirectObjectHolder* holder,
-    CPDF_Object* root)
+    const CPDF_Object* root)
     : validator_(validator), holder_(holder), root_(root) {
   DCHECK(validator_);
   DCHECK(holder);
diff --git a/core/fpdfapi/parser/cpdf_object_avail.h b/core/fpdfapi/parser/cpdf_object_avail.h
index a1dcc27..a8f5c6f 100644
--- a/core/fpdfapi/parser/cpdf_object_avail.h
+++ b/core/fpdfapi/parser/cpdf_object_avail.h
@@ -21,7 +21,7 @@
  public:
   CPDF_ObjectAvail(const RetainPtr<CPDF_ReadValidator>& validator,
                    CPDF_IndirectObjectHolder* holder,
-                   CPDF_Object* root);
+                   const CPDF_Object* root);
   CPDF_ObjectAvail(const RetainPtr<CPDF_ReadValidator>& validator,
                    CPDF_IndirectObjectHolder* holder,
                    uint32_t obj_num);
@@ -40,9 +40,9 @@
   void CleanMemory();
   bool HasObjectParsed(uint32_t obj_num) const;
 
-  RetainPtr<CPDF_ReadValidator> validator_;
-  UnownedPtr<CPDF_IndirectObjectHolder> holder_;
-  RetainPtr<CPDF_Object> root_;
+  RetainPtr<CPDF_ReadValidator> const validator_;
+  UnownedPtr<CPDF_IndirectObjectHolder> const holder_;
+  RetainPtr<const CPDF_Object> root_;
   std::set<uint32_t> parsed_objnums_;
   std::stack<uint32_t> non_parsed_objects_;
 };
diff --git a/core/fpdfdoc/cpdf_bafontmap.cpp b/core/fpdfdoc/cpdf_bafontmap.cpp
index 272cef8..149955b 100644
--- a/core/fpdfdoc/cpdf_bafontmap.cpp
+++ b/core/fpdfdoc/cpdf_bafontmap.cpp
@@ -231,7 +231,7 @@
   const bool bWidget =
       (m_pAnnotDict->GetNameFor(pdfium::annotation::kSubtype) == "Widget");
   if (bWidget) {
-    CPDF_Dictionary* pRootDict = m_pDocument->GetRoot();
+    RetainPtr<CPDF_Dictionary> pRootDict = m_pDocument->GetMutableRoot();
     if (pRootDict)
       pAcroFormDict = pRootDict->GetMutableDictFor("AcroForm");
   }
diff --git a/core/fpdfdoc/cpdf_generateap.cpp b/core/fpdfdoc/cpdf_generateap.cpp
index 5108df6..f75fc54 100644
--- a/core/fpdfdoc/cpdf_generateap.cpp
+++ b/core/fpdfdoc/cpdf_generateap.cpp
@@ -916,7 +916,7 @@
 void CPDF_GenerateAP::GenerateFormAP(CPDF_Document* pDoc,
                                      CPDF_Dictionary* pAnnotDict,
                                      FormType type) {
-  CPDF_Dictionary* pRootDict = pDoc->GetRoot();
+  RetainPtr<CPDF_Dictionary> pRootDict = pDoc->GetMutableRoot();
   if (!pRootDict)
     return;
 
diff --git a/core/fpdfdoc/cpdf_interactiveform.cpp b/core/fpdfdoc/cpdf_interactiveform.cpp
index b0b5ee4..e43cf81 100644
--- a/core/fpdfdoc/cpdf_interactiveform.cpp
+++ b/core/fpdfdoc/cpdf_interactiveform.cpp
@@ -266,8 +266,8 @@
 
 CPDF_Dictionary* InitDict(CPDF_Document* pDocument) {
   CPDF_Dictionary* pFormDict = pDocument->NewIndirect<CPDF_Dictionary>();
-  pDocument->GetRoot()->SetNewFor<CPDF_Reference>("AcroForm", pDocument,
-                                                  pFormDict->GetObjNum());
+  pDocument->GetMutableRoot()->SetNewFor<CPDF_Reference>(
+      "AcroForm", pDocument, pFormDict->GetObjNum());
 
   ByteString csBaseName;
   FX_Charset charSet = GetNativeCharSet();
@@ -528,7 +528,7 @@
 
 CPDF_InteractiveForm::CPDF_InteractiveForm(CPDF_Document* pDocument)
     : m_pDocument(pDocument), m_pFieldTree(std::make_unique<CFieldTree>()) {
-  CPDF_Dictionary* pRoot = m_pDocument->GetRoot();
+  RetainPtr<CPDF_Dictionary> pRoot = m_pDocument->GetMutableRoot();
   if (!pRoot)
     return;
 
@@ -566,7 +566,7 @@
   DCHECK(csNameTag);
 
   RetainPtr<CPDF_Dictionary> pFormDict =
-      pDocument->GetRoot()->GetMutableDictFor("AcroForm");
+      pDocument->GetMutableRoot()->GetMutableDictFor("AcroForm");
   if (!pFormDict)
     pFormDict = InitDict(pDocument);
 
diff --git a/core/fpdfdoc/cpdf_nametree.cpp b/core/fpdfdoc/cpdf_nametree.cpp
index 6a50e4e..87d9972 100644
--- a/core/fpdfdoc/cpdf_nametree.cpp
+++ b/core/fpdfdoc/cpdf_nametree.cpp
@@ -368,7 +368,7 @@
 CPDF_Array* LookupOldStyleNamedDest(CPDF_Document* pDoc,
                                     const ByteString& name) {
   RetainPtr<CPDF_Dictionary> pDests =
-      pDoc->GetRoot()->GetMutableDictFor("Dests");
+      pDoc->GetMutableRoot()->GetMutableDictFor("Dests");
   if (!pDests)
     return nullptr;
   return GetNamedDestFromObject(pDests->GetMutableDirectObjectFor(name).Get());
@@ -387,7 +387,7 @@
 std::unique_ptr<CPDF_NameTree> CPDF_NameTree::Create(
     CPDF_Document* pDoc,
     const ByteString& category) {
-  CPDF_Dictionary* pRoot = pDoc->GetRoot();
+  RetainPtr<CPDF_Dictionary> pRoot = pDoc->GetMutableRoot();
   if (!pRoot)
     return nullptr;
 
@@ -407,7 +407,7 @@
 std::unique_ptr<CPDF_NameTree> CPDF_NameTree::CreateWithRootNameArray(
     CPDF_Document* pDoc,
     const ByteString& category) {
-  CPDF_Dictionary* pRoot = pDoc->GetRoot();
+  RetainPtr<CPDF_Dictionary> pRoot = pDoc->GetMutableRoot();
   if (!pRoot)
     return nullptr;
 
diff --git a/core/fpdfdoc/cpdf_viewerpreferences.cpp b/core/fpdfdoc/cpdf_viewerpreferences.cpp
index fc60dac..48a9d2a 100644
--- a/core/fpdfdoc/cpdf_viewerpreferences.cpp
+++ b/core/fpdfdoc/cpdf_viewerpreferences.cpp
@@ -31,9 +31,9 @@
   return pDict ? pDict->GetIntegerFor("NumCopies") : 1;
 }
 
-CPDF_Array* CPDF_ViewerPreferences::PrintPageRange() const {
-  CPDF_Dictionary* pDict = GetViewerPreferences();
-  return pDict ? pDict->GetMutableArrayFor("PrintPageRange").Get() : nullptr;
+const CPDF_Array* CPDF_ViewerPreferences::PrintPageRange() const {
+  const CPDF_Dictionary* pDict = GetViewerPreferences();
+  return pDict ? pDict->GetArrayFor("PrintPageRange") : nullptr;
 }
 
 ByteString CPDF_ViewerPreferences::Duplex() const {
@@ -54,7 +54,7 @@
   return pName->GetString();
 }
 
-CPDF_Dictionary* CPDF_ViewerPreferences::GetViewerPreferences() const {
-  CPDF_Dictionary* pDict = m_pDoc->GetRoot();
-  return pDict ? pDict->GetMutableDictFor("ViewerPreferences").Get() : nullptr;
+const CPDF_Dictionary* CPDF_ViewerPreferences::GetViewerPreferences() const {
+  const CPDF_Dictionary* pDict = m_pDoc->GetRoot();
+  return pDict ? pDict->GetDictFor("ViewerPreferences") : nullptr;
 }
diff --git a/core/fpdfdoc/cpdf_viewerpreferences.h b/core/fpdfdoc/cpdf_viewerpreferences.h
index 13c809f..f5001c2 100644
--- a/core/fpdfdoc/cpdf_viewerpreferences.h
+++ b/core/fpdfdoc/cpdf_viewerpreferences.h
@@ -25,14 +25,14 @@
   bool IsDirectionR2L() const;
   bool PrintScaling() const;
   int32_t NumCopies() const;
-  CPDF_Array* PrintPageRange() const;
+  const CPDF_Array* PrintPageRange() const;
   ByteString Duplex() const;
 
   // Gets the entry for |bsKey|.
   absl::optional<ByteString> GenericName(const ByteString& bsKey) const;
 
  private:
-  CPDF_Dictionary* GetViewerPreferences() const;
+  const CPDF_Dictionary* GetViewerPreferences() const;
 
   UnownedPtr<const CPDF_Document> const m_pDoc;
 };
diff --git a/fpdfsdk/cpdfsdk_formfillenvironment.cpp b/fpdfsdk/cpdfsdk_formfillenvironment.cpp
index b064635..52e2dc6 100644
--- a/fpdfsdk/cpdfsdk_formfillenvironment.cpp
+++ b/fpdfsdk/cpdfsdk_formfillenvironment.cpp
@@ -651,7 +651,7 @@
 }
 
 bool CPDFSDK_FormFillEnvironment::ProcOpenAction() {
-  CPDF_Dictionary* pRoot = m_pCPDFDoc->GetRoot();
+  const CPDF_Dictionary* pRoot = m_pCPDFDoc->GetRoot();
   if (!pRoot)
     return false;
 
diff --git a/fpdfsdk/fpdf_formfill.cpp b/fpdfsdk/fpdf_formfill.cpp
index 5b261cf..d37bf63 100644
--- a/fpdfsdk/fpdf_formfill.cpp
+++ b/fpdfsdk/fpdf_formfill.cpp
@@ -768,7 +768,7 @@
     return;
 
   CPDF_Document* pDoc = pFormFillEnv->GetPDFDocument();
-  CPDF_Dictionary* pDict = pDoc->GetRoot();
+  const CPDF_Dictionary* pDict = pDoc->GetRoot();
   if (!pDict)
     return;
 
diff --git a/fpdfsdk/fpdf_ppo.cpp b/fpdfsdk/fpdf_ppo.cpp
index 2d544eb..7c60121 100644
--- a/fpdfsdk/fpdf_ppo.cpp
+++ b/fpdfsdk/fpdf_ppo.cpp
@@ -250,7 +250,7 @@
   DCHECK(m_pDestDoc);
   DCHECK(m_pSrcDoc);
 
-  CPDF_Dictionary* pNewRoot = dest()->GetRoot();
+  RetainPtr<CPDF_Dictionary> pNewRoot = dest()->GetMutableRoot();
   if (!pNewRoot)
     return false;
 
@@ -832,7 +832,7 @@
   if (!pSrcDict)
     return false;
 
-  CPDF_Dictionary* pDstDict = pDstDoc->GetRoot();
+  RetainPtr<CPDF_Dictionary> pDstDict = pDstDoc->GetMutableRoot();
   if (!pDstDict)
     return false;
 
diff --git a/fpdfsdk/fpdf_save.cpp b/fpdfsdk/fpdf_save.cpp
index c82faeb..e64e0af 100644
--- a/fpdfsdk/fpdf_save.cpp
+++ b/fpdfsdk/fpdf_save.cpp
@@ -46,7 +46,7 @@
   if (!pPDFDocument)
     return false;
 
-  CPDF_Dictionary* pRoot = pPDFDocument->GetRoot();
+  RetainPtr<CPDF_Dictionary> pRoot = pPDFDocument->GetMutableRoot();
   if (!pRoot)
     return false;
 
diff --git a/fpdfsdk/fpdf_signature.cpp b/fpdfsdk/fpdf_signature.cpp
index 7134988..d168f03 100644
--- a/fpdfsdk/fpdf_signature.cpp
+++ b/fpdfsdk/fpdf_signature.cpp
@@ -17,7 +17,7 @@
 
 std::vector<CPDF_Dictionary*> CollectSignatures(CPDF_Document* doc) {
   std::vector<CPDF_Dictionary*> signatures;
-  CPDF_Dictionary* root = doc->GetRoot();
+  const CPDF_Dictionary* root = doc->GetRoot();
   if (!root)
     return signatures;