Return retained reference from CPDF_Dictionary::GetDirectObjectFor().

Change-Id: I8af5e0ecddfc4619521bf1f2962beb72b1803ec7
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/97612
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fpdfapi/edit/cpdf_creator.cpp b/core/fpdfapi/edit/cpdf_creator.cpp
index 6c05051..74edaf5 100644
--- a/core/fpdfapi/edit/cpdf_creator.cpp
+++ b/core/fpdfapi/edit/cpdf_creator.cpp
@@ -216,7 +216,7 @@
       m_IsIncremental = false;
 
     const CPDF_Dictionary* pDict = m_pDocument->GetRoot();
-    m_pMetadata.Reset(pDict ? pDict->GetDirectObjectFor("Metadata") : nullptr);
+    m_pMetadata = pDict ? pDict->GetDirectObjectFor("Metadata") : nullptr;
     m_iStage = Stage::kWriteHeader10;
   }
   if (m_iStage == Stage::kWriteHeader10) {
diff --git a/core/fpdfapi/font/cpdf_cidfont.cpp b/core/fpdfapi/font/cpdf_cidfont.cpp
index 1ff59fd..c90c15f 100644
--- a/core/fpdfapi/font/cpdf_cidfont.cpp
+++ b/core/fpdfapi/font/cpdf_cidfont.cpp
@@ -422,7 +422,8 @@
     m_bAdobeCourierStd = true;
   }
 
-  const CPDF_Object* pEncoding = m_pFontDict->GetDirectObjectFor("Encoding");
+  RetainPtr<const CPDF_Object> pEncoding =
+      m_pFontDict->GetDirectObjectFor("Encoding");
   if (!pEncoding)
     return false;
 
@@ -474,7 +475,8 @@
   if (!IsEmbedded())
     LoadSubstFont();
 
-  const CPDF_Object* pmap = pCIDFontDict->GetDirectObjectFor("CIDToGIDMap");
+  RetainPtr<const CPDF_Object> pmap =
+      pCIDFontDict->GetDirectObjectFor("CIDToGIDMap");
   if (pmap) {
     const CPDF_Stream* pMapStream = pmap->AsStream();
     if (pMapStream) {
diff --git a/core/fpdfapi/font/cpdf_simplefont.cpp b/core/fpdfapi/font/cpdf_simplefont.cpp
index dcdff59..450f264 100644
--- a/core/fpdfapi/font/cpdf_simplefont.cpp
+++ b/core/fpdfapi/font/cpdf_simplefont.cpp
@@ -152,7 +152,8 @@
 }
 
 void CPDF_SimpleFont::LoadPDFEncoding(bool bEmbedded, bool bTrueType) {
-  const CPDF_Object* pEncoding = m_pFontDict->GetDirectObjectFor("Encoding");
+  RetainPtr<const CPDF_Object> pEncoding =
+      m_pFontDict->GetDirectObjectFor("Encoding");
   if (!pEncoding) {
     if (m_BaseFontName == "Symbol") {
       m_BaseEncoding =
diff --git a/core/fpdfapi/page/cpdf_colorspace.cpp b/core/fpdfapi/page/cpdf_colorspace.cpp
index 1561aa4..a27c6ef 100644
--- a/core/fpdfapi/page/cpdf_colorspace.cpp
+++ b/core/fpdfapi/page/cpdf_colorspace.cpp
@@ -1046,11 +1046,12 @@
     const CPDF_Dictionary* pDict,
     std::set<const CPDF_Object*>* pVisited,
     uint32_t nExpectedComponents) {
-  const CPDF_Object* pAlterCSObj = pDict->GetDirectObjectFor("Alternate");
+  RetainPtr<const CPDF_Object> pAlterCSObj =
+      pDict->GetDirectObjectFor("Alternate");
   if (!pAlterCSObj)
     return false;
 
-  auto pAlterCS = CPDF_ColorSpace::Load(pDoc, pAlterCSObj, pVisited);
+  auto pAlterCS = CPDF_ColorSpace::Load(pDoc, pAlterCSObj.Get(), pVisited);
   if (!pAlterCS)
     return false;
 
diff --git a/core/fpdfapi/page/cpdf_dib.cpp b/core/fpdfapi/page/cpdf_dib.cpp
index f6256c9..548143f 100644
--- a/core/fpdfapi/page/cpdf_dib.cpp
+++ b/core/fpdfapi/page/cpdf_dib.cpp
@@ -344,15 +344,16 @@
     return true;
   }
 
-  const CPDF_Object* pCSObj = m_pDict->GetDirectObjectFor("ColorSpace");
+  RetainPtr<const CPDF_Object> pCSObj =
+      m_pDict->GetDirectObjectFor("ColorSpace");
   if (!pCSObj)
     return false;
 
   auto* pDocPageData = CPDF_DocPageData::FromDocument(m_pDocument.Get());
   if (pFormResources)
-    m_pColorSpace = pDocPageData->GetColorSpace(pCSObj, pFormResources);
+    m_pColorSpace = pDocPageData->GetColorSpace(pCSObj.Get(), pFormResources);
   if (!m_pColorSpace)
-    m_pColorSpace = pDocPageData->GetColorSpace(pCSObj, pPageResources);
+    m_pColorSpace = pDocPageData->GetColorSpace(pCSObj.Get(), pPageResources);
   if (!m_pColorSpace)
     return false;
 
@@ -417,7 +418,7 @@
   if (m_pDict->KeyExist("SMask"))
     return true;
 
-  const CPDF_Object* pMask = m_pDict->GetDirectObjectFor("Mask");
+  RetainPtr<const CPDF_Object> pMask = m_pDict->GetDirectObjectFor("Mask");
   if (!pMask)
     return true;
 
@@ -751,7 +752,7 @@
 
   RetainPtr<const CPDF_Stream> mask(m_pDict->GetStreamFor("SMask"));
   if (!mask) {
-    mask.Reset(ToStream(m_pDict->GetDirectObjectFor("Mask")));
+    mask = ToStream(m_pDict->GetDirectObjectFor("Mask"));
     return mask ? StartLoadMaskDIB(std::move(mask)) : LoadState::kSuccess;
   }
 
diff --git a/core/fpdfapi/page/cpdf_docpagedata.cpp b/core/fpdfapi/page/cpdf_docpagedata.cpp
index d2198f7..1a62218 100644
--- a/core/fpdfapi/page/cpdf_docpagedata.cpp
+++ b/core/fpdfapi/page/cpdf_docpagedata.cpp
@@ -274,8 +274,8 @@
     if (!pCS && pResources) {
       const CPDF_Dictionary* pList = pResources->GetDictFor("ColorSpace");
       if (pList) {
-        return GetColorSpaceInternal(pList->GetDirectObjectFor(name), nullptr,
-                                     pVisited, pVisitedInternal);
+        return GetColorSpaceInternal(pList->GetDirectObjectFor(name).Get(),
+                                     nullptr, pVisited, pVisitedInternal);
       }
     }
     if (!pCS || !pResources)
@@ -285,7 +285,7 @@
     if (!pColorSpaces)
       return pCS;
 
-    const CPDF_Object* pDefaultCS = nullptr;
+    RetainPtr<const CPDF_Object> pDefaultCS;
     switch (pCS->GetFamily()) {
       case CPDF_ColorSpace::Family::kDeviceRGB:
         pDefaultCS = pColorSpaces->GetDirectObjectFor("DefaultRGB");
@@ -302,7 +302,7 @@
     if (!pDefaultCS)
       return pCS;
 
-    return GetColorSpaceInternal(pDefaultCS, nullptr, pVisited,
+    return GetColorSpaceInternal(pDefaultCS.Get(), nullptr, pVisited,
                                  pVisitedInternal);
   }
 
diff --git a/core/fpdfapi/page/cpdf_occontext.cpp b/core/fpdfapi/page/cpdf_occontext.cpp
index 19bdc4f..341558b 100644
--- a/core/fpdfapi/page/cpdf_occontext.cpp
+++ b/core/fpdfapi/page/cpdf_occontext.cpp
@@ -17,7 +17,7 @@
 bool HasIntent(const CPDF_Dictionary* pDict,
                ByteStringView csElement,
                ByteStringView csDef) {
-  const CPDF_Object* pIntent = pDict->GetDirectObjectFor("Intent");
+  RetainPtr<const CPDF_Object> pIntent = pDict->GetDirectObjectFor("Intent");
   if (!pIntent)
     return csElement == csDef;
 
@@ -233,7 +233,7 @@
     return GetOCGVE(pVE, 0);
 
   ByteString csP = pOCMDDict->GetStringFor("P", "AnyOn");
-  const CPDF_Object* pOCGObj = pOCMDDict->GetDirectObjectFor("OCGs");
+  RetainPtr<const CPDF_Object> pOCGObj = pOCMDDict->GetDirectObjectFor("OCGs");
   if (!pOCGObj)
     return true;
 
diff --git a/core/fpdfapi/page/cpdf_page.cpp b/core/fpdfapi/page/cpdf_page.cpp
index f8cbb1b..63eb328 100644
--- a/core/fpdfapi/page/cpdf_page.cpp
+++ b/core/fpdfapi/page/cpdf_page.cpp
@@ -82,10 +82,11 @@
   std::set<const CPDF_Dictionary*> visited;
   const CPDF_Dictionary* pPageDict = GetDict();
   while (pPageDict && !pdfium::Contains(visited, pPageDict)) {
-    const CPDF_Object* pObj = pPageDict->GetDirectObjectFor(name);
-    if (pObj)
-      return pObj;
-
+    RetainPtr<const CPDF_Object> pObj = pPageDict->GetDirectObjectFor(name);
+    if (pObj) {
+      // TODO(tsepez): return retained objects.
+      return pObj.Get();
+    }
     visited.insert(pPageDict);
     pPageDict = pPageDict->GetDictFor(pdfium::page_object::kParent);
   }
diff --git a/core/fpdfapi/page/cpdf_shadingpattern.cpp b/core/fpdfapi/page/cpdf_shadingpattern.cpp
index 81a0439..a155120 100644
--- a/core/fpdfapi/page/cpdf_shadingpattern.cpp
+++ b/core/fpdfapi/page/cpdf_shadingpattern.cpp
@@ -56,7 +56,8 @@
     return false;
 
   m_pFunctions.clear();
-  const CPDF_Object* pFunc = pShadingDict->GetDirectObjectFor("Function");
+  RetainPtr<const CPDF_Object> pFunc =
+      pShadingDict->GetDirectObjectFor("Function");
   if (pFunc) {
     if (const CPDF_Array* pArray = pFunc->AsArray()) {
       m_pFunctions.resize(std::min<size_t>(pArray->size(), 4));
@@ -65,15 +66,17 @@
             CPDF_Function::Load(pArray->GetDirectObjectAt(i).Get());
       }
     } else {
-      m_pFunctions.push_back(CPDF_Function::Load(pFunc));
+      // TODO(tsepez): pass retained argumments to load.
+      m_pFunctions.push_back(CPDF_Function::Load(pFunc.Get()));
     }
   }
-  const CPDF_Object* pCSObj = pShadingDict->GetDirectObjectFor("ColorSpace");
+  RetainPtr<const CPDF_Object> pCSObj =
+      pShadingDict->GetDirectObjectFor("ColorSpace");
   if (!pCSObj)
     return false;
 
   auto* pDocPageData = CPDF_DocPageData::FromDocument(document());
-  m_pCS = pDocPageData->GetColorSpace(pCSObj, nullptr);
+  m_pCS = pDocPageData->GetColorSpace(pCSObj.Get(), nullptr);
 
   // The color space is required and cannot be a Pattern space, according to the
   // PDF 1.7 spec, page 305.
@@ -85,8 +88,9 @@
 }
 
 const CPDF_Object* CPDF_ShadingPattern::GetShadingObject() const {
-  return m_bShading ? pattern_obj()
-                    : pattern_obj()->GetDict()->GetDirectObjectFor("Shading");
+  return m_bShading
+             ? pattern_obj()
+             : pattern_obj()->GetDict()->GetDirectObjectFor("Shading").Get();
 }
 
 bool CPDF_ShadingPattern::Validate() const {
diff --git a/core/fpdfapi/page/cpdf_streamcontentparser.cpp b/core/fpdfapi/page/cpdf_streamcontentparser.cpp
index 078c172..b6ec661 100644
--- a/core/fpdfapi/page/cpdf_streamcontentparser.cpp
+++ b/core/fpdfapi/page/cpdf_streamcontentparser.cpp
@@ -623,7 +623,7 @@
     }
   }
   ReplaceAbbr(pDict.Get());
-  const CPDF_Object* pCSObj = nullptr;
+  RetainPtr<const CPDF_Object> pCSObj;
   if (pDict->KeyExist("ColorSpace")) {
     pCSObj = pDict->GetDirectObjectFor("ColorSpace");
     if (pCSObj->IsName()) {
@@ -636,8 +636,8 @@
     }
   }
   pDict->SetNewFor<CPDF_Name>("Subtype", "Image");
-  RetainPtr<CPDF_Stream> pStream =
-      m_pSyntax->ReadInlineStream(m_pDocument.Get(), std::move(pDict), pCSObj);
+  RetainPtr<CPDF_Stream> pStream = m_pSyntax->ReadInlineStream(
+      m_pDocument.Get(), std::move(pDict), pCSObj.Get());
   while (true) {
     CPDF_StreamParser::ElementType type = m_pSyntax->ParseNextElement();
     if (type == CPDF_StreamParser::ElementType::kEndOfData)
diff --git a/core/fpdfapi/page/cpdf_streamparser.cpp b/core/fpdfapi/page/cpdf_streamparser.cpp
index 033021f..04e0625 100644
--- a/core/fpdfapi/page/cpdf_streamparser.cpp
+++ b/core/fpdfapi/page/cpdf_streamparser.cpp
@@ -140,7 +140,7 @@
 
   ByteString decoder;
   RetainPtr<const CPDF_Dictionary> pParam;
-  const CPDF_Object* pFilter = pDict->GetDirectObjectFor("Filter");
+  RetainPtr<const CPDF_Object> pFilter = pDict->GetDirectObjectFor("Filter");
   if (pFilter) {
     const CPDF_Array* pArray = pFilter->AsArray();
     if (pArray) {
diff --git a/core/fpdfapi/parser/cpdf_crypto_handler.cpp b/core/fpdfapi/parser/cpdf_crypto_handler.cpp
index 14a841c..8ac08c7 100644
--- a/core/fpdfapi/parser/cpdf_crypto_handler.cpp
+++ b/core/fpdfapi/parser/cpdf_crypto_handler.cpp
@@ -38,7 +38,8 @@
     const CPDF_Dictionary* dictionary) {
   if (!dictionary)
     return false;
-  const CPDF_Object* type_obj = dictionary->GetDirectObjectFor(kTypeKey);
+  RetainPtr<const CPDF_Object> type_obj =
+      dictionary->GetDirectObjectFor(kTypeKey);
   if (!type_obj)
     type_obj = dictionary->GetDirectObjectFor(pdfium::form_fields::kFT);
   return type_obj && type_obj->GetString() == pdfium::form_fields::kSig;
diff --git a/core/fpdfapi/parser/cpdf_dictionary.cpp b/core/fpdfapi/parser/cpdf_dictionary.cpp
index a92ffea..63df92a 100644
--- a/core/fpdfapi/parser/cpdf_dictionary.cpp
+++ b/core/fpdfapi/parser/cpdf_dictionary.cpp
@@ -81,15 +81,15 @@
   return pdfium::WrapRetain(const_cast<CPDF_Object*>(GetObjectFor(key)));
 }
 
-const CPDF_Object* CPDF_Dictionary::GetDirectObjectFor(
+RetainPtr<const CPDF_Object> CPDF_Dictionary::GetDirectObjectFor(
     const ByteString& key) const {
-  const CPDF_Object* p = GetObjectFor(key);
-  return p ? p->GetDirect().Get() : nullptr;
+  return const_cast<CPDF_Dictionary*>(this)->GetMutableDirectObjectFor(key);
 }
 
 RetainPtr<CPDF_Object> CPDF_Dictionary::GetMutableDirectObjectFor(
     const ByteString& key) {
-  return pdfium::WrapRetain(const_cast<CPDF_Object*>(GetDirectObjectFor(key)));
+  RetainPtr<CPDF_Object> p = GetMutableObjectFor(key);
+  return p ? p->GetMutableDirect() : nullptr;
 }
 
 ByteString CPDF_Dictionary::GetStringFor(const ByteString& key) const {
@@ -143,7 +143,7 @@
 
 const CPDF_Dictionary* CPDF_Dictionary::GetDictFor(
     const ByteString& key) const {
-  const CPDF_Object* p = GetDirectObjectFor(key);
+  RetainPtr<const CPDF_Object> p = GetDirectObjectFor(key);
   if (!p)
     return nullptr;
   if (const CPDF_Dictionary* pDict = p->AsDictionary())
@@ -167,7 +167,7 @@
 }
 
 const CPDF_Array* CPDF_Dictionary::GetArrayFor(const ByteString& key) const {
-  return ToArray(GetDirectObjectFor(key));
+  return ToArray(GetDirectObjectFor(key).Get());
 }
 
 RetainPtr<CPDF_Array> CPDF_Dictionary::GetMutableArrayFor(
@@ -184,7 +184,7 @@
 }
 
 const CPDF_Stream* CPDF_Dictionary::GetStreamFor(const ByteString& key) const {
-  return ToStream(GetDirectObjectFor(key));
+  return ToStream(GetDirectObjectFor(key).Get());
 }
 
 RetainPtr<CPDF_Stream> CPDF_Dictionary::GetMutableStreamFor(
diff --git a/core/fpdfapi/parser/cpdf_dictionary.h b/core/fpdfapi/parser/cpdf_dictionary.h
index 77d9e37..e6966e7 100644
--- a/core/fpdfapi/parser/cpdf_dictionary.h
+++ b/core/fpdfapi/parser/cpdf_dictionary.h
@@ -46,7 +46,7 @@
   const CPDF_Object* GetObjectFor(const ByteString& key) const;
   RetainPtr<CPDF_Object> GetMutableObjectFor(const ByteString& key);
 
-  const CPDF_Object* GetDirectObjectFor(const ByteString& key) const;
+  RetainPtr<const CPDF_Object> GetDirectObjectFor(const ByteString& key) const;
   RetainPtr<CPDF_Object> GetMutableDirectObjectFor(const ByteString& key);
 
   // These will return the string representation of the object specified by
diff --git a/core/fpdfapi/parser/cpdf_object_unittest.cpp b/core/fpdfapi/parser/cpdf_object_unittest.cpp
index 8c25fb9..9ab64b9 100644
--- a/core/fpdfapi/parser/cpdf_object_unittest.cpp
+++ b/core/fpdfapi/parser/cpdf_object_unittest.cpp
@@ -1007,7 +1007,7 @@
   CPDF_Object* pObj = dict->SetNewFor<CPDF_Number>("clams", 42);
   dict->ConvertToIndirectObjectFor("clams", &objects_holder);
   const CPDF_Object* pRef = dict->GetObjectFor("clams");
-  const CPDF_Object* pNum = dict->GetDirectObjectFor("clams");
+  RetainPtr<const CPDF_Object> pNum = dict->GetDirectObjectFor("clams");
   EXPECT_TRUE(pRef->IsReference());
   EXPECT_TRUE(pNum->IsNumber());
   EXPECT_NE(pObj, pRef);
diff --git a/core/fpdfapi/parser/cpdf_syntax_parser.cpp b/core/fpdfapi/parser/cpdf_syntax_parser.cpp
index ad1880d..c3a01cb 100644
--- a/core/fpdfapi/parser/cpdf_syntax_parser.cpp
+++ b/core/fpdfapi/parser/cpdf_syntax_parser.cpp
@@ -707,7 +707,8 @@
 
 RetainPtr<CPDF_Stream> CPDF_SyntaxParser::ReadStream(
     RetainPtr<CPDF_Dictionary> pDict) {
-  const CPDF_Number* pLenObj = ToNumber(pDict->GetDirectObjectFor("Length"));
+  RetainPtr<const CPDF_Number> pLenObj =
+      ToNumber(pDict->GetDirectObjectFor("Length"));
   FX_FILESIZE len = pLenObj ? pLenObj->GetInteger() : -1;
 
   // Locate the start of stream.
diff --git a/core/fpdfapi/parser/fpdf_parser_decode.cpp b/core/fpdfapi/parser/fpdf_parser_decode.cpp
index d150bfe..d25df9d 100644
--- a/core/fpdfapi/parser/fpdf_parser_decode.cpp
+++ b/core/fpdfapi/parser/fpdf_parser_decode.cpp
@@ -365,14 +365,14 @@
 }
 
 absl::optional<DecoderArray> GetDecoderArray(const CPDF_Dictionary* pDict) {
-  const CPDF_Object* pFilter = pDict->GetDirectObjectFor("Filter");
+  RetainPtr<const CPDF_Object> pFilter = pDict->GetDirectObjectFor("Filter");
   if (!pFilter)
     return DecoderArray();
 
   if (!pFilter->IsArray() && !pFilter->IsName())
     return absl::nullopt;
 
-  const CPDF_Object* pParams =
+  RetainPtr<const CPDF_Object> pParams =
       pDict->GetDirectObjectFor(pdfium::stream::kDecodeParms);
 
   DecoderArray decoder_array;
@@ -380,7 +380,7 @@
     if (!ValidateDecoderPipeline(pDecoders))
       return absl::nullopt;
 
-    const CPDF_Array* pParamsArray = ToArray(pParams);
+    RetainPtr<const CPDF_Array> pParamsArray = ToArray(pParams);
     for (size_t i = 0; i < pDecoders->size(); ++i) {
       // TODO(tsepez): push retained arguments.
       decoder_array.push_back(
diff --git a/core/fpdfapi/render/cpdf_imagerenderer.cpp b/core/fpdfapi/render/cpdf_imagerenderer.cpp
index 0a558ad..3a7830e 100644
--- a/core/fpdfapi/render/cpdf_imagerenderer.cpp
+++ b/core/fpdfapi/render/cpdf_imagerenderer.cpp
@@ -171,10 +171,11 @@
       pPage ? pPage->GetPageResources() : nullptr;
   const CPDF_Dictionary* pStreamDict =
       m_pImageObject->GetImage()->GetStream()->GetDict();
-  const CPDF_Object* pCSObj = pStreamDict->GetDirectObjectFor("ColorSpace");
+  RetainPtr<const CPDF_Object> pCSObj =
+      pStreamDict->GetDirectObjectFor("ColorSpace");
   auto* pData = CPDF_DocPageData::FromDocument(pDocument);
   RetainPtr<CPDF_ColorSpace> pColorSpace =
-      pData->GetColorSpace(pCSObj, pPageResources);
+      pData->GetColorSpace(pCSObj.Get(), pPageResources);
   if (pColorSpace) {
     CPDF_ColorSpace::Family format = pColorSpace->GetFamily();
     if (format == CPDF_ColorSpace::Family::kDeviceCMYK ||
diff --git a/core/fpdfapi/render/cpdf_renderstatus.cpp b/core/fpdfapi/render/cpdf_renderstatus.cpp
index 9bf9b53..6eb286d 100644
--- a/core/fpdfapi/render/cpdf_renderstatus.cpp
+++ b/core/fpdfapi/render/cpdf_renderstatus.cpp
@@ -1404,10 +1404,10 @@
     return nullptr;
 
   std::unique_ptr<CPDF_Function> pFunc;
-  const CPDF_Object* pFuncObj =
+  RetainPtr<const CPDF_Object> pFuncObj =
       pSMaskDict->GetDirectObjectFor(pdfium::transparency::kTR);
   if (pFuncObj && (pFuncObj->IsDictionary() || pFuncObj->IsStream()))
-    pFunc = CPDF_Function::Load(pFuncObj);
+    pFunc = CPDF_Function::Load(pFuncObj.Get());
 
   CFX_Matrix matrix = mtMatrix;
   matrix.Translate(-pClipRect->left, -pClipRect->top);
@@ -1500,14 +1500,14 @@
   if (!pBC)
     return kDefaultColor;
 
-  const CPDF_Object* pCSObj = nullptr;
+  RetainPtr<const CPDF_Object> pCSObj;
   const CPDF_Dictionary* pGroup =
       pGroupDict ? pGroupDict->GetDictFor("Group") : nullptr;
   if (pGroup)
     pCSObj = pGroup->GetDirectObjectFor(pdfium::transparency::kCS);
   RetainPtr<CPDF_ColorSpace> pCS =
       CPDF_DocPageData::FromDocument(m_pContext->GetDocument())
-          ->GetColorSpace(pCSObj, nullptr);
+          ->GetColorSpace(pCSObj.Get(), nullptr);
   if (!pCS)
     return kDefaultColor;
 
diff --git a/core/fpdfdoc/cpdf_action.cpp b/core/fpdfdoc/cpdf_action.cpp
index 77df25d..1aff394 100644
--- a/core/fpdfdoc/cpdf_action.cpp
+++ b/core/fpdfdoc/cpdf_action.cpp
@@ -66,9 +66,10 @@
     return WideString();
   }
 
-  const CPDF_Object* pFile = m_pDict->GetDirectObjectFor(pdfium::stream::kF);
+  RetainPtr<const CPDF_Object> pFile =
+      m_pDict->GetDirectObjectFor(pdfium::stream::kF);
   if (pFile)
-    return CPDF_FileSpec(pFile).GetFileName();
+    return CPDF_FileSpec(pFile.Get()).GetFileName();
 
   if (type != Type::kLaunch)
     return WideString();
@@ -91,7 +92,7 @@
   if (pURI) {
     auto result = csURI.Find(":");
     if (!result.has_value() || result.value() == 0) {
-      auto* pBase = pURI->GetDirectObjectFor("Base");
+      RetainPtr<const CPDF_Object> pBase = pURI->GetDirectObjectFor("Base");
       if (pBase && (pBase->IsString() || pBase->IsStream()))
         csURI = pBase->GetString() + csURI;
     }
@@ -118,7 +119,7 @@
 
   ByteString csType = m_pDict->GetStringFor("S");
   const CPDF_Object* pFields = csType == "Hide"
-                                   ? m_pDict->GetDirectObjectFor("T")
+                                   ? m_pDict->GetDirectObjectFor("T").Get()
                                    : m_pDict->GetArrayFor("Fields");
   if (!pFields)
     return result;
@@ -153,7 +154,7 @@
   if (!m_pDict || !m_pDict->KeyExist("Next"))
     return 0;
 
-  const CPDF_Object* pNext = m_pDict->GetDirectObjectFor("Next");
+  RetainPtr<const CPDF_Object> pNext = m_pDict->GetDirectObjectFor("Next");
   if (!pNext)
     return 0;
   if (pNext->IsDictionary())
@@ -166,12 +167,15 @@
   if (!m_pDict || !m_pDict->KeyExist("Next"))
     return CPDF_Action(nullptr);
 
-  const CPDF_Object* pNext = m_pDict->GetDirectObjectFor("Next");
-  if (const CPDF_Array* pArray = ToArray(pNext)) {
+  RetainPtr<const CPDF_Object> pNext = m_pDict->GetDirectObjectFor("Next");
+  if (!pNext)
+    return CPDF_Action(nullptr);
+
+  if (const CPDF_Array* pArray = pNext->AsArray()) {
     // TODO(tsepez): Actions should take retained arguments.
     return CPDF_Action(pArray->GetDictAt(iIndex).Get());
   }
-  if (const CPDF_Dictionary* pDict = ToDictionary(pNext)) {
+  if (const CPDF_Dictionary* pDict = pNext->AsDictionary()) {
     if (iIndex == 0)
       return CPDF_Action(pDict);
   }
@@ -182,6 +186,8 @@
   if (!m_pDict)
     return nullptr;
 
-  const CPDF_Object* pJS = m_pDict->GetDirectObjectFor("JS");
-  return (pJS && (pJS->IsString() || pJS->IsStream())) ? pJS : nullptr;
+  RetainPtr<const CPDF_Object> pJS = m_pDict->GetDirectObjectFor("JS");
+
+  // TODO(tsepez): return retained references.
+  return (pJS && (pJS->IsString() || pJS->IsStream())) ? pJS.Get() : nullptr;
 }
diff --git a/core/fpdfdoc/cpdf_bookmark.cpp b/core/fpdfdoc/cpdf_bookmark.cpp
index 75e4936..41d8ef9 100644
--- a/core/fpdfdoc/cpdf_bookmark.cpp
+++ b/core/fpdfdoc/cpdf_bookmark.cpp
@@ -23,7 +23,8 @@
   if (!m_pDict)
     return WideString();
 
-  const CPDF_String* pString = ToString(m_pDict->GetDirectObjectFor("Title"));
+  RetainPtr<const CPDF_String> pString =
+      ToString(m_pDict->GetDirectObjectFor("Title"));
   if (!pString)
     return WideString();
 
diff --git a/core/fpdfdoc/cpdf_dest.cpp b/core/fpdfdoc/cpdf_dest.cpp
index 3636d70..5c9720f 100644
--- a/core/fpdfdoc/cpdf_dest.cpp
+++ b/core/fpdfdoc/cpdf_dest.cpp
@@ -37,7 +37,8 @@
 CPDF_Dest::~CPDF_Dest() = default;
 
 // static
-CPDF_Dest CPDF_Dest::Create(CPDF_Document* pDoc, const CPDF_Object* pDest) {
+CPDF_Dest CPDF_Dest::Create(CPDF_Document* pDoc,
+                            RetainPtr<const CPDF_Object> pDest) {
   if (!pDest)
     return CPDF_Dest(nullptr);
 
diff --git a/core/fpdfdoc/cpdf_dest.h b/core/fpdfdoc/cpdf_dest.h
index 98f51d0..75d93aa 100644
--- a/core/fpdfdoc/cpdf_dest.h
+++ b/core/fpdfdoc/cpdf_dest.h
@@ -20,7 +20,8 @@
   ~CPDF_Dest();
 
   // Use when |pDest| is an object of an unknown type. Can pass in nullptr.
-  static CPDF_Dest Create(CPDF_Document* pDoc, const CPDF_Object* pDest);
+  static CPDF_Dest Create(CPDF_Document* pDoc,
+                          RetainPtr<const CPDF_Object> pDest);
 
   const CPDF_Array* GetArray() const { return m_pArray.Get(); }
   int GetDestPageIndex(CPDF_Document* pDoc) const;
diff --git a/core/fpdfdoc/cpdf_filespec.cpp b/core/fpdfdoc/cpdf_filespec.cpp
index f1e574b..fda2978 100644
--- a/core/fpdfdoc/cpdf_filespec.cpp
+++ b/core/fpdfdoc/cpdf_filespec.cpp
@@ -95,11 +95,12 @@
 WideString CPDF_FileSpec::GetFileName() const {
   WideString csFileName;
   if (const CPDF_Dictionary* pDict = m_pObj->AsDictionary()) {
-    const CPDF_String* pUF = ToString(pDict->GetDirectObjectFor("UF"));
+    RetainPtr<const CPDF_String> pUF =
+        ToString(pDict->GetDirectObjectFor("UF"));
     if (pUF)
       csFileName = pUF->GetUnicodeText();
     if (csFileName.IsEmpty()) {
-      const CPDF_String* pK =
+      RetainPtr<const CPDF_String> pK =
           ToString(pDict->GetDirectObjectFor(pdfium::stream::kF));
       if (pK)
         csFileName = WideString::FromDefANSI(pK->GetString().AsStringView());
@@ -109,7 +110,8 @@
 
     if (csFileName.IsEmpty()) {
       for (const auto* key : {"DOS", "Mac", "Unix"}) {
-        const CPDF_String* pValue = ToString(pDict->GetDirectObjectFor(key));
+        RetainPtr<const CPDF_String> pValue =
+            ToString(pDict->GetDirectObjectFor(key));
         if (pValue) {
           csFileName =
               WideString::FromDefANSI(pValue->GetString().AsStringView());
diff --git a/core/fpdfdoc/cpdf_formfield.cpp b/core/fpdfdoc/cpdf_formfield.cpp
index dc98c66..a3569ec 100644
--- a/core/fpdfdoc/cpdf_formfield.cpp
+++ b/core/fpdfdoc/cpdf_formfield.cpp
@@ -40,7 +40,7 @@
   if (!pFieldDict || nLevel > kGetFieldMaxRecursion)
     return nullptr;
 
-  const CPDF_Object* pAttr = pFieldDict->GetDirectObjectFor(name);
+  const CPDF_Object* pAttr = pFieldDict->GetDirectObjectFor(name).Get();
   if (pAttr)
     return pAttr;
 
diff --git a/core/fpdfdoc/cpdf_interactiveform.cpp b/core/fpdfdoc/cpdf_interactiveform.cpp
index 11417d4..1a74750 100644
--- a/core/fpdfdoc/cpdf_interactiveform.cpp
+++ b/core/fpdfdoc/cpdf_interactiveform.cpp
@@ -823,14 +823,14 @@
     if (pParent && pParent != pFieldDict &&
         !pParent->KeyExist(pdfium::form_fields::kFT)) {
       if (pFieldDict->KeyExist(pdfium::form_fields::kFT)) {
-        const CPDF_Object* pFTValue =
+        RetainPtr<const CPDF_Object> pFTValue =
             pFieldDict->GetDirectObjectFor(pdfium::form_fields::kFT);
         if (pFTValue)
           pParent->SetFor(pdfium::form_fields::kFT, pFTValue->Clone());
       }
 
       if (pFieldDict->KeyExist(pdfium::form_fields::kFf)) {
-        const CPDF_Object* pFfValue =
+        RetainPtr<const CPDF_Object> pFfValue =
             pFieldDict->GetDirectObjectFor(pdfium::form_fields::kFf);
         if (pFfValue)
           pParent->SetFor(pdfium::form_fields::kFf, pFfValue->Clone());
diff --git a/core/fpdfdoc/cpdf_nametree.cpp b/core/fpdfdoc/cpdf_nametree.cpp
index be9e62b..e3f314d 100644
--- a/core/fpdfdoc/cpdf_nametree.cpp
+++ b/core/fpdfdoc/cpdf_nametree.cpp
@@ -399,9 +399,7 @@
   const CPDF_Dictionary* pDests = pDoc->GetRoot()->GetDictFor("Dests");
   if (!pDests)
     return nullptr;
-  // TODO(tsepez): return const retained objects from CPDF object getters.
-  return GetNamedDestFromObject(
-      pdfium::WrapRetain(pDests->GetDirectObjectFor(name)));
+  return GetNamedDestFromObject(pDests->GetDirectObjectFor(name));
 }
 
 }  // namespace
diff --git a/core/fpdfdoc/cpdf_structelement.cpp b/core/fpdfdoc/cpdf_structelement.cpp
index 5cb54ec..90e99c2 100644
--- a/core/fpdfdoc/cpdf_structelement.cpp
+++ b/core/fpdfdoc/cpdf_structelement.cpp
@@ -98,7 +98,7 @@
   if (const CPDF_Reference* pRef = ToReference(pObj))
     PageObjNum = pRef->GetRefObjNum();
 
-  const CPDF_Object* pKids = pDict->GetDirectObjectFor("K");
+  RetainPtr<const CPDF_Object> pKids = pDict->GetDirectObjectFor("K");
   if (!pKids)
     return;
 
@@ -115,7 +115,9 @@
   }
 
   m_Kids.resize(1);
-  LoadKid(PageObjNum, pKids, &m_Kids[0]);
+
+  // TODO(tsepez): pass retained arguments.
+  LoadKid(PageObjNum, pKids.Get(), &m_Kids[0]);
 }
 
 void CPDF_StructElement::LoadKid(uint32_t PageObjNum,
diff --git a/core/fpdfdoc/cpdf_structtree.cpp b/core/fpdfdoc/cpdf_structtree.cpp
index fdecd3b..d68a074 100644
--- a/core/fpdfdoc/cpdf_structtree.cpp
+++ b/core/fpdfdoc/cpdf_structtree.cpp
@@ -48,7 +48,7 @@
   if (!m_pTreeRoot)
     return;
 
-  const CPDF_Object* pKids = m_pTreeRoot->GetDirectObjectFor("K");
+  RetainPtr<const CPDF_Object> pKids = m_pTreeRoot->GetDirectObjectFor("K");
   if (!pKids)
     return;
 
@@ -122,7 +122,7 @@
 bool CPDF_StructTree::AddTopLevelNode(
     const CPDF_Dictionary* pDict,
     const RetainPtr<CPDF_StructElement>& pElement) {
-  const CPDF_Object* pObj = m_pTreeRoot->GetDirectObjectFor("K");
+  RetainPtr<const CPDF_Object> pObj = m_pTreeRoot->GetDirectObjectFor("K");
   if (!pObj)
     return false;
 
diff --git a/fpdfsdk/cpdfsdk_widget.cpp b/fpdfsdk/cpdfsdk_widget.cpp
index de23bd6..cc6df3f 100644
--- a/fpdfsdk/cpdfsdk_widget.cpp
+++ b/fpdfsdk/cpdfsdk_widget.cpp
@@ -357,7 +357,7 @@
     ap_entry = "N";
 
   // Get the AP stream or subdirectory
-  const CPDF_Object* pSub = pAP->GetDirectObjectFor(ap_entry);
+  RetainPtr<const CPDF_Object> pSub = pAP->GetDirectObjectFor(ap_entry);
   if (!pSub)
     return false;
 
diff --git a/fpdfsdk/fpdf_editimg.cpp b/fpdfsdk/fpdf_editimg.cpp
index 617a14b..0b63e5e 100644
--- a/fpdfsdk/fpdf_editimg.cpp
+++ b/fpdfsdk/fpdf_editimg.cpp
@@ -312,8 +312,10 @@
     return 0;
 
   const CPDF_Dictionary* pDict = pImg->GetDict();
-  const CPDF_Object* pFilter =
-      pDict ? pDict->GetDirectObjectFor("Filter") : nullptr;
+  if (!pDict)
+    return 0;
+
+  RetainPtr<const CPDF_Object> pFilter = pDict->GetDirectObjectFor("Filter");
   if (!pFilter)
     return 0;
 
@@ -336,7 +338,7 @@
 
   CPDF_PageObject* pObj = CPDFPageObjectFromFPDFPageObject(image_object);
   const CPDF_Dictionary* pDict = pObj->AsImage()->GetImage()->GetDict();
-  const CPDF_Object* pFilter = pDict->GetDirectObjectFor("Filter");
+  RetainPtr<const CPDF_Object> pFilter = pDict->GetDirectObjectFor("Filter");
   ByteString bsFilter = pFilter->IsName()
                             ? pFilter->AsName()->GetString()
                             : pFilter->AsArray()->GetStringAt(index);
diff --git a/fpdfsdk/fpdf_ppo.cpp b/fpdfsdk/fpdf_ppo.cpp
index 3e136dc..77ccc52 100644
--- a/fpdfsdk/fpdf_ppo.cpp
+++ b/fpdfsdk/fpdf_ppo.cpp
@@ -600,7 +600,7 @@
 CPDF_Stream* CPDF_NPageToOneExporter::MakeXObjectFromPageRaw(
     const RetainPtr<CPDF_Page>& pSrcPage) {
   const CPDF_Dictionary* pSrcPageDict = pSrcPage->GetDict();
-  const CPDF_Object* pSrcContentObj =
+  RetainPtr<const CPDF_Object> pSrcContentObj =
       pSrcPageDict->GetDirectObjectFor(pdfium::page_object::kContents);
 
   CPDF_Stream* pNewXObject = dest()->NewIndirect<CPDF_Stream>(
@@ -623,7 +623,7 @@
 
   if (pSrcContentObj) {
     ByteString bsSrcContentStream;
-    const CPDF_Array* pSrcContentArray = ToArray(pSrcContentObj);
+    const CPDF_Array* pSrcContentArray = pSrcContentObj->AsArray();
     if (pSrcContentArray) {
       for (size_t i = 0; i < pSrcContentArray->size(); ++i) {
         RetainPtr<const CPDF_Stream> pStream = pSrcContentArray->GetStreamAt(i);
diff --git a/fpdfsdk/fpdfxfa/cpdfxfa_context.cpp b/fpdfsdk/fpdfxfa/cpdfxfa_context.cpp
index 662bb0a..eb768cf 100644
--- a/fpdfsdk/fpdfxfa/cpdfxfa_context.cpp
+++ b/fpdfsdk/fpdfxfa/cpdfxfa_context.cpp
@@ -67,7 +67,8 @@
   if (!pAcroForm)
     return nullptr;
 
-  const CPDF_Object* pElementXFA = pAcroForm->GetDirectObjectFor("XFA");
+  RetainPtr<const CPDF_Object> pElementXFA =
+      pAcroForm->GetDirectObjectFor("XFA");
   if (!pElementXFA)
     return nullptr;