Add const/non-const versions of remaining CPDF_Dictionary methods.

GetObjectFor() and GetDirectObjectFor().

Change-Id: I588cd994dfccf0ffd4c8f91362a4806dc109251e
Reviewed-on: https://pdfium-review.googlesource.com/32991
Reviewed-by: Ryan Harrison <rharrison@chromium.org>
Commit-Queue: Ryan Harrison <rharrison@chromium.org>
diff --git a/core/fpdfapi/edit/cpdf_creator.cpp b/core/fpdfapi/edit/cpdf_creator.cpp
index 5e3f9ee..24c4c2c 100644
--- a/core/fpdfapi/edit/cpdf_creator.cpp
+++ b/core/fpdfapi/edit/cpdf_creator.cpp
@@ -148,7 +148,6 @@
       m_pEncryptDict(m_pParser ? m_pParser->GetEncryptDict() : nullptr),
       m_dwEncryptObjNum(0),
       m_pSecurityHandler(m_pParser ? m_pParser->GetSecurityHandler() : nullptr),
-      m_pMetadata(nullptr),
       m_dwLastObjNum(m_pDocument->GetLastObjNum()),
       m_Archive(pdfium::MakeUnique<CFX_FileBufferArchive>(archive)),
       m_SavedOffset(0),
diff --git a/core/fpdfapi/edit/cpdf_creator.h b/core/fpdfapi/edit/cpdf_creator.h
index 4c1d0f1..f95cab4 100644
--- a/core/fpdfapi/edit/cpdf_creator.h
+++ b/core/fpdfapi/edit/cpdf_creator.h
@@ -88,7 +88,7 @@
   UnownedPtr<CPDF_Dictionary> m_pEncryptDict;
   uint32_t m_dwEncryptObjNum;
   fxcrt::MaybeOwned<CPDF_SecurityHandler> m_pSecurityHandler;
-  UnownedPtr<CPDF_Object> m_pMetadata;
+  UnownedPtr<const CPDF_Object> m_pMetadata;
   uint32_t m_dwLastObjNum;
   std::unique_ptr<IFX_ArchiveStream> m_Archive;
   FX_FILESIZE m_SavedOffset;
diff --git a/core/fpdfapi/font/cpdf_cidfont.cpp b/core/fpdfapi/font/cpdf_cidfont.cpp
index 38a4d65..4b4f04b 100644
--- a/core/fpdfapi/font/cpdf_cidfont.cpp
+++ b/core/fpdfapi/font/cpdf_cidfont.cpp
@@ -407,9 +407,9 @@
   if (!IsEmbedded())
     LoadSubstFont();
 
-  CPDF_Object* pmap = pCIDFontDict->GetDirectObjectFor("CIDToGIDMap");
+  const CPDF_Object* pmap = pCIDFontDict->GetDirectObjectFor("CIDToGIDMap");
   if (pmap) {
-    if (CPDF_Stream* pStream = pmap->AsStream()) {
+    if (const CPDF_Stream* pStream = pmap->AsStream()) {
       m_pStreamAcc = pdfium::MakeRetain<CPDF_StreamAcc>(pStream);
       m_pStreamAcc->LoadAllDataFiltered();
     } else if (m_pFontFile && pmap->GetString() == "Identity") {
diff --git a/core/fpdfapi/page/cpdf_docpagedata.cpp b/core/fpdfapi/page/cpdf_docpagedata.cpp
index 37283b9..49d44b3 100644
--- a/core/fpdfapi/page/cpdf_docpagedata.cpp
+++ b/core/fpdfapi/page/cpdf_docpagedata.cpp
@@ -254,7 +254,7 @@
     if (!pColorSpaces)
       return pCS;
 
-    CPDF_Object* pDefaultCS = nullptr;
+    const CPDF_Object* pDefaultCS = nullptr;
     switch (pCS->GetFamily()) {
       case PDFCS_DEVICERGB:
         pDefaultCS = pColorSpaces->GetDirectObjectFor("DefaultRGB");
diff --git a/core/fpdfapi/parser/cpdf_cross_ref_avail.cpp b/core/fpdfapi/parser/cpdf_cross_ref_avail.cpp
index be9818a..2ab530e 100644
--- a/core/fpdfapi/parser/cpdf_cross_ref_avail.cpp
+++ b/core/fpdfapi/parser/cpdf_cross_ref_avail.cpp
@@ -186,7 +186,7 @@
     return false;
   }
 
-  CPDF_Name* type_name = ToName(trailer->GetObjectFor(kTypeFieldKey));
+  const CPDF_Name* type_name = ToName(trailer->GetObjectFor(kTypeFieldKey));
   if (type_name && type_name->GetString() == kXRefKeyword) {
     const int32_t xrefpos = trailer->GetIntegerFor(kPrevCrossRefFieldKey);
     if (xrefpos &&
diff --git a/core/fpdfapi/parser/cpdf_data_avail.cpp b/core/fpdfapi/parser/cpdf_data_avail.cpp
index 1296b23..719169a 100644
--- a/core/fpdfapi/parser/cpdf_data_avail.cpp
+++ b/core/fpdfapi/parser/cpdf_data_avail.cpp
@@ -279,7 +279,7 @@
 
 bool CPDF_DataAvail::PreparePageItem() {
   const CPDF_Dictionary* pRoot = m_pDocument->GetRoot();
-  CPDF_Reference* pRef =
+  const CPDF_Reference* pRef =
       ToReference(pRoot ? pRoot->GetObjectFor("Pages") : nullptr);
   if (!pRef) {
     m_docStatus = PDF_DATAAVAIL_ERROR;
@@ -996,7 +996,7 @@
     if (!pRoot)
       return FormAvailable;
 
-    CPDF_Object* pAcroForm = pRoot->GetObjectFor("AcroForm");
+    const CPDF_Object* pAcroForm = pRoot->GetObjectFor("AcroForm");
     if (!pAcroForm)
       return FormNotExist;
 
diff --git a/core/fpdfapi/parser/cpdf_dictionary.cpp b/core/fpdfapi/parser/cpdf_dictionary.cpp
index 5257a20..ae7239e 100644
--- a/core/fpdfapi/parser/cpdf_dictionary.cpp
+++ b/core/fpdfapi/parser/cpdf_dictionary.cpp
@@ -81,63 +81,74 @@
   return std::move(pCopy);
 }
 
-CPDF_Object* CPDF_Dictionary::GetObjectFor(const ByteString& key) const {
+const CPDF_Object* CPDF_Dictionary::GetObjectFor(const ByteString& key) const {
   auto it = m_Map.find(key);
   return it != m_Map.end() ? it->second.get() : nullptr;
 }
 
-CPDF_Object* CPDF_Dictionary::GetDirectObjectFor(const ByteString& key) const {
+CPDF_Object* CPDF_Dictionary::GetObjectFor(const ByteString& key) {
+  auto it = m_Map.find(key);
+  return it != m_Map.end() ? it->second.get() : nullptr;
+}
+
+const CPDF_Object* CPDF_Dictionary::GetDirectObjectFor(
+    const ByteString& key) const {
+  const CPDF_Object* p = GetObjectFor(key);
+  return p ? p->GetDirect() : nullptr;
+}
+
+CPDF_Object* CPDF_Dictionary::GetDirectObjectFor(const ByteString& key) {
   CPDF_Object* p = GetObjectFor(key);
   return p ? p->GetDirect() : nullptr;
 }
 
 ByteString CPDF_Dictionary::GetStringFor(const ByteString& key) const {
-  CPDF_Object* p = GetObjectFor(key);
+  const CPDF_Object* p = GetObjectFor(key);
   return p ? p->GetString() : ByteString();
 }
 
 WideString CPDF_Dictionary::GetUnicodeTextFor(const ByteString& key) const {
-  CPDF_Object* p = GetObjectFor(key);
-  if (CPDF_Reference* pRef = ToReference(p))
+  const CPDF_Object* p = GetObjectFor(key);
+  if (const CPDF_Reference* pRef = ToReference(p))
     p = pRef->GetDirect();
   return p ? p->GetUnicodeText() : WideString();
 }
 
 ByteString CPDF_Dictionary::GetStringFor(const ByteString& key,
                                          const ByteString& def) const {
-  CPDF_Object* p = GetObjectFor(key);
+  const CPDF_Object* p = GetObjectFor(key);
   return p ? p->GetString() : ByteString(def);
 }
 
 int CPDF_Dictionary::GetIntegerFor(const ByteString& key) const {
-  CPDF_Object* p = GetObjectFor(key);
+  const CPDF_Object* p = GetObjectFor(key);
   return p ? p->GetInteger() : 0;
 }
 
 int CPDF_Dictionary::GetIntegerFor(const ByteString& key, int def) const {
-  CPDF_Object* p = GetObjectFor(key);
+  const CPDF_Object* p = GetObjectFor(key);
   return p ? p->GetInteger() : def;
 }
 
 float CPDF_Dictionary::GetNumberFor(const ByteString& key) const {
-  CPDF_Object* p = GetObjectFor(key);
+  const CPDF_Object* p = GetObjectFor(key);
   return p ? p->GetNumber() : 0;
 }
 
 bool CPDF_Dictionary::GetBooleanFor(const ByteString& key,
                                     bool bDefault) const {
-  CPDF_Object* p = GetObjectFor(key);
+  const CPDF_Object* p = GetObjectFor(key);
   return ToBoolean(p) ? p->GetInteger() != 0 : bDefault;
 }
 
 const CPDF_Dictionary* CPDF_Dictionary::GetDictFor(
     const ByteString& key) const {
-  CPDF_Object* p = GetDirectObjectFor(key);
+  const CPDF_Object* p = GetDirectObjectFor(key);
   if (!p)
     return nullptr;
-  if (CPDF_Dictionary* pDict = p->AsDictionary())
+  if (const CPDF_Dictionary* pDict = p->AsDictionary())
     return pDict;
-  if (CPDF_Stream* pStream = p->AsStream())
+  if (const CPDF_Stream* pStream = p->AsStream())
     return pStream->GetDict();
   return nullptr;
 }
diff --git a/core/fpdfapi/parser/cpdf_dictionary.h b/core/fpdfapi/parser/cpdf_dictionary.h
index 5240ab3..569baed 100644
--- a/core/fpdfapi/parser/cpdf_dictionary.h
+++ b/core/fpdfapi/parser/cpdf_dictionary.h
@@ -41,8 +41,10 @@
   bool WriteTo(IFX_ArchiveStream* archive) const override;
 
   size_t GetCount() const { return m_Map.size(); }
-  CPDF_Object* GetObjectFor(const ByteString& key) const;
-  CPDF_Object* GetDirectObjectFor(const ByteString& key) const;
+  const CPDF_Object* GetObjectFor(const ByteString& key) const;
+  CPDF_Object* GetObjectFor(const ByteString& key);
+  const CPDF_Object* GetDirectObjectFor(const ByteString& key) const;
+  CPDF_Object* GetDirectObjectFor(const ByteString& key);
   ByteString GetStringFor(const ByteString& key) const;
   ByteString GetStringFor(const ByteString& key,
                           const ByteString& default_str) const;
diff --git a/core/fpdfapi/parser/cpdf_stream_acc.h b/core/fpdfapi/parser/cpdf_stream_acc.h
index 1c9d5ef..cd83634 100644
--- a/core/fpdfapi/parser/cpdf_stream_acc.h
+++ b/core/fpdfapi/parser/cpdf_stream_acc.h
@@ -49,7 +49,7 @@
   uint32_t m_dwSize = 0;
   bool m_bNewBuf = false;
   ByteString m_ImageDecoder;
-  CPDF_Dictionary* m_pImageParam = nullptr;
+  const CPDF_Dictionary* m_pImageParam = nullptr;
   UnownedPtr<const CPDF_Stream> const m_pStream;
   uint8_t* m_pSrcData = nullptr;
 };
diff --git a/core/fpdfapi/parser/fpdf_parser_decode.cpp b/core/fpdfapi/parser/fpdf_parser_decode.cpp
index e734183..aafb812 100644
--- a/core/fpdfapi/parser/fpdf_parser_decode.cpp
+++ b/core/fpdfapi/parser/fpdf_parser_decode.cpp
@@ -308,7 +308,7 @@
 uint32_t FPDFAPI_FlateOrLZWDecode(bool bLZW,
                                   const uint8_t* src_buf,
                                   uint32_t src_size,
-                                  CPDF_Dictionary* pParams,
+                                  const CPDF_Dictionary* pParams,
                                   uint32_t estimated_size,
                                   uint8_t** dest_buf,
                                   uint32_t* dest_size) {
@@ -339,17 +339,18 @@
                     uint8_t** dest_buf,
                     uint32_t* dest_size,
                     ByteString* ImageEncoding,
-                    CPDF_Dictionary** pImageParms) {
-  CPDF_Object* pDecoder = pDict ? pDict->GetDirectObjectFor("Filter") : nullptr;
+                    const CPDF_Dictionary** pImageParms) {
+  const CPDF_Object* pDecoder =
+      pDict ? pDict->GetDirectObjectFor("Filter") : nullptr;
   if (!pDecoder || (!pDecoder->IsArray() && !pDecoder->IsName()))
     return false;
 
-  CPDF_Object* pParams =
+  const CPDF_Object* pParams =
       pDict ? pDict->GetDirectObjectFor(pdfium::stream::kDecodeParms) : nullptr;
 
-  std::vector<std::pair<ByteString, CPDF_Object*>> DecoderArray;
-  if (CPDF_Array* pDecoders = pDecoder->AsArray()) {
-    CPDF_Array* pParamsArray = ToArray(pParams);
+  std::vector<std::pair<ByteString, const CPDF_Object*>> DecoderArray;
+  if (const CPDF_Array* pDecoders = pDecoder->AsArray()) {
+    const CPDF_Array* pParamsArray = ToArray(pParams);
     for (size_t i = 0; i < pDecoders->GetCount(); ++i) {
       DecoderArray.push_back(
           {pDecoders->GetStringAt(i),
@@ -365,7 +366,7 @@
   for (size_t i = 0; i < nSize; ++i) {
     int estimated_size = i == nSize - 1 ? last_estimated_size : 0;
     ByteString decoder = DecoderArray[i].first;
-    CPDF_Dictionary* pParam = ToDictionary(DecoderArray[i].second);
+    const CPDF_Dictionary* pParam = ToDictionary(DecoderArray[i].second);
     uint8_t* new_buf = nullptr;
     uint32_t new_size = 0xFFFFFFFF;
     uint32_t offset = FX_INVALID_OFFSET;
diff --git a/core/fpdfapi/parser/fpdf_parser_decode.h b/core/fpdfapi/parser/fpdf_parser_decode.h
index 825d431..c0f636a 100644
--- a/core/fpdfapi/parser/fpdf_parser_decode.h
+++ b/core/fpdfapi/parser/fpdf_parser_decode.h
@@ -67,7 +67,7 @@
 uint32_t FPDFAPI_FlateOrLZWDecode(bool bLZW,
                                   const uint8_t* src_buf,
                                   uint32_t src_size,
-                                  CPDF_Dictionary* pParams,
+                                  const CPDF_Dictionary* pParams,
                                   uint32_t estimated_size,
                                   uint8_t** dest_buf,
                                   uint32_t* dest_size);
@@ -80,6 +80,6 @@
                     uint8_t** dest_buf,
                     uint32_t* dest_size,
                     ByteString* ImageEncoding,
-                    CPDF_Dictionary** pImageParms);
+                    const CPDF_Dictionary** pImageParms);
 
 #endif  // CORE_FPDFAPI_PARSER_FPDF_PARSER_DECODE_H_
diff --git a/core/fpdfapi/render/cpdf_dibsource.cpp b/core/fpdfapi/render/cpdf_dibsource.cpp
index e9de528..ad828f2 100644
--- a/core/fpdfapi/render/cpdf_dibsource.cpp
+++ b/core/fpdfapi/render/cpdf_dibsource.cpp
@@ -342,12 +342,12 @@
 
   if (m_bImageMask || !m_pDict->KeyExist("ColorSpace")) {
     if (!m_bImageMask) {
-      CPDF_Object* pFilter = m_pDict->GetDirectObjectFor("Filter");
+      const CPDF_Object* pFilter = m_pDict->GetDirectObjectFor("Filter");
       if (pFilter) {
         ByteString filter;
         if (pFilter->IsName()) {
           filter = pFilter->GetString();
-        } else if (CPDF_Array* pArray = pFilter->AsArray()) {
+        } else if (const CPDF_Array* pArray = pFilter->AsArray()) {
           filter = pArray->GetStringAt(pArray->GetCount() - 1);
         }
 
@@ -427,11 +427,11 @@
   if (m_pDict->KeyExist("SMask"))
     return true;
 
-  CPDF_Object* pMask = m_pDict->GetDirectObjectFor("Mask");
+  const CPDF_Object* pMask = m_pDict->GetDirectObjectFor("Mask");
   if (!pMask)
     return true;
 
-  if (CPDF_Array* pArray = pMask->AsArray()) {
+  if (const CPDF_Array* pArray = pMask->AsArray()) {
     if (pArray->GetCount() >= m_nComponents * 2) {
       for (uint32_t i = 0; i < m_nComponents; i++) {
         int min_num = pArray->GetIntegerAt(i * 2);
@@ -791,7 +791,7 @@
 
 void CPDF_DIBSource::ValidateDictParam() {
   m_bpc = m_bpc_orig;
-  CPDF_Object* pFilter = m_pDict->GetDirectObjectFor("Filter");
+  const CPDF_Object* pFilter = m_pDict->GetDirectObjectFor("Filter");
   if (pFilter) {
     if (pFilter->IsName()) {
       ByteString filter = pFilter->GetString();
@@ -805,7 +805,7 @@
       } else if (filter == "DCTDecode") {
         m_bpc = 8;
       }
-    } else if (CPDF_Array* pArray = pFilter->AsArray()) {
+    } else if (const CPDF_Array* pArray = pFilter->AsArray()) {
       ByteString filter = pArray->GetStringAt(pArray->GetCount() - 1);
       if (filter == "CCITTFaxDecode" || filter == "JBIG2Decode") {
         m_bpc = 1;
diff --git a/core/fpdfdoc/cpdf_action.cpp b/core/fpdfdoc/cpdf_action.cpp
index 4a89a7d..49d143a 100644
--- a/core/fpdfdoc/cpdf_action.cpp
+++ b/core/fpdfdoc/cpdf_action.cpp
@@ -36,14 +36,14 @@
   if (type != "GoTo" && type != "GoToR")
     return CPDF_Dest();
 
-  CPDF_Object* pDest = m_pDict->GetDirectObjectFor("D");
+  const CPDF_Object* pDest = m_pDict->GetDirectObjectFor("D");
   if (!pDest)
     return CPDF_Dest();
   if (pDest->IsString() || pDest->IsName()) {
     CPDF_NameTree name_tree(pDoc, "Dests");
     return CPDF_Dest(name_tree.LookupNamedDest(pDoc, pDest->GetUnicodeText()));
   }
-  if (CPDF_Array* pArray = pDest->AsArray())
+  if (const CPDF_Array* pArray = pDest->AsArray())
     return CPDF_Dest(pArray);
 
   return CPDF_Dest();
@@ -71,7 +71,7 @@
     return WideString();
   }
 
-  CPDF_Object* pFile = m_pDict->GetDirectObjectFor(pdfium::stream::kF);
+  const CPDF_Object* pFile = m_pDict->GetDirectObjectFor(pdfium::stream::kF);
   if (pFile)
     return CPDF_FileSpec(pFile).GetFileName();
 
@@ -108,7 +108,7 @@
   if (!m_pDict)
     return csJS;
 
-  CPDF_Object* pJS = m_pDict->GetDirectObjectFor("JS");
+  const CPDF_Object* pJS = m_pDict->GetDirectObjectFor("JS");
   return pJS ? pJS->GetUnicodeText() : csJS;
 }
 
@@ -116,24 +116,23 @@
   if (!m_pDict || !m_pDict->KeyExist("Next"))
     return 0;
 
-  CPDF_Object* pNext = m_pDict->GetDirectObjectFor("Next");
+  const CPDF_Object* pNext = m_pDict->GetDirectObjectFor("Next");
   if (!pNext)
     return 0;
   if (pNext->IsDictionary())
     return 1;
-  if (CPDF_Array* pArray = pNext->AsArray())
-    return pArray->GetCount();
-  return 0;
+  const CPDF_Array* pArray = pNext->AsArray();
+  return pArray ? pArray->GetCount() : 0;
 }
 
 CPDF_Action CPDF_Action::GetSubAction(size_t iIndex) const {
   if (!m_pDict || !m_pDict->KeyExist("Next"))
     return CPDF_Action(nullptr);
 
-  CPDF_Object* pNext = m_pDict->GetDirectObjectFor("Next");
-  if (CPDF_Array* pArray = ToArray(pNext))
+  const CPDF_Object* pNext = m_pDict->GetDirectObjectFor("Next");
+  if (const CPDF_Array* pArray = ToArray(pNext))
     return CPDF_Action(pArray->GetDictAt(iIndex));
-  if (CPDF_Dictionary* pDict = ToDictionary(pNext)) {
+  if (const CPDF_Dictionary* pDict = ToDictionary(pNext)) {
     if (iIndex == 0)
       return CPDF_Action(pDict);
   }
diff --git a/core/fpdfdoc/cpdf_annot.cpp b/core/fpdfdoc/cpdf_annot.cpp
index 5734e19..ee79c21 100644
--- a/core/fpdfdoc/cpdf_annot.cpp
+++ b/core/fpdfdoc/cpdf_annot.cpp
@@ -61,10 +61,10 @@
   return pForm;
 }
 
-CPDF_Stream* FPDFDOC_GetAnnotAPInternal(const CPDF_Dictionary* pAnnotDict,
+CPDF_Stream* FPDFDOC_GetAnnotAPInternal(CPDF_Dictionary* pAnnotDict,
                                         CPDF_Annot::AppearanceMode eMode,
                                         bool bFallbackToNormal) {
-  const CPDF_Dictionary* pAP = pAnnotDict->GetDictFor("AP");
+  CPDF_Dictionary* pAP = pAnnotDict->GetDictFor("AP");
   if (!pAP)
     return nullptr;
 
@@ -177,12 +177,12 @@
   return m_pAnnotDict->GetIntegerFor("F");
 }
 
-CPDF_Stream* FPDFDOC_GetAnnotAP(const CPDF_Dictionary* pAnnotDict,
+CPDF_Stream* FPDFDOC_GetAnnotAP(CPDF_Dictionary* pAnnotDict,
                                 CPDF_Annot::AppearanceMode eMode) {
   return FPDFDOC_GetAnnotAPInternal(pAnnotDict, eMode, true);
 }
 
-CPDF_Stream* FPDFDOC_GetAnnotAPNoFallback(const CPDF_Dictionary* pAnnotDict,
+CPDF_Stream* FPDFDOC_GetAnnotAPNoFallback(CPDF_Dictionary* pAnnotDict,
                                           CPDF_Annot::AppearanceMode eMode) {
   return FPDFDOC_GetAnnotAPInternal(pAnnotDict, eMode, false);
 }
diff --git a/core/fpdfdoc/cpdf_annot.h b/core/fpdfdoc/cpdf_annot.h
index b287594..df9f773 100644
--- a/core/fpdfdoc/cpdf_annot.h
+++ b/core/fpdfdoc/cpdf_annot.h
@@ -128,12 +128,12 @@
 // Get the AP in an annotation dict for a given appearance mode.
 // If |eMode| is not Normal and there is not AP for that mode, falls back to
 // the Normal AP.
-CPDF_Stream* FPDFDOC_GetAnnotAP(const CPDF_Dictionary* pAnnotDict,
+CPDF_Stream* FPDFDOC_GetAnnotAP(CPDF_Dictionary* pAnnotDict,
                                 CPDF_Annot::AppearanceMode eMode);
 
 // Get the AP in an annotation dict for a given appearance mode.
 // No fallbacks to Normal like in FPDFDOC_GetAnnotAP.
-CPDF_Stream* FPDFDOC_GetAnnotAPNoFallback(const CPDF_Dictionary* pAnnotDict,
+CPDF_Stream* FPDFDOC_GetAnnotAPNoFallback(CPDF_Dictionary* pAnnotDict,
                                           CPDF_Annot::AppearanceMode eMode);
 
 #endif  // CORE_FPDFDOC_CPDF_ANNOT_H_
diff --git a/core/fpdfdoc/cpdf_bookmark.cpp b/core/fpdfdoc/cpdf_bookmark.cpp
index 3237580..89dbbf8 100644
--- a/core/fpdfdoc/cpdf_bookmark.cpp
+++ b/core/fpdfdoc/cpdf_bookmark.cpp
@@ -50,7 +50,7 @@
   if (!m_pDict)
     return WideString();
 
-  CPDF_String* pString = ToString(m_pDict->GetDirectObjectFor("Title"));
+  const CPDF_String* pString = ToString(m_pDict->GetDirectObjectFor("Title"));
   if (!pString)
     return WideString();
 
@@ -71,7 +71,7 @@
   if (!m_pDict)
     return CPDF_Dest();
 
-  CPDF_Object* pDest = m_pDict->GetDirectObjectFor("Dest");
+  const CPDF_Object* pDest = m_pDict->GetDirectObjectFor("Dest");
   if (!pDest)
     return CPDF_Dest();
   if (pDest->IsString() || pDest->IsName()) {
@@ -79,7 +79,7 @@
     return CPDF_Dest(
         name_tree.LookupNamedDest(pDocument, pDest->GetUnicodeText()));
   }
-  if (CPDF_Array* pArray = pDest->AsArray())
+  if (const CPDF_Array* pArray = pDest->AsArray())
     return CPDF_Dest(pArray);
   return CPDF_Dest();
 }
diff --git a/core/fpdfdoc/cpdf_dest.cpp b/core/fpdfdoc/cpdf_dest.cpp
index e787dcd..58d0ac2 100644
--- a/core/fpdfdoc/cpdf_dest.cpp
+++ b/core/fpdfdoc/cpdf_dest.cpp
@@ -34,16 +34,16 @@
 
 CPDF_Dest::CPDF_Dest(const CPDF_Dest& that) = default;
 
-CPDF_Dest::CPDF_Dest(CPDF_Array* pObj) : m_pObj(pObj) {}
+CPDF_Dest::CPDF_Dest(const CPDF_Array* pObj) : m_pObj(pObj) {}
 
 CPDF_Dest::~CPDF_Dest() {}
 
 int CPDF_Dest::GetPageIndexDeprecated(CPDF_Document* pDoc) const {
-  CPDF_Array* pArray = ToArray(m_pObj.Get());
+  const CPDF_Array* pArray = ToArray(m_pObj.Get());
   if (!pArray)
     return 0;
 
-  CPDF_Object* pPage = pArray->GetDirectObjectAt(0);
+  const CPDF_Object* pPage = pArray->GetDirectObjectAt(0);
   if (!pPage)
     return 0;
 
@@ -57,11 +57,11 @@
 }
 
 int CPDF_Dest::GetDestPageIndex(CPDF_Document* pDoc) const {
-  CPDF_Array* pArray = ToArray(m_pObj.Get());
+  const CPDF_Array* pArray = ToArray(m_pObj.Get());
   if (!pArray)
     return -1;
 
-  CPDF_Object* pPage = pArray->GetDirectObjectAt(0);
+  const CPDF_Object* pPage = pArray->GetDirectObjectAt(0);
   if (!pPage)
     return -1;
 
@@ -75,11 +75,11 @@
 }
 
 uint32_t CPDF_Dest::GetPageObjNum() const {
-  CPDF_Array* pArray = ToArray(m_pObj.Get());
+  const CPDF_Array* pArray = ToArray(m_pObj.Get());
   if (!pArray)
     return 0;
 
-  CPDF_Object* pPage = pArray->GetDirectObjectAt(0);
+  const CPDF_Object* pPage = pArray->GetDirectObjectAt(0);
   if (!pPage)
     return 0;
   if (pPage->IsNumber())
@@ -90,11 +90,11 @@
 }
 
 int CPDF_Dest::GetZoomMode() const {
-  CPDF_Array* pArray = ToArray(m_pObj.Get());
+  const CPDF_Array* pArray = ToArray(m_pObj.Get());
   if (!pArray)
     return 0;
 
-  CPDF_Object* pObj = pArray->GetDirectObjectAt(1);
+  const CPDF_Object* pObj = pArray->GetDirectObjectAt(1);
   if (!pObj)
     return 0;
 
@@ -117,7 +117,7 @@
   *pHasY = false;
   *pHasZoom = false;
 
-  CPDF_Array* pArray = ToArray(m_pObj.Get());
+  const CPDF_Array* pArray = ToArray(m_pObj.Get());
   if (!pArray)
     return false;
 
@@ -155,7 +155,7 @@
 }
 
 unsigned long CPDF_Dest::GetNumParams() const {
-  CPDF_Array* pArray = ToArray(m_pObj.Get());
+  const CPDF_Array* pArray = ToArray(m_pObj.Get());
   if (!pArray || pArray->GetCount() < 2)
     return 0;
 
@@ -165,7 +165,7 @@
 }
 
 float CPDF_Dest::GetParam(int index) const {
-  CPDF_Array* pArray = ToArray(m_pObj.Get());
+  const CPDF_Array* pArray = ToArray(m_pObj.Get());
   return pArray ? pArray->GetNumberAt(2 + index) : 0;
 }
 
diff --git a/core/fpdfdoc/cpdf_dest.h b/core/fpdfdoc/cpdf_dest.h
index 9f9f087..7f4eb86c 100644
--- a/core/fpdfdoc/cpdf_dest.h
+++ b/core/fpdfdoc/cpdf_dest.h
@@ -18,10 +18,10 @@
  public:
   CPDF_Dest();
   CPDF_Dest(const CPDF_Dest& that);
-  explicit CPDF_Dest(CPDF_Array* pObj);
+  explicit CPDF_Dest(const CPDF_Array* pObj);
   ~CPDF_Dest();
 
-  CPDF_Array* GetObject() const { return m_pObj.Get(); }
+  const CPDF_Array* GetObject() const { return m_pObj.Get(); }
   ByteString GetRemoteName() const;
 
   // Deprecated. Use GetDestPageIndex instead.
@@ -46,7 +46,7 @@
               float* pZoom) const;
 
  private:
-  UnownedPtr<CPDF_Array> m_pObj;
+  UnownedPtr<const CPDF_Array> const m_pObj;
 };
 
 #endif  // CORE_FPDFDOC_CPDF_DEST_H_
diff --git a/core/fpdfdoc/cpdf_filespec.cpp b/core/fpdfdoc/cpdf_filespec.cpp
index e741ac6..88abea3 100644
--- a/core/fpdfdoc/cpdf_filespec.cpp
+++ b/core/fpdfdoc/cpdf_filespec.cpp
@@ -19,6 +19,10 @@
 
 namespace {
 
+// List of keys to check for the file specification string.
+// Follows the same precedence order as GetFileName().
+constexpr const char* kKeys[] = {"UF", "F", "DOS", "Mac", "Unix"};
+
 #if _FX_PLATFORM_ == _FX_PLATFORM_APPLE_ || \
     _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_
 WideString ChangeSlashToPlatform(const wchar_t* str) {
@@ -54,7 +58,12 @@
 
 }  // namespace
 
-CPDF_FileSpec::CPDF_FileSpec(CPDF_Object* pObj) : m_pObj(pObj) {
+CPDF_FileSpec::CPDF_FileSpec(const CPDF_Object* pObj) : m_pObj(pObj) {
+  ASSERT(m_pObj);
+}
+
+CPDF_FileSpec::CPDF_FileSpec(CPDF_Object* pObj)
+    : m_pObj(pObj), m_pWritableObj(pObj) {
   ASSERT(m_pObj);
 }
 
@@ -92,7 +101,7 @@
 
 WideString CPDF_FileSpec::GetFileName() const {
   WideString csFileName;
-  if (CPDF_Dictionary* pDict = m_pObj->AsDictionary()) {
+  if (const CPDF_Dictionary* pDict = m_pObj->AsDictionary()) {
     csFileName = pDict->GetUnicodeTextFor("UF");
     if (csFileName.IsEmpty()) {
       csFileName = WideString::FromLocal(
@@ -117,8 +126,30 @@
   return DecodeFileName(csFileName);
 }
 
-CPDF_Stream* CPDF_FileSpec::GetFileStream() const {
-  CPDF_Dictionary* pDict = m_pObj->AsDictionary();
+const CPDF_Stream* CPDF_FileSpec::GetFileStream() const {
+  const CPDF_Dictionary* pDict = m_pObj->AsDictionary();
+  if (!pDict)
+    return nullptr;
+
+  // Get the embedded files dictionary.
+  const CPDF_Dictionary* pFiles = pDict->GetDictFor("EF");
+  if (!pFiles)
+    return nullptr;
+
+  size_t end = pDict->GetStringFor("FS") == "URL" ? 2 : FX_ArraySize(kKeys);
+  for (size_t i = 0; i < end; ++i) {
+    const ByteString& key = kKeys[i];
+    if (!pDict->GetUnicodeTextFor(key).IsEmpty()) {
+      const CPDF_Stream* pStream = pFiles->GetStreamFor(key);
+      if (pStream)
+        return pStream;
+    }
+  }
+  return nullptr;
+}
+
+CPDF_Stream* CPDF_FileSpec::GetFileStream() {
+  CPDF_Dictionary* pDict = m_pWritableObj->AsDictionary();
   if (!pDict)
     return nullptr;
 
@@ -127,12 +158,9 @@
   if (!pFiles)
     return nullptr;
 
-  // Get the file stream of the highest precedence with its file specification
-  // string available. Follows the same precedence order as GetFileName().
-  constexpr const char* keys[] = {"UF", "F", "DOS", "Mac", "Unix"};
-  size_t end = pDict->GetStringFor("FS") == "URL" ? 2 : FX_ArraySize(keys);
+  size_t end = pDict->GetStringFor("FS") == "URL" ? 2 : FX_ArraySize(kKeys);
   for (size_t i = 0; i < end; ++i) {
-    const ByteString& key = keys[i];
+    const ByteString& key = kKeys[i];
     if (!pDict->GetUnicodeTextFor(key).IsEmpty()) {
       CPDF_Stream* pStream = pFiles->GetStreamFor(key);
       if (pStream)
@@ -142,16 +170,22 @@
   return nullptr;
 }
 
-CPDF_Dictionary* CPDF_FileSpec::GetParamsDict() const {
+const CPDF_Dictionary* CPDF_FileSpec::GetParamsDict() const {
+  const CPDF_Stream* pStream = GetFileStream();
+  if (!pStream)
+    return nullptr;
+
+  const CPDF_Dictionary* pDict = pStream->GetDict();
+  return pDict ? pDict->GetDictFor("Params") : nullptr;
+}
+
+CPDF_Dictionary* CPDF_FileSpec::GetParamsDict() {
   CPDF_Stream* pStream = GetFileStream();
   if (!pStream)
     return nullptr;
 
   CPDF_Dictionary* pDict = pStream->GetDict();
-  if (!pDict)
-    return nullptr;
-
-  return pDict->GetDictFor("Params");
+  return pDict ? pDict->GetDictFor("Params") : nullptr;
 }
 
 WideString CPDF_FileSpec::EncodeFileName(const WideString& filepath) {
@@ -184,10 +218,15 @@
 }
 
 void CPDF_FileSpec::SetFileName(const WideString& wsFileName) {
+  if (!m_pWritableObj) {
+    NOTREACHED();
+    return;
+  }
+
   WideString wsStr = EncodeFileName(wsFileName);
   if (m_pObj->IsString()) {
-    m_pObj->SetString(ByteString::FromUnicode(wsStr));
-  } else if (CPDF_Dictionary* pDict = m_pObj->AsDictionary()) {
+    m_pWritableObj->SetString(ByteString::FromUnicode(wsStr));
+  } else if (CPDF_Dictionary* pDict = m_pWritableObj->AsDictionary()) {
     pDict->SetNewFor<CPDF_String>(pdfium::stream::kF,
                                   ByteString::FromUnicode(wsStr), false);
     pDict->SetNewFor<CPDF_String>("UF", PDF_EncodeText(wsStr), false);
diff --git a/core/fpdfdoc/cpdf_filespec.h b/core/fpdfdoc/cpdf_filespec.h
index deeccb9..7050f69 100644
--- a/core/fpdfdoc/cpdf_filespec.h
+++ b/core/fpdfdoc/cpdf_filespec.h
@@ -18,6 +18,7 @@
 
 class CPDF_FileSpec {
  public:
+  explicit CPDF_FileSpec(const CPDF_Object* pObj);
   explicit CPDF_FileSpec(CPDF_Object* pObj);
   ~CPDF_FileSpec();
 
@@ -27,16 +28,20 @@
   // Convert a pdf file name into platform dependent format.
   static WideString DecodeFileName(const WideString& filepath);
 
-  CPDF_Object* GetObj() const { return m_pObj.Get(); }
+  const CPDF_Object* GetObj() const { return m_pObj.Get(); }
+  CPDF_Object* GetObj() { return m_pWritableObj.Get(); }
   WideString GetFileName() const;
-  CPDF_Stream* GetFileStream() const;
-  CPDF_Dictionary* GetParamsDict() const;
+  const CPDF_Stream* GetFileStream() const;
+  CPDF_Stream* GetFileStream();
+  const CPDF_Dictionary* GetParamsDict() const;
+  CPDF_Dictionary* GetParamsDict();
 
   // Set this file spec to refer to a file name (not a url).
   void SetFileName(const WideString& wsFileName);
 
  private:
-  UnownedPtr<CPDF_Object> const m_pObj;
+  UnownedPtr<const CPDF_Object> const m_pObj;
+  UnownedPtr<CPDF_Object> const m_pWritableObj;
 };
 
 #endif  // CORE_FPDFDOC_CPDF_FILESPEC_H_
diff --git a/core/fpdfdoc/cpdf_formfield.cpp b/core/fpdfdoc/cpdf_formfield.cpp
index acad073..8dcc9e6 100644
--- a/core/fpdfdoc/cpdf_formfield.cpp
+++ b/core/fpdfdoc/cpdf_formfield.cpp
@@ -37,6 +37,8 @@
 const int kFormTextNoScroll = 0x400;
 const int kFormTextComb = 0x800;
 
+constexpr int kGetFieldMaxRecursion = 32;
+
 bool IsUnison(CPDF_FormField* pField) {
   if (pField->GetType() == CPDF_FormField::CheckBox)
     return true;
@@ -53,10 +55,23 @@
   return {};
 }
 
-CPDF_Object* FPDF_GetFieldAttr(const CPDF_Dictionary* pFieldDict,
+const CPDF_Object* FPDF_GetFieldAttr(const CPDF_Dictionary* pFieldDict,
+                                     const char* name,
+                                     int nLevel) {
+  if (!pFieldDict || nLevel > kGetFieldMaxRecursion)
+    return nullptr;
+
+  const CPDF_Object* pAttr = pFieldDict->GetDirectObjectFor(name);
+  if (pAttr)
+    return pAttr;
+
+  const CPDF_Dictionary* pParent = pFieldDict->GetDictFor("Parent");
+  return pParent ? FPDF_GetFieldAttr(pParent, name, nLevel + 1) : nullptr;
+}
+
+CPDF_Object* FPDF_GetFieldAttr(CPDF_Dictionary* pFieldDict,
                                const char* name,
                                int nLevel) {
-  static constexpr int kGetFieldMaxRecursion = 32;
   if (!pFieldDict || nLevel > kGetFieldMaxRecursion)
     return nullptr;
 
@@ -64,7 +79,7 @@
   if (pAttr)
     return pAttr;
 
-  const CPDF_Dictionary* pParent = pFieldDict->GetDictFor("Parent");
+  CPDF_Dictionary* pParent = pFieldDict->GetDictFor("Parent");
   return pParent ? FPDF_GetFieldAttr(pParent, name, nLevel + 1) : nullptr;
 }
 
@@ -100,9 +115,9 @@
 CPDF_FormField::~CPDF_FormField() {}
 
 void CPDF_FormField::SyncFieldFlags() {
-  CPDF_Object* ft_attr = FPDF_GetFieldAttr(m_pDict.Get(), "FT");
+  const CPDF_Object* ft_attr = FPDF_GetFieldAttr(m_pDict.Get(), "FT");
   ByteString type_name = ft_attr ? ft_attr->GetString() : ByteString();
-  CPDF_Object* ff_attr = FPDF_GetFieldAttr(m_pDict.Get(), "Ff");
+  const CPDF_Object* ff_attr = FPDF_GetFieldAttr(m_pDict.Get(), "Ff");
   uint32_t flags = ff_attr ? ff_attr->GetInteger() : 0;
   m_Flags = 0;
   if (flags & FORMFLAG_READONLY)
@@ -196,17 +211,17 @@
     case CPDF_FormField::RichText:
     case CPDF_FormField::File:
     default: {
-      CPDF_Object* pDV = FPDF_GetFieldAttr(m_pDict.Get(), "DV");
+      const CPDF_Object* pDV = FPDF_GetFieldAttr(m_pDict.Get(), "DV");
       WideString csDValue;
       if (pDV)
         csDValue = pDV->GetUnicodeText();
 
-      CPDF_Object* pV = FPDF_GetFieldAttr(m_pDict.Get(), "V");
+      const CPDF_Object* pV = FPDF_GetFieldAttr(m_pDict.Get(), "V");
       WideString csValue;
       if (pV)
         csValue = pV->GetUnicodeText();
 
-      CPDF_Object* pRV = FPDF_GetFieldAttr(m_pDict.Get(), "RV");
+      const CPDF_Object* pRV = FPDF_GetFieldAttr(m_pDict.Get(), "RV");
       if (!pRV && (csDValue == csValue))
         return false;
 
@@ -265,27 +280,27 @@
 }
 
 CPDF_AAction CPDF_FormField::GetAdditionalAction() const {
-  CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict.Get(), "AA");
+  const CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict.Get(), "AA");
   return CPDF_AAction(pObj ? pObj->GetDict() : nullptr);
 }
 
 WideString CPDF_FormField::GetAlternateName() const {
-  CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict.Get(), "TU");
+  const CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict.Get(), "TU");
   return pObj ? pObj->GetUnicodeText() : L"";
 }
 
 WideString CPDF_FormField::GetMappingName() const {
-  CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict.Get(), "TM");
+  const CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict.Get(), "TM");
   return pObj ? pObj->GetUnicodeText() : L"";
 }
 
 uint32_t CPDF_FormField::GetFieldFlags() const {
-  CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict.Get(), "Ff");
+  const CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict.Get(), "Ff");
   return pObj ? pObj->GetInteger() : 0;
 }
 
 ByteString CPDF_FormField::GetDefaultStyle() const {
-  CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict.Get(), "DS");
+  const CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict.Get(), "DS");
   return pObj ? pObj->GetString() : "";
 }
 
@@ -293,7 +308,8 @@
   if (GetType() == CheckBox || GetType() == RadioButton)
     return GetCheckValue(bDefault);
 
-  CPDF_Object* pValue = FPDF_GetFieldAttr(m_pDict.Get(), bDefault ? "DV" : "V");
+  const CPDF_Object* pValue =
+      FPDF_GetFieldAttr(m_pDict.Get(), bDefault ? "DV" : "V");
   if (!pValue) {
     if (!bDefault) {
       if (m_Type == RichText)
@@ -394,7 +410,7 @@
 }
 
 int CPDF_FormField::GetMaxLen() const {
-  if (CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict.Get(), "MaxLen"))
+  if (const CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict.Get(), "MaxLen"))
     return pObj->GetInteger();
 
   for (auto& pControl : m_ControlList) {
@@ -408,7 +424,7 @@
 }
 
 int CPDF_FormField::CountSelectedItems() const {
-  CPDF_Object* pValue = FPDF_GetFieldAttr(m_pDict.Get(), "V");
+  const CPDF_Object* pValue = FPDF_GetFieldAttr(m_pDict.Get(), "V");
   if (!pValue) {
     pValue = FPDF_GetFieldAttr(m_pDict.Get(), "I");
     if (!pValue)
@@ -417,13 +433,12 @@
 
   if (pValue->IsString() || pValue->IsNumber())
     return pValue->GetString().IsEmpty() ? 0 : 1;
-  if (CPDF_Array* pArray = pValue->AsArray())
-    return pArray->GetCount();
-  return 0;
+  const CPDF_Array* pArray = pValue->AsArray();
+  return pArray ? pArray->GetCount() : 0;
 }
 
 int CPDF_FormField::GetSelectedIndex(int index) const {
-  CPDF_Object* pValue = FPDF_GetFieldAttr(m_pDict.Get(), "V");
+  const CPDF_Object* pValue = FPDF_GetFieldAttr(m_pDict.Get(), "V");
   if (!pValue) {
     pValue = FPDF_GetFieldAttr(m_pDict.Get(), "I");
     if (!pValue)
@@ -438,11 +453,11 @@
       return -1;
     sel_value = pValue->GetUnicodeText();
   } else {
-    CPDF_Array* pArray = pValue->AsArray();
+    const CPDF_Array* pArray = pValue->AsArray();
     if (!pArray || index < 0)
       return -1;
 
-    CPDF_Object* elementValue = pArray->GetDirectObjectAt(index);
+    const CPDF_Object* elementValue = pArray->GetDirectObjectAt(index);
     sel_value = elementValue ? elementValue->GetUnicodeText() : WideString();
   }
   if (index < CountSelectedOptions()) {
@@ -483,7 +498,7 @@
     return true;
 
   WideString opt_value = GetOptionValue(index);
-  CPDF_Object* pValue = FPDF_GetFieldAttr(m_pDict.Get(), "V");
+  const CPDF_Object* pValue = FPDF_GetFieldAttr(m_pDict.Get(), "V");
   if (!pValue) {
     pValue = FPDF_GetFieldAttr(m_pDict.Get(), "I");
     if (!pValue)
@@ -499,7 +514,7 @@
     return (pValue->GetInteger() == index);
   }
 
-  CPDF_Array* pArray = pValue->AsArray();
+  const CPDF_Array* pArray = pValue->AsArray();
   if (!pArray)
     return false;
 
@@ -547,7 +562,7 @@
       pI->AddNew<CPDF_Number>(index);
     }
   } else {
-    CPDF_Object* pValue = FPDF_GetFieldAttr(m_pDict.Get(), "V");
+    const CPDF_Object* pValue = FPDF_GetFieldAttr(m_pDict.Get(), "V");
     if (pValue) {
       if (GetType() == ListBox) {
         SelectOption(index, false);
@@ -586,7 +601,7 @@
 
 int CPDF_FormField::GetDefaultSelectedItem() const {
   ASSERT(GetType() == ComboBox || GetType() == ListBox);
-  CPDF_Object* pValue = FPDF_GetFieldAttr(m_pDict.Get(), "DV");
+  const CPDF_Object* pValue = FPDF_GetFieldAttr(m_pDict.Get(), "DV");
   if (!pValue)
     return -1;
   WideString csDV = pValue->GetUnicodeText();
@@ -600,22 +615,22 @@
 }
 
 int CPDF_FormField::CountOptions() const {
-  CPDF_Array* pArray = ToArray(FPDF_GetFieldAttr(m_pDict.Get(), "Opt"));
+  const CPDF_Array* pArray = ToArray(FPDF_GetFieldAttr(m_pDict.Get(), "Opt"));
   return pArray ? pArray->GetCount() : 0;
 }
 
 WideString CPDF_FormField::GetOptionText(int index, int sub_index) const {
-  CPDF_Array* pArray = ToArray(FPDF_GetFieldAttr(m_pDict.Get(), "Opt"));
+  const CPDF_Array* pArray = ToArray(FPDF_GetFieldAttr(m_pDict.Get(), "Opt"));
   if (!pArray)
     return WideString();
 
-  CPDF_Object* pOption = pArray->GetDirectObjectAt(index);
+  const CPDF_Object* pOption = pArray->GetDirectObjectAt(index);
   if (!pOption)
     return WideString();
-  if (CPDF_Array* pOptionArray = pOption->AsArray())
+  if (const CPDF_Array* pOptionArray = pOption->AsArray())
     pOption = pOptionArray->GetDirectObjectAt(sub_index);
 
-  CPDF_String* pString = ToString(pOption);
+  const CPDF_String* pString = ToString(pOption);
   return pString ? pString->GetUnicodeText() : WideString();
 }
 
@@ -677,13 +692,13 @@
     }
   }
 
-  CPDF_Object* pOpt = FPDF_GetFieldAttr(m_pDict.Get(), "Opt");
+  const CPDF_Object* pOpt = FPDF_GetFieldAttr(m_pDict.Get(), "Opt");
   if (!ToArray(pOpt)) {
     if (bChecked) {
       m_pDict->SetNewFor<CPDF_Name>("V", csBExport);
     } else {
       ByteString csV;
-      CPDF_Object* pV = FPDF_GetFieldAttr(m_pDict.Get(), "V");
+      const CPDF_Object* pV = FPDF_GetFieldAttr(m_pDict.Get(), "V");
       if (pV)
         csV = pV->GetString();
       if (csV == csBExport)
@@ -733,17 +748,17 @@
 }
 
 int CPDF_FormField::GetTopVisibleIndex() const {
-  CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict.Get(), "TI");
+  const CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict.Get(), "TI");
   return pObj ? pObj->GetInteger() : 0;
 }
 
 int CPDF_FormField::CountSelectedOptions() const {
-  CPDF_Array* pArray = ToArray(FPDF_GetFieldAttr(m_pDict.Get(), "I"));
+  const CPDF_Array* pArray = ToArray(FPDF_GetFieldAttr(m_pDict.Get(), "I"));
   return pArray ? pArray->GetCount() : 0;
 }
 
 int CPDF_FormField::GetSelectedOptionIndex(int index) const {
-  CPDF_Array* pArray = ToArray(FPDF_GetFieldAttr(m_pDict.Get(), "I"));
+  const CPDF_Array* pArray = ToArray(FPDF_GetFieldAttr(m_pDict.Get(), "I"));
   if (!pArray)
     return -1;
 
@@ -754,7 +769,7 @@
 }
 
 bool CPDF_FormField::IsOptionSelected(int iOptIndex) const {
-  CPDF_Array* pArray = ToArray(FPDF_GetFieldAttr(m_pDict.Get(), "I"));
+  const CPDF_Array* pArray = ToArray(FPDF_GetFieldAttr(m_pDict.Get(), "I"));
   if (!pArray)
     return false;
 
@@ -841,7 +856,7 @@
     return;
 
   ByteString DA;
-  if (CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict.Get(), "DA"))
+  if (const CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict.Get(), "DA"))
     DA = pObj->GetString();
 
   if (DA.IsEmpty())
diff --git a/core/fpdfdoc/cpdf_formfield.h b/core/fpdfdoc/cpdf_formfield.h
index 315ca76..29ff714 100644
--- a/core/fpdfdoc/cpdf_formfield.h
+++ b/core/fpdfdoc/cpdf_formfield.h
@@ -79,9 +79,13 @@
 class CPDF_InterForm;
 class CPDF_String;
 
-CPDF_Object* FPDF_GetFieldAttr(const CPDF_Dictionary* pFieldDict,
+const CPDF_Object* FPDF_GetFieldAttr(const CPDF_Dictionary* pFieldDict,
+                                     const char* name,
+                                     int nLevel = 0);
+CPDF_Object* FPDF_GetFieldAttr(CPDF_Dictionary* pFieldDict,
                                const char* name,
                                int nLevel = 0);
+
 WideString FPDF_GetFullName(CPDF_Dictionary* pFieldDict);
 
 class CPDF_FormField {
@@ -167,6 +171,8 @@
   CPDF_Font* GetFont() const { return m_pFont.Get(); }
 
   const CPDF_Dictionary* GetDict() const { return m_pDict.Get(); }
+  CPDF_Dictionary* GetDict() { return m_pDict.Get(); }
+
   const CPDF_InterForm* GetForm() const { return m_pForm.Get(); }
 
   WideString GetCheckValue(bool bDefault) const;
diff --git a/core/fpdfdoc/cpdf_interform.cpp b/core/fpdfdoc/cpdf_interform.cpp
index 83df36b..ad7753b 100644
--- a/core/fpdfdoc/cpdf_interform.cpp
+++ b/core/fpdfdoc/cpdf_interform.cpp
@@ -1142,32 +1142,33 @@
     if (dwFlags & 0x04)
       continue;
 
-    if (bIncludeOrExclude == pdfium::ContainsValue(fields, pField)) {
-      if ((dwFlags & 0x02) != 0 &&
-          pField->GetDict()->GetStringFor("V").IsEmpty()) {
-        continue;
-      }
+    if (bIncludeOrExclude != pdfium::ContainsValue(fields, pField))
+      continue;
 
-      WideString fullname = FPDF_GetFullName(pField->GetFieldDict());
-      auto pFieldDict =
-          pdfium::MakeUnique<CPDF_Dictionary>(pDoc->GetByteStringPool());
-      pFieldDict->SetNewFor<CPDF_String>("T", fullname);
-      if (pField->GetType() == CPDF_FormField::CheckBox ||
-          pField->GetType() == CPDF_FormField::RadioButton) {
-        WideString csExport = pField->GetCheckValue(false);
-        ByteString csBExport = PDF_EncodeText(csExport);
-        CPDF_Object* pOpt = FPDF_GetFieldAttr(pField->GetDict(), "Opt");
-        if (pOpt)
-          pFieldDict->SetNewFor<CPDF_String>("V", csBExport, false);
-        else
-          pFieldDict->SetNewFor<CPDF_Name>("V", csBExport);
-      } else {
-        CPDF_Object* pV = FPDF_GetFieldAttr(pField->GetDict(), "V");
-        if (pV)
-          pFieldDict->SetFor("V", pV->CloneDirectObject());
-      }
-      pFields->Add(std::move(pFieldDict));
+    if ((dwFlags & 0x02) != 0 &&
+        pField->GetDict()->GetStringFor("V").IsEmpty()) {
+      continue;
     }
+
+    WideString fullname = FPDF_GetFullName(pField->GetFieldDict());
+    auto pFieldDict =
+        pdfium::MakeUnique<CPDF_Dictionary>(pDoc->GetByteStringPool());
+    pFieldDict->SetNewFor<CPDF_String>("T", fullname);
+    if (pField->GetType() == CPDF_FormField::CheckBox ||
+        pField->GetType() == CPDF_FormField::RadioButton) {
+      WideString csExport = pField->GetCheckValue(false);
+      ByteString csBExport = PDF_EncodeText(csExport);
+      CPDF_Object* pOpt = FPDF_GetFieldAttr(pField->GetDict(), "Opt");
+      if (pOpt)
+        pFieldDict->SetNewFor<CPDF_String>("V", csBExport, false);
+      else
+        pFieldDict->SetNewFor<CPDF_Name>("V", csBExport);
+    } else {
+      CPDF_Object* pV = FPDF_GetFieldAttr(pField->GetDict(), "V");
+      if (pV)
+        pFieldDict->SetFor("V", pV->CloneDirectObject());
+    }
+    pFields->Add(std::move(pFieldDict));
   }
   return pDoc;
 }
diff --git a/core/fpdfdoc/cpdf_occontext.cpp b/core/fpdfdoc/cpdf_occontext.cpp
index 192a254..2aac213 100644
--- a/core/fpdfdoc/cpdf_occontext.cpp
+++ b/core/fpdfdoc/cpdf_occontext.cpp
@@ -26,12 +26,12 @@
 bool HasIntent(const CPDF_Dictionary* pDict,
                const ByteStringView& csElement,
                const ByteStringView& csDef) {
-  CPDF_Object* pIntent = pDict->GetDirectObjectFor("Intent");
+  const CPDF_Object* pIntent = pDict->GetDirectObjectFor("Intent");
   if (!pIntent)
     return csElement == csDef;
 
   ByteString bsIntent;
-  if (CPDF_Array* pArray = pIntent->AsArray()) {
+  if (const CPDF_Array* pArray = pIntent->AsArray()) {
     for (size_t i = 0; i < pArray->GetCount(); i++) {
       bsIntent = pArray->GetStringAt(i);
       if (bsIntent == "All" || bsIntent == csElement)
@@ -242,14 +242,14 @@
     return GetOCGVE(pVE, 0);
 
   ByteString csP = pOCMDDict->GetStringFor("P", "AnyOn");
-  CPDF_Object* pOCGObj = pOCMDDict->GetDirectObjectFor("OCGs");
+  const CPDF_Object* pOCGObj = pOCMDDict->GetDirectObjectFor("OCGs");
   if (!pOCGObj)
     return true;
 
   if (const CPDF_Dictionary* pDict = pOCGObj->AsDictionary())
     return GetOCGVisible(pDict);
 
-  CPDF_Array* pArray = pOCGObj->AsArray();
+  const CPDF_Array* pArray = pOCGObj->AsArray();
   if (!pArray)
     return true;
 
@@ -259,7 +259,7 @@
   bool bValidEntrySeen = false;
   for (size_t i = 0; i < pArray->GetCount(); i++) {
     bool bItem = true;
-    CPDF_Dictionary* pItemDict = pArray->GetDictAt(i);
+    const CPDF_Dictionary* pItemDict = pArray->GetDictAt(i);
     if (!pItemDict)
       continue;
 
diff --git a/core/fpdfdoc/cpdf_structelement.cpp b/core/fpdfdoc/cpdf_structelement.cpp
index ed5c8c7..24c028f 100644
--- a/core/fpdfdoc/cpdf_structelement.cpp
+++ b/core/fpdfdoc/cpdf_structelement.cpp
@@ -59,15 +59,15 @@
   if (const CPDF_Reference* pRef = ToReference(pObj))
     PageObjNum = pRef->GetRefObjNum();
 
-  CPDF_Object* pKids = pDict->GetDirectObjectFor("K");
+  const CPDF_Object* pKids = pDict->GetDirectObjectFor("K");
   if (!pKids)
     return;
 
   m_Kids.clear();
-  if (CPDF_Array* pArray = pKids->AsArray()) {
+  if (const CPDF_Array* pArray = pKids->AsArray()) {
     m_Kids.resize(pArray->GetCount());
     for (uint32_t i = 0; i < pArray->GetCount(); i++) {
-      CPDF_Object* pKid = pArray->GetDirectObjectAt(i);
+      const CPDF_Object* pKid = pArray->GetDirectObjectAt(i);
       LoadKid(PageObjNum, pKid, &m_Kids[i]);
     }
     return;
@@ -78,7 +78,7 @@
 }
 
 void CPDF_StructElement::LoadKid(uint32_t PageObjNum,
-                                 CPDF_Object* pKidObj,
+                                 const CPDF_Object* pKidObj,
                                  CPDF_StructKid* pKid) {
   pKid->m_Type = CPDF_StructKid::Invalid;
   if (!pKidObj)
@@ -94,10 +94,10 @@
     return;
   }
 
-  CPDF_Dictionary* pKidDict = pKidObj->AsDictionary();
+  const CPDF_Dictionary* pKidDict = pKidObj->AsDictionary();
   if (!pKidDict)
     return;
-  if (CPDF_Reference* pRef = ToReference(pKidDict->GetObjectFor("Pg")))
+  if (const CPDF_Reference* pRef = ToReference(pKidDict->GetObjectFor("Pg")))
     PageObjNum = pRef->GetRefObjNum();
 
   ByteString type = pKidDict->GetStringFor("Type");
@@ -108,7 +108,7 @@
 
   if (type == "MCR") {
     pKid->m_Type = CPDF_StructKid::StreamContent;
-    CPDF_Reference* pRef = ToReference(pKidDict->GetObjectFor("Stm"));
+    const CPDF_Reference* pRef = ToReference(pKidDict->GetObjectFor("Stm"));
     pKid->m_RefObjNum = pRef ? pRef->GetRefObjNum() : 0;
     pKid->m_PageObjNum = PageObjNum;
     pKid->m_ContentId = pKidDict->GetIntegerFor("MCID");
@@ -117,7 +117,7 @@
 
   if (type == "OBJR") {
     pKid->m_Type = CPDF_StructKid::Object;
-    CPDF_Reference* pObj = ToReference(pKidDict->GetObjectFor("Obj"));
+    const CPDF_Reference* pObj = ToReference(pKidDict->GetObjectFor("Obj"));
     pKid->m_RefObjNum = pObj ? pObj->GetRefObjNum() : 0;
     pKid->m_PageObjNum = PageObjNum;
     return;
diff --git a/core/fpdfdoc/cpdf_structelement.h b/core/fpdfdoc/cpdf_structelement.h
index 2586d9c..4e590cb 100644
--- a/core/fpdfdoc/cpdf_structelement.h
+++ b/core/fpdfdoc/cpdf_structelement.h
@@ -54,7 +54,9 @@
   ~CPDF_StructElement() override;
 
   void LoadKids(const CPDF_Dictionary* pDict);
-  void LoadKid(uint32_t PageObjNum, CPDF_Object* pObj, CPDF_StructKid* pKid);
+  void LoadKid(uint32_t PageObjNum,
+               const CPDF_Object* pObj,
+               CPDF_StructKid* pKid);
 
   UnownedPtr<CPDF_StructTree> const m_pTree;
   UnownedPtr<CPDF_StructElement> const m_pParent;
diff --git a/core/fpdfdoc/cpdf_structtree.cpp b/core/fpdfdoc/cpdf_structtree.cpp
index 1e4d08a..d0a6787 100644
--- a/core/fpdfdoc/cpdf_structtree.cpp
+++ b/core/fpdfdoc/cpdf_structtree.cpp
@@ -47,14 +47,14 @@
   if (!m_pTreeRoot)
     return;
 
-  CPDF_Object* pKids = m_pTreeRoot->GetDirectObjectFor("K");
+  const CPDF_Object* pKids = m_pTreeRoot->GetDirectObjectFor("K");
   if (!pKids)
     return;
 
   uint32_t dwKids = 0;
   if (pKids->IsDictionary())
     dwKids = 1;
-  else if (CPDF_Array* pArray = pKids->AsArray())
+  else if (const CPDF_Array* pArray = pKids->AsArray())
     dwKids = pArray->GetCount();
   else
     return;
@@ -119,7 +119,7 @@
 bool CPDF_StructTree::AddTopLevelNode(
     const CPDF_Dictionary* pDict,
     const RetainPtr<CPDF_StructElement>& pElement) {
-  CPDF_Object* pObj = m_pTreeRoot->GetDirectObjectFor("K");
+  const CPDF_Object* pObj = m_pTreeRoot->GetDirectObjectFor("K");
   if (!pObj)
     return false;
 
@@ -129,13 +129,13 @@
     m_Kids[0] = pElement;
   }
 
-  CPDF_Array* pTopKids = pObj->AsArray();
+  const CPDF_Array* pTopKids = pObj->AsArray();
   if (!pTopKids)
     return true;
 
   bool bSave = false;
   for (size_t i = 0; i < pTopKids->GetCount(); i++) {
-    CPDF_Reference* pKidRef = ToReference(pTopKids->GetObjectAt(i));
+    const CPDF_Reference* pKidRef = ToReference(pTopKids->GetObjectAt(i));
     if (pKidRef && pKidRef->GetRefObjNum() == pDict->GetObjNum()) {
       m_Kids[i] = pElement;
       bSave = true;
diff --git a/fpdfsdk/cpdfsdk_helpers.cpp b/fpdfsdk/cpdfsdk_helpers.cpp
index 5773a8b..76e5449 100644
--- a/fpdfsdk/cpdfsdk_helpers.cpp
+++ b/fpdfsdk/cpdfsdk_helpers.cpp
@@ -333,7 +333,7 @@
     uint8_t* decoded_data = nullptr;
     uint32_t decoded_len = 0;
     ByteString dummy_last_decoder;
-    CPDF_Dictionary* dummy_last_param;
+    const CPDF_Dictionary* dummy_last_param;
     if (PDF_DataDecode(data, len, dict,
                        dict->GetIntegerFor(pdfium::stream::kDL), false,
                        &decoded_data, &decoded_len, &dummy_last_decoder,
diff --git a/fpdfsdk/cpdfsdk_helpers.h b/fpdfsdk/cpdfsdk_helpers.h
index ba54645..fae7ef0 100644
--- a/fpdfsdk/cpdfsdk_helpers.h
+++ b/fpdfsdk/cpdfsdk_helpers.h
@@ -110,11 +110,11 @@
   return reinterpret_cast<CPDF_ClipPath*>(path);
 }
 
-inline FPDF_DEST FPDFDestFromCPDFArray(CPDF_Array* dest) {
+inline FPDF_DEST FPDFDestFromCPDFArray(const CPDF_Array* dest) {
   return reinterpret_cast<FPDF_DEST>(dest);
 }
-inline CPDF_Array* CPDFArrayFromFPDFDest(FPDF_DEST dest) {
-  return reinterpret_cast<CPDF_Array*>(dest);
+inline const CPDF_Array* CPDFArrayFromFPDFDest(FPDF_DEST dest) {
+  return reinterpret_cast<const CPDF_Array*>(dest);
 }
 
 inline FPDF_FONT FPDFFontFromCPDFFont(CPDF_Font* font) {
diff --git a/fpdfsdk/formfiller/cba_fontmap.cpp b/fpdfsdk/formfiller/cba_fontmap.cpp
index d219ca4..671ba92 100644
--- a/fpdfsdk/formfiller/cba_fontmap.cpp
+++ b/fpdfsdk/formfiller/cba_fontmap.cpp
@@ -203,7 +203,7 @@
   }
 
   ByteString sDA;
-  CPDF_Object* pObj = FPDF_GetFieldAttr(m_pAnnotDict.Get(), "DA");
+  const CPDF_Object* pObj = FPDF_GetFieldAttr(m_pAnnotDict.Get(), "DA");
   if (pObj)
     sDA = pObj->GetString();
 
diff --git a/fpdfsdk/fpdf_annot.cpp b/fpdfsdk/fpdf_annot.cpp
index d3bf38d..1fa71f2 100644
--- a/fpdfsdk/fpdf_annot.cpp
+++ b/fpdfsdk/fpdf_annot.cpp
@@ -142,7 +142,7 @@
                   FPDF_OBJECT_REFERENCE,
               "CPDF_Object::REFERENCE value mismatch");
 
-bool HasAPStream(const CPDF_Dictionary* pAnnotDict) {
+bool HasAPStream(CPDF_Dictionary* pAnnotDict) {
   return !!FPDFDOC_GetAnnotAP(pAnnotDict, CPDF_Annot::AppearanceMode::Normal);
 }
 
@@ -188,7 +188,7 @@
   array->AddNew<CPDF_Number>(quad_points->y4);
 }
 
-void UpdateBBox(const CPDF_Dictionary* annot_dict) {
+void UpdateBBox(CPDF_Dictionary* annot_dict) {
   // Update BBox entry in appearance stream based on the bounding rectangle
   // of the annotation's quadpoints.
   CPDF_Stream* pStream =
diff --git a/fpdfsdk/fpdf_ext.cpp b/fpdfsdk/fpdf_ext.cpp
index 509cfe8..6a2ab06 100644
--- a/fpdfsdk/fpdf_ext.cpp
+++ b/fpdfsdk/fpdf_ext.cpp
@@ -85,7 +85,7 @@
   if (!pRoot)
     return PAGEMODE_UNKNOWN;
 
-  CPDF_Object* pName = pRoot->GetObjectFor("PageMode");
+  const CPDF_Object* pName = pRoot->GetObjectFor("PageMode");
   if (!pName)
     return PAGEMODE_USENONE;
 
diff --git a/fpdfsdk/fpdf_structtree.cpp b/fpdfsdk/fpdf_structtree.cpp
index d39f808..206a08e 100644
--- a/fpdfsdk/fpdf_structtree.cpp
+++ b/fpdfsdk/fpdf_structtree.cpp
@@ -84,7 +84,7 @@
 FPDF_StructElement_GetMarkedContentID(FPDF_STRUCTELEMENT struct_element) {
   CPDF_StructElement* elem =
       CPDFStructElementFromFPDFStructElement(struct_element);
-  CPDF_Object* p =
+  const CPDF_Object* p =
       (elem && elem->GetDict()) ? elem->GetDict()->GetObjectFor("K") : nullptr;
   return p && p->IsNumber() ? p->GetInteger() : -1;
 }
diff --git a/public/fpdfview.h b/public/fpdfview.h
index a3017b4..de0421e 100644
--- a/public/fpdfview.h
+++ b/public/fpdfview.h
@@ -41,7 +41,7 @@
 typedef struct fpdf_bitmap_t__* FPDF_BITMAP;
 typedef const struct fpdf_bookmark_t__* FPDF_BOOKMARK;
 typedef struct fpdf_clippath_t__* FPDF_CLIPPATH;
-typedef struct fpdf_dest_t__* FPDF_DEST;
+typedef const struct fpdf_dest_t__* FPDF_DEST;
 typedef struct fpdf_document_t__* FPDF_DOCUMENT;
 typedef struct fpdf_font_t__* FPDF_FONT;
 typedef struct fpdf_link_t__* FPDF_LINK;