Return retained refs from CPDF_IndirectObjectHolder::NewIndirect<T>().

This cleans up some of the Reset() calls introduced in the previous CL.

-- use `auto` when type name is already on the same line.
-- Add a test that shows how UAF is possible otherwise.

Change-Id: I6d0437ccc6495c6b954f0e005b82aacaf0021128
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/98234
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
index 9afda3f..4ced722 100644
--- a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
+++ b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
@@ -180,7 +180,9 @@
     const ByteString& bsType) const {
   DCHECK(pResource);
   if (!m_pObjHolder->GetResources()) {
-    m_pObjHolder->SetResources(m_pDocument->NewIndirect<CPDF_Dictionary>());
+    // TODO(tsepez): pass retained argument.
+    m_pObjHolder->SetResources(
+        m_pDocument->NewIndirect<CPDF_Dictionary>().Get());
     m_pObjHolder->GetMutableDict()->SetNewFor<CPDF_Reference>(
         "Resources", m_pDocument.Get(),
         m_pObjHolder->GetResources()->GetObjNum());
diff --git a/core/fpdfapi/edit/cpdf_pagecontentgenerator_unittest.cpp b/core/fpdfapi/edit/cpdf_pagecontentgenerator_unittest.cpp
index 87d723a..934ade1 100644
--- a/core/fpdfapi/edit/cpdf_pagecontentgenerator_unittest.cpp
+++ b/core/fpdfapi/edit/cpdf_pagecontentgenerator_unittest.cpp
@@ -316,14 +316,14 @@
   {
     // Set the text object font and text
     auto pTextObj = std::make_unique<CPDF_TextObject>();
-    RetainPtr<CPDF_Dictionary> pDict(pDoc->NewIndirect<CPDF_Dictionary>());
+    auto pDict = pDoc->NewIndirect<CPDF_Dictionary>();
     pDict->SetNewFor<CPDF_Name>("Type", "Font");
     pDict->SetNewFor<CPDF_Name>("Subtype", "TrueType");
 
     RetainPtr<CPDF_Font> pFont = CPDF_Font::GetStockFont(pDoc.get(), "Arial");
     pDict->SetNewFor<CPDF_Name>("BaseFont", pFont->GetBaseFontName());
 
-    CPDF_Dictionary* pDesc = pDoc->NewIndirect<CPDF_Dictionary>();
+    auto pDesc = pDoc->NewIndirect<CPDF_Dictionary>();
     pDesc->SetNewFor<CPDF_Name>("Type", "FontDescriptor");
     pDesc->SetNewFor<CPDF_Name>("FontName", pFont->GetBaseFontName());
     pDict->SetNewFor<CPDF_Reference>("FontDescriptor", pDoc.get(),
diff --git a/core/fpdfapi/edit/cpdf_pagecontentmanager.cpp b/core/fpdfapi/edit/cpdf_pagecontentmanager.cpp
index 6d6ca0e..e2305ce 100644
--- a/core/fpdfapi/edit/cpdf_pagecontentmanager.cpp
+++ b/core/fpdfapi/edit/cpdf_pagecontentmanager.cpp
@@ -66,13 +66,13 @@
 }
 
 size_t CPDF_PageContentManager::AddStream(fxcrt::ostringstream* buf) {
-  CPDF_Stream* new_stream = doc_->NewIndirect<CPDF_Stream>();
+  auto new_stream = doc_->NewIndirect<CPDF_Stream>();
   new_stream->SetDataFromStringstream(buf);
 
   // If there is one Content stream (not in an array), now there will be two, so
   // create an array with the old and the new one. The new one's index is 1.
   if (contents_stream_) {
-    CPDF_Array* new_contents_array = doc_->NewIndirect<CPDF_Array>();
+    auto new_contents_array = doc_->NewIndirect<CPDF_Array>();
     new_contents_array->AppendNew<CPDF_Reference>(
         doc_.Get(), contents_stream_->GetObjNum());
     new_contents_array->AppendNew<CPDF_Reference>(doc_.Get(),
@@ -81,7 +81,7 @@
     RetainPtr<CPDF_Dictionary> page_dict = obj_holder_->GetMutableDict();
     page_dict->SetNewFor<CPDF_Reference>("Contents", doc_.Get(),
                                          new_contents_array->GetObjNum());
-    contents_array_.Reset(new_contents_array);
+    contents_array_ = std::move(new_contents_array);
     contents_stream_ = nullptr;
     return 1;
   }
@@ -98,7 +98,7 @@
   RetainPtr<CPDF_Dictionary> page_dict = obj_holder_->GetMutableDict();
   page_dict->SetNewFor<CPDF_Reference>("Contents", doc_.Get(),
                                        new_stream->GetObjNum());
-  contents_stream_.Reset(new_stream);
+  contents_stream_ = std::move(new_stream);
   return 0;
 }
 
diff --git a/core/fpdfapi/page/cpdf_docpagedata.cpp b/core/fpdfapi/page/cpdf_docpagedata.cpp
index 1d1227f..4b0277247 100644
--- a/core/fpdfapi/page/cpdf_docpagedata.cpp
+++ b/core/fpdfapi/page/cpdf_docpagedata.cpp
@@ -221,8 +221,7 @@
     return pdfium::WrapRetain(pFont);
   }
 
-  RetainPtr<CPDF_Dictionary> pDict(
-      GetDocument()->NewIndirect<CPDF_Dictionary>());
+  auto pDict = GetDocument()->NewIndirect<CPDF_Dictionary>();
   pDict->SetNewFor<CPDF_Name>("Type", "Font");
   pDict->SetNewFor<CPDF_Name>("Subtype", "Type1");
   pDict->SetNewFor<CPDF_Name>("BaseFont", fontName);
@@ -485,9 +484,9 @@
       CalculateFlags(pFont->IsBold(), pFont->IsItalic(), pFont->IsFixedWidth(),
                      false, false, charset == FX_Charset::kSymbol);
 
-  RetainPtr<CPDF_Dictionary> pBaseDict(
-      GetDocument()->NewIndirect<CPDF_Dictionary>());
+  auto pBaseDict = GetDocument()->NewIndirect<CPDF_Dictionary>();
   pBaseDict->SetNewFor<CPDF_Name>("Type", "Font");
+
   auto pEncoding = std::make_unique<CFX_UnicodeEncoding>(pFont.get());
   RetainPtr<CPDF_Dictionary> pFontDict = pBaseDict;
   if (!bCJK) {
@@ -599,8 +598,7 @@
                  ptm->otmrcFontBox.right, ptm->otmrcFontBox.top};
   FX_Free(tm_buf);
   basefont.Replace(" ", "");
-  RetainPtr<CPDF_Dictionary> pBaseDict(
-      GetDocument()->NewIndirect<CPDF_Dictionary>());
+  auto pBaseDict = GetDocument()->NewIndirect<CPDF_Dictionary>();
   pBaseDict->SetNewFor<CPDF_Name>("Type", "Font");
   RetainPtr<CPDF_Dictionary> pFontDict = pBaseDict;
   if (!bCJK) {
@@ -653,8 +651,7 @@
   if (i == std::size(kFX_CharsetUnicodes))
     return i;
 
-  CPDF_Dictionary* pEncodingDict =
-      GetDocument()->NewIndirect<CPDF_Dictionary>();
+  auto pEncodingDict = GetDocument()->NewIndirect<CPDF_Dictionary>();
   pEncodingDict->SetNewFor<CPDF_Name>("BaseEncoding",
                                       pdfium::font_encodings::kWinAnsiEncoding);
 
@@ -671,12 +668,13 @@
   return i;
 }
 
+// TODO(tsepez): return retained reference.
 CPDF_Dictionary* CPDF_DocPageData::ProcessbCJK(
     const RetainPtr<CPDF_Dictionary>& pBaseDict,
     FX_Charset charset,
     ByteString basefont,
     std::function<void(wchar_t, wchar_t, CPDF_Array*)> Insert) {
-  CPDF_Dictionary* pFontDict = GetDocument()->NewIndirect<CPDF_Dictionary>();
+  auto pFontDict = GetDocument()->NewIndirect<CPDF_Dictionary>();
   ByteString cmap;
   ByteString ordering;
   int supplement = 0;
@@ -736,5 +734,5 @@
 
   CPDF_Array* pArray = pBaseDict->SetNewFor<CPDF_Array>("DescendantFonts");
   pArray->AppendNew<CPDF_Reference>(GetDocument(), pFontDict->GetObjNum());
-  return pFontDict;
+  return pFontDict.Get();
 }
diff --git a/core/fpdfapi/page/cpdf_image.cpp b/core/fpdfapi/page/cpdf_image.cpp
index 00f7ce2..056c346 100644
--- a/core/fpdfapi/page/cpdf_image.cpp
+++ b/core/fpdfapi/page/cpdf_image.cpp
@@ -226,7 +226,7 @@
     size_t palette_size = pBitmap->GetRequiredPaletteSize();
     if (palette_size > 0) {
       DCHECK(palette_size <= 256);
-      CPDF_Array* pCS = m_pDocument->NewIndirect<CPDF_Array>();
+      auto pCS = m_pDocument->NewIndirect<CPDF_Array>();
       pCS->AppendNew<CPDF_Name>("Indexed");
       pCS->AppendNew<CPDF_Name>("DeviceRGB");
       pCS->AppendNew<CPDF_Number>(static_cast<int>(palette_size - 1));
@@ -241,7 +241,7 @@
         ptr += 3;
       }
       auto pNewDict = m_pDocument->New<CPDF_Dictionary>();
-      CPDF_Stream* pCTS = m_pDocument->NewIndirect<CPDF_Stream>(
+      auto pCTS = m_pDocument->NewIndirect<CPDF_Stream>(
           std::move(pColorTable), palette_size * 3, std::move(pNewDict));
       pCS->AppendNew<CPDF_Reference>(m_pDocument.Get(), pCTS->GetObjNum());
       pDict->SetNewFor<CPDF_Reference>("ColorSpace", m_pDocument.Get(),
@@ -280,7 +280,7 @@
       }
     }
     pMaskDict->SetNewFor<CPDF_Number>("Length", mask_size);
-    CPDF_Stream* pNewStream = m_pDocument->NewIndirect<CPDF_Stream>(
+    auto pNewStream = m_pDocument->NewIndirect<CPDF_Stream>(
         std::move(mask_buf), mask_size, std::move(pMaskDict));
     pDict->SetNewFor<CPDF_Reference>("SMask", m_pDocument.Get(),
                                      pNewStream->GetObjNum());
diff --git a/core/fpdfapi/parser/cfdf_document.cpp b/core/fpdfapi/parser/cfdf_document.cpp
index 412983e..d1b38d9 100644
--- a/core/fpdfapi/parser/cfdf_document.cpp
+++ b/core/fpdfapi/parser/cfdf_document.cpp
@@ -23,7 +23,7 @@
 
 std::unique_ptr<CFDF_Document> CFDF_Document::CreateNewDoc() {
   auto pDoc = std::make_unique<CFDF_Document>();
-  pDoc->m_pRootDict.Reset(pDoc->NewIndirect<CPDF_Dictionary>());
+  pDoc->m_pRootDict = pDoc->NewIndirect<CPDF_Dictionary>();
   pDoc->m_pRootDict->SetNewFor<CPDF_Dictionary>("FDF");
   return pDoc;
 }
diff --git a/core/fpdfapi/parser/cpdf_document.cpp b/core/fpdfapi/parser/cpdf_document.cpp
index a4f80fd..4796b32 100644
--- a/core/fpdfapi/parser/cpdf_document.cpp
+++ b/core/fpdfapi/parser/cpdf_document.cpp
@@ -326,10 +326,11 @@
   return m_pCodecContext.get();
 }
 
+// TODO(tsepez): return retained reference.
 CPDF_Stream* CPDF_Document::CreateModifiedAPStream() {
-  auto* stream = NewIndirect<CPDF_Stream>();
+  auto stream = NewIndirect<CPDF_Stream>();
   m_ModifiedAPStreamIDs.insert(stream->GetObjNum());
-  return stream;
+  return stream.Get();
 }
 
 bool CPDF_Document::IsModifiedAPStream(const CPDF_Stream* stream) const {
@@ -392,19 +393,19 @@
 void CPDF_Document::CreateNewDoc() {
   DCHECK(!m_pRootDict);
   DCHECK(!m_pInfoDict);
-  m_pRootDict.Reset(NewIndirect<CPDF_Dictionary>());
+  m_pRootDict = NewIndirect<CPDF_Dictionary>();
   m_pRootDict->SetNewFor<CPDF_Name>("Type", "Catalog");
 
-  CPDF_Dictionary* pPages = NewIndirect<CPDF_Dictionary>();
+  auto pPages = NewIndirect<CPDF_Dictionary>();
   pPages->SetNewFor<CPDF_Name>("Type", "Pages");
   pPages->SetNewFor<CPDF_Number>("Count", 0);
   pPages->SetNewFor<CPDF_Array>("Kids");
   m_pRootDict->SetNewFor<CPDF_Reference>("Pages", this, pPages->GetObjNum());
-  m_pInfoDict.Reset(NewIndirect<CPDF_Dictionary>());
+  m_pInfoDict = NewIndirect<CPDF_Dictionary>();
 }
 
 RetainPtr<CPDF_Dictionary> CPDF_Document::CreateNewPage(int iPage) {
-  RetainPtr<CPDF_Dictionary> pDict(NewIndirect<CPDF_Dictionary>());
+  auto pDict = NewIndirect<CPDF_Dictionary>();
   pDict->SetNewFor<CPDF_Name>("Type", "Page");
   uint32_t dwObjNum = pDict->GetObjNum();
   if (!InsertNewPage(iPage, pDict.Get())) {
diff --git a/core/fpdfapi/parser/cpdf_document_unittest.cpp b/core/fpdfapi/parser/cpdf_document_unittest.cpp
index 4760dbe..ee9756c 100644
--- a/core/fpdfapi/parser/cpdf_document_unittest.cpp
+++ b/core/fpdfapi/parser/cpdf_document_unittest.cpp
@@ -25,12 +25,13 @@
 
 const int kNumTestPages = 7;
 
+// TODO(tsepez): return retained reference.
 CPDF_Dictionary* CreatePageTreeNode(RetainPtr<CPDF_Array> kids,
                                     CPDF_Document* pDoc,
                                     int count) {
   CPDF_Array* pUnowned =
       pDoc->AddIndirectObject(std::move(kids))->AsMutableArray();
-  CPDF_Dictionary* pageNode = pDoc->NewIndirect<CPDF_Dictionary>();
+  auto pageNode = pDoc->NewIndirect<CPDF_Dictionary>();
   pageNode->SetNewFor<CPDF_Name>("Type", "Pages");
   pageNode->SetNewFor<CPDF_Reference>("Kids", pDoc, pUnowned->GetObjNum());
   pageNode->SetNewFor<CPDF_Number>("Count", count);
@@ -38,7 +39,7 @@
     pUnowned->GetMutableDictAt(i)->SetNewFor<CPDF_Reference>(
         "Parent", pDoc, pageNode->GetObjNum());
   }
-  return pageNode;
+  return pageNode.Get();
 }
 
 RetainPtr<CPDF_Dictionary> CreateNumberedPage(size_t number) {
@@ -88,7 +89,8 @@
     CPDF_Dictionary* pagesDict =
         CreatePageTreeNode(std::move(allPages), this, kNumTestPages);
 
-    SetRootForTesting(NewIndirect<CPDF_Dictionary>());
+    // TODO(tsepez): pass retained argument.
+    SetRootForTesting(NewIndirect<CPDF_Dictionary>().Get());
     GetMutableRoot()->SetNewFor<CPDF_Reference>("Pages", this,
                                                 pagesDict->GetObjNum());
     ResizePageListForTesting(kNumTestPages);
@@ -113,7 +115,7 @@
     inlined_page_ = allPages->Append(CreateNumberedPage(2));
     CPDF_Dictionary* pagesDict =
         CreatePageTreeNode(std::move(allPages), this, 3);
-    SetRootForTesting(NewIndirect<CPDF_Dictionary>());
+    SetRootForTesting(NewIndirect<CPDF_Dictionary>().Get());
     GetMutableRoot()->SetNewFor<CPDF_Reference>("Pages", this,
                                                 pagesDict->GetObjNum());
     ResizePageListForTesting(3);
@@ -134,11 +136,11 @@
 class CPDF_TestDocPagesWithoutKids final : public CPDF_TestDocument {
  public:
   CPDF_TestDocPagesWithoutKids() {
-    CPDF_Dictionary* pagesDict = NewIndirect<CPDF_Dictionary>();
+    auto pagesDict = NewIndirect<CPDF_Dictionary>();
     pagesDict->SetNewFor<CPDF_Name>("Type", "Pages");
     pagesDict->SetNewFor<CPDF_Number>("Count", 3);
     ResizePageListForTesting(10);
-    SetRootForTesting(NewIndirect<CPDF_Dictionary>());
+    SetRootForTesting(NewIndirect<CPDF_Dictionary>().Get());
     GetMutableRoot()->SetNewFor<CPDF_Reference>("Pages", this,
                                                 pagesDict->GetObjNum());
   }
@@ -233,8 +235,8 @@
   EXPECT_FALSE(CPDF_Document::IsValidPageObject(
       document.AddIndirectObject(dict_type_name_font)));
 
-  CPDF_Object* obj_no_type = document.NewIndirect<CPDF_Dictionary>();
-  EXPECT_FALSE(CPDF_Document::IsValidPageObject(obj_no_type));
+  auto obj_no_type = document.NewIndirect<CPDF_Dictionary>();
+  EXPECT_FALSE(CPDF_Document::IsValidPageObject(obj_no_type.Get()));
 }
 
 TEST_F(DocumentTest, UseCachedPageObjNumIfHaveNotPagesDict) {
@@ -266,7 +268,7 @@
   document.LoadPages();
 
   ASSERT_EQ(kPageCount, document.GetPageCount());
-  CPDF_Object* page_stub = document.NewIndirect<CPDF_Dictionary>();
+  auto page_stub = document.NewIndirect<CPDF_Dictionary>();
   const uint32_t obj_num = page_stub->GetObjNum();
 
   EXPECT_FALSE(document.IsPageLoaded(kTestPageNum));
diff --git a/core/fpdfapi/parser/cpdf_indirect_object_holder.h b/core/fpdfapi/parser/cpdf_indirect_object_holder.h
index 544e012..fae2245 100644
--- a/core/fpdfapi/parser/cpdf_indirect_object_holder.h
+++ b/core/fpdfapi/parser/cpdf_indirect_object_holder.h
@@ -32,19 +32,20 @@
   void DeleteIndirectObject(uint32_t objnum);
 
   // Creates and adds a new object owned by the indirect object holder,
-  // and returns an unowned pointer to it.  We have a special case to
+  // and returns a retained pointer to it.  We have a special case to
   // handle objects that can intern strings from our ByteStringPool.
   template <typename T, typename... Args>
-  typename std::enable_if<!CanInternStrings<T>::value, T*>::type NewIndirect(
-      Args&&... args) {
-    return static_cast<T*>(
-        AddIndirectObject(pdfium::MakeRetain<T>(std::forward<Args>(args)...)));
+  typename std::enable_if<!CanInternStrings<T>::value, RetainPtr<T>>::type
+  NewIndirect(Args&&... args) {
+    return pdfium::WrapRetain(static_cast<T*>(
+        AddIndirectObject(pdfium::MakeRetain<T>(std::forward<Args>(args)...))));
   }
   template <typename T, typename... Args>
-  typename std::enable_if<CanInternStrings<T>::value, T*>::type NewIndirect(
-      Args&&... args) {
-    return static_cast<T*>(AddIndirectObject(
-        pdfium::MakeRetain<T>(m_pByteStringPool, std::forward<Args>(args)...)));
+  typename std::enable_if<CanInternStrings<T>::value, RetainPtr<T>>::type
+  NewIndirect(Args&&... args) {
+    return pdfium::WrapRetain(
+        static_cast<T*>(AddIndirectObject(pdfium::MakeRetain<T>(
+            m_pByteStringPool, std::forward<Args>(args)...))));
   }
 
   // Creates and adds a new object not owned by the indirect object holder,
diff --git a/core/fpdfapi/parser/cpdf_indirect_object_holder_unittest.cpp b/core/fpdfapi/parser/cpdf_indirect_object_holder_unittest.cpp
index ac27f99..fdf5a98 100644
--- a/core/fpdfapi/parser/cpdf_indirect_object_holder_unittest.cpp
+++ b/core/fpdfapi/parser/cpdf_indirect_object_holder_unittest.cpp
@@ -4,6 +4,8 @@
 
 #include "core/fpdfapi/parser/cpdf_indirect_object_holder.h"
 
+#include "core/fpdfapi/parser/cpdf_array.h"
+#include "core/fpdfapi/parser/cpdf_dictionary.h"
 #include "core/fpdfapi/parser/cpdf_null.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -75,3 +77,16 @@
   EXPECT_FALSE(mock_holder.ReplaceIndirectObjectIfHigherGeneration(
       CPDF_Object::kInvalidObjNum, pdfium::MakeRetain<CPDF_Null>()));
 }
+
+TEST(IndirectObjectHolderTest, TemplateNewMethods) {
+  MockIndirectObjectHolder mock_holder;
+
+  auto pDict = mock_holder.NewIndirect<CPDF_Dictionary>();
+  auto pArray = mock_holder.NewIndirect<CPDF_Array>();
+  mock_holder.DeleteIndirectObject(pDict->GetObjNum());
+  mock_holder.DeleteIndirectObject(pArray->GetObjNum());
+
+  // No longer UAF since NewIndirect<> returns retained objects.
+  EXPECT_TRUE(pDict->IsDictionary());
+  EXPECT_TRUE(pArray->IsArray());
+}
diff --git a/core/fpdfapi/parser/cpdf_object_unittest.cpp b/core/fpdfapi/parser/cpdf_object_unittest.cpp
index e81c573..54c2a03 100644
--- a/core/fpdfapi/parser/cpdf_object_unittest.cpp
+++ b/core/fpdfapi/parser/cpdf_object_unittest.cpp
@@ -976,8 +976,8 @@
   {
     CPDF_IndirectObjectHolder objects_holder;
     // Create an object with a reference loop.
-    CPDF_Dictionary* dict_obj = objects_holder.NewIndirect<CPDF_Dictionary>();
-    RetainPtr<CPDF_Array> arr_obj = pdfium::MakeRetain<CPDF_Array>();
+    auto dict_obj = objects_holder.NewIndirect<CPDF_Dictionary>();
+    auto arr_obj = pdfium::MakeRetain<CPDF_Array>();
     arr_obj->InsertNewAt<CPDF_Reference>(0, &objects_holder,
                                          dict_obj->GetObjNum());
     RetainPtr<const CPDF_Object> elem0 = arr_obj->GetObjectAt(0);
diff --git a/core/fpdfapi/parser/fpdf_parser_utility_unittest.cpp b/core/fpdfapi/parser/fpdf_parser_utility_unittest.cpp
index 27cbd10..a895587 100644
--- a/core/fpdfapi/parser/fpdf_parser_utility_unittest.cpp
+++ b/core/fpdfapi/parser/fpdf_parser_utility_unittest.cpp
@@ -94,7 +94,7 @@
     auto dict = doc->New<CPDF_Dictionary>();
 
     // Add a correct dictionary entry.
-    CPDF_Dictionary* new_dict = doc->NewIndirect<CPDF_Dictionary>();
+    auto new_dict = doc->NewIndirect<CPDF_Dictionary>();
     new_dict->SetNewFor<CPDF_Name>("Type", "foo");
     dict->SetNewFor<CPDF_Reference>("f1", doc.get(), new_dict->GetObjNum());
 
diff --git a/core/fpdfdoc/cpdf_bafontmap.cpp b/core/fpdfdoc/cpdf_bafontmap.cpp
index fe7ef83..1ce8ea6 100644
--- a/core/fpdfdoc/cpdf_bafontmap.cpp
+++ b/core/fpdfdoc/cpdf_bafontmap.cpp
@@ -299,7 +299,7 @@
 
   RetainPtr<CPDF_Stream> pStream = pAPDict->GetMutableStreamFor(m_sAPType);
   if (!pStream) {
-    pStream.Reset(m_pDocument->NewIndirect<CPDF_Stream>());
+    pStream = m_pDocument->NewIndirect<CPDF_Stream>();
     pAPDict->SetNewFor<CPDF_Reference>(m_sAPType, m_pDocument.Get(),
                                        pStream->GetObjNum());
   }
@@ -315,7 +315,7 @@
   RetainPtr<CPDF_Dictionary> pStreamResFontList =
       pStreamResList->GetMutableDictFor("Font");
   if (!pStreamResFontList) {
-    pStreamResFontList.Reset(m_pDocument->NewIndirect<CPDF_Dictionary>());
+    pStreamResFontList = m_pDocument->NewIndirect<CPDF_Dictionary>();
     pStreamResList->SetNewFor<CPDF_Reference>("Font", m_pDocument.Get(),
                                               pStreamResFontList->GetObjNum());
   }
diff --git a/core/fpdfdoc/cpdf_formfield_unittest.cpp b/core/fpdfdoc/cpdf_formfield_unittest.cpp
index d88eee9..355d3b6 100644
--- a/core/fpdfdoc/cpdf_formfield_unittest.cpp
+++ b/core/fpdfdoc/cpdf_formfield_unittest.cpp
@@ -72,36 +72,36 @@
   EXPECT_TRUE(name.IsEmpty());
 
   CPDF_IndirectObjectHolder obj_holder;
-  CPDF_Dictionary* root = obj_holder.NewIndirect<CPDF_Dictionary>();
+  auto root = obj_holder.NewIndirect<CPDF_Dictionary>();
   root->SetNewFor<CPDF_Name>("T", "foo");
-  name = CPDF_FormField::GetFullNameForDict(root);
+  name = CPDF_FormField::GetFullNameForDict(root.Get());
   EXPECT_STREQ("foo", name.ToUTF8().c_str());
 
-  CPDF_Dictionary* dict1 = obj_holder.NewIndirect<CPDF_Dictionary>();
+  auto dict1 = obj_holder.NewIndirect<CPDF_Dictionary>();
   root->SetNewFor<CPDF_Reference>("Parent", &obj_holder, dict1->GetObjNum());
   dict1->SetNewFor<CPDF_Name>("T", "bar");
-  name = CPDF_FormField::GetFullNameForDict(root);
+  name = CPDF_FormField::GetFullNameForDict(root.Get());
   EXPECT_STREQ("bar.foo", name.ToUTF8().c_str());
 
   CPDF_Dictionary* dict2 = dict1->SetNewFor<CPDF_Dictionary>("Parent");
-  name = CPDF_FormField::GetFullNameForDict(root);
+  name = CPDF_FormField::GetFullNameForDict(root.Get());
   EXPECT_STREQ("bar.foo", name.ToUTF8().c_str());
 
-  CPDF_Dictionary* dict3 = obj_holder.NewIndirect<CPDF_Dictionary>();
+  auto dict3 = obj_holder.NewIndirect<CPDF_Dictionary>();
   dict2->SetNewFor<CPDF_Reference>("Parent", &obj_holder, dict3->GetObjNum());
 
   dict3->SetNewFor<CPDF_Name>("T", "qux");
-  name = CPDF_FormField::GetFullNameForDict(root);
+  name = CPDF_FormField::GetFullNameForDict(root.Get());
   EXPECT_STREQ("qux.bar.foo", name.ToUTF8().c_str());
 
   dict3->SetNewFor<CPDF_Reference>("Parent", &obj_holder, root->GetObjNum());
-  name = CPDF_FormField::GetFullNameForDict(root);
+  name = CPDF_FormField::GetFullNameForDict(root.Get());
   EXPECT_STREQ("qux.bar.foo", name.ToUTF8().c_str());
-  name = CPDF_FormField::GetFullNameForDict(dict1);
+  name = CPDF_FormField::GetFullNameForDict(dict1.Get());
   EXPECT_STREQ("foo.qux.bar", name.ToUTF8().c_str());
   name = CPDF_FormField::GetFullNameForDict(dict2);
   EXPECT_STREQ("bar.foo.qux", name.ToUTF8().c_str());
-  name = CPDF_FormField::GetFullNameForDict(dict3);
+  name = CPDF_FormField::GetFullNameForDict(dict3.Get());
   EXPECT_STREQ("bar.foo.qux", name.ToUTF8().c_str());
 }
 
diff --git a/core/fpdfdoc/cpdf_generateap.cpp b/core/fpdfdoc/cpdf_generateap.cpp
index ffcd95f..91aea41 100644
--- a/core/fpdfdoc/cpdf_generateap.cpp
+++ b/core/fpdfdoc/cpdf_generateap.cpp
@@ -397,7 +397,7 @@
 RetainPtr<CPDF_Dictionary> GenerateResourceFontDict(
     CPDF_Document* pDoc,
     const ByteString& sFontDictName) {
-  CPDF_Dictionary* pFontDict = pDoc->NewIndirect<CPDF_Dictionary>();
+  auto pFontDict = pDoc->NewIndirect<CPDF_Dictionary>();
   pFontDict->SetNewFor<CPDF_Name>("Type", "Font");
   pFontDict->SetNewFor<CPDF_Name>("Subtype", "Type1");
   pFontDict->SetNewFor<CPDF_Name>("BaseFont", CFX_Font::kDefaultAnsiFontName);
@@ -503,7 +503,7 @@
                           fxcrt::ostringstream* psAppStream,
                           RetainPtr<CPDF_Dictionary> pResourceDict,
                           bool bIsTextMarkupAnnotation) {
-  CPDF_Stream* pNormalStream = pDoc->NewIndirect<CPDF_Stream>();
+  auto pNormalStream = pDoc->NewIndirect<CPDF_Stream>();
   pNormalStream->SetDataFromStringstream(psAppStream);
 
   RetainPtr<CPDF_Dictionary> pAPDict =
@@ -944,7 +944,7 @@
   RetainPtr<CPDF_Dictionary> pFontDict =
       pDRFontDict->GetMutableDictFor(font_name);
   if (!pFontDict) {
-    pFontDict.Reset(pDoc->NewIndirect<CPDF_Dictionary>());
+    pFontDict = pDoc->NewIndirect<CPDF_Dictionary>();
     pFontDict->SetNewFor<CPDF_Name>("Type", "Font");
     pFontDict->SetNewFor<CPDF_Name>("Subtype", "Type1");
     pFontDict->SetNewFor<CPDF_Name>("BaseFont", CFX_Font::kDefaultAnsiFontName);
@@ -1061,7 +1061,7 @@
       pAnnotDict->GetOrCreateDictFor(pdfium::annotation::kAP);
   RetainPtr<CPDF_Stream> pNormalStream = pAPDict->GetMutableStreamFor("N");
   if (!pNormalStream) {
-    pNormalStream.Reset(pDoc->NewIndirect<CPDF_Stream>());
+    pNormalStream = pDoc->NewIndirect<CPDF_Stream>();
     pAPDict->SetNewFor<CPDF_Reference>("N", pDoc, pNormalStream->GetObjNum());
   }
   RetainPtr<CPDF_Dictionary> pStreamDict = pNormalStream->GetMutableDict();
diff --git a/core/fpdfdoc/cpdf_interactiveform.cpp b/core/fpdfdoc/cpdf_interactiveform.cpp
index 7eacf75..02128d8 100644
--- a/core/fpdfdoc/cpdf_interactiveform.cpp
+++ b/core/fpdfdoc/cpdf_interactiveform.cpp
@@ -269,23 +269,24 @@
 
 // TODO(tsepez): return retained reference.
 CPDF_Dictionary* InitDict(CPDF_Document* pDocument) {
-  CPDF_Dictionary* pFormDict = pDocument->NewIndirect<CPDF_Dictionary>();
+  auto pFormDict = pDocument->NewIndirect<CPDF_Dictionary>();
   pDocument->GetMutableRoot()->SetNewFor<CPDF_Reference>(
       "AcroForm", pDocument, pFormDict->GetObjNum());
 
   ByteString csBaseName;
   FX_Charset charSet = GetNativeCharSet();
   RetainPtr<CPDF_Font> pFont = AddStandardFont(pDocument);
-  if (pFont)
-    AddFont(pFormDict, pDocument, pFont, &csBaseName);
-
+  if (pFont) {
+    // TODO(tsepez): pass retained reference.
+    AddFont(pFormDict.Get(), pDocument, pFont, &csBaseName);
+  }
   if (charSet != FX_Charset::kANSI) {
     ByteString csFontName = GetNativeFontName(charSet, nullptr);
     if (!pFont || csFontName != CFX_Font::kDefaultAnsiFontName) {
       pFont = AddNativeFont(charSet, pDocument);
       if (pFont) {
         csBaseName.clear();
-        AddFont(pFormDict, pDocument, pFont, &csBaseName);
+        AddFont(pFormDict.Get(), pDocument, pFont, &csBaseName);
       }
     }
   }
@@ -294,7 +295,7 @@
     csDA = "/" + PDF_NameEncode(csBaseName) + " 0 Tf ";
   csDA += "0 g";
   pFormDict->SetNewFor<CPDF_String>("DA", csDA, /*bHex=*/false);
-  return pFormDict;
+  return pFormDict.Get();
 }
 
 RetainPtr<CPDF_Font> GetNativeFont(const CPDF_Dictionary* pFormDict,
diff --git a/core/fpdfdoc/cpdf_nametree.cpp b/core/fpdfdoc/cpdf_nametree.cpp
index 66fe5bc..8d95dd4 100644
--- a/core/fpdfdoc/cpdf_nametree.cpp
+++ b/core/fpdfdoc/cpdf_nametree.cpp
@@ -444,14 +444,14 @@
   // Retrieve the document's Names dictionary; create it if missing.
   RetainPtr<CPDF_Dictionary> pNames = pRoot->GetMutableDictFor("Names");
   if (!pNames) {
-    pNames.Reset(pDoc->NewIndirect<CPDF_Dictionary>());
+    pNames = pDoc->NewIndirect<CPDF_Dictionary>();
     pRoot->SetNewFor<CPDF_Reference>("Names", pDoc, pNames->GetObjNum());
   }
 
   // Create the |category| dictionary if missing.
   RetainPtr<CPDF_Dictionary> pCategory = pNames->GetMutableDictFor(category);
   if (!pCategory) {
-    pCategory.Reset(pDoc->NewIndirect<CPDF_Dictionary>());
+    pCategory = pDoc->NewIndirect<CPDF_Dictionary>();
     pCategory->SetNewFor<CPDF_Array>("Names");
     pNames->SetNewFor<CPDF_Reference>(category, pDoc, pCategory->GetObjNum());
   }
diff --git a/fpdfsdk/fpdf_annot.cpp b/fpdfsdk/fpdf_annot.cpp
index 503dc5b..28661ec 100644
--- a/fpdfsdk/fpdf_annot.cpp
+++ b/fpdfsdk/fpdf_annot.cpp
@@ -1098,8 +1098,7 @@
     if (!pDoc)
       return false;
 
-    CPDF_Stream* pNewIndirectStream = pDoc->NewIndirect<CPDF_Stream>();
-
+    auto pNewIndirectStream = pDoc->NewIndirect<CPDF_Stream>();
     ByteString newAPStream =
         PDF_EncodeText(WideStringFromFPDFWideString(value).AsStringView());
     pNewIndirectStream->SetData(newAPStream.raw_span());
diff --git a/fpdfsdk/fpdf_attachment.cpp b/fpdfsdk/fpdf_attachment.cpp
index d84acd8..b1461bb 100644
--- a/fpdfsdk/fpdf_attachment.cpp
+++ b/fpdfsdk/fpdf_attachment.cpp
@@ -77,7 +77,7 @@
     return nullptr;
 
   // Set up the basic entries in the filespec dictionary.
-  CPDF_Dictionary* pFile = pDoc->NewIndirect<CPDF_Dictionary>();
+  auto pFile = pDoc->NewIndirect<CPDF_Dictionary>();
   pFile->SetNewFor<CPDF_Name>("Type", "Filespec");
   pFile->SetNewFor<CPDF_String>("UF", wsName.AsStringView());
   pFile->SetNewFor<CPDF_String>(pdfium::stream::kF, wsName.AsStringView());
@@ -86,7 +86,7 @@
   if (!name_tree->AddValueAndName(pFile->MakeReference(pDoc), wsName))
     return nullptr;
 
-  return FPDFAttachmentFromCPDFObject(pFile);
+  return FPDFAttachmentFromCPDFObject(pFile.Get());
 }
 
 FPDF_EXPORT FPDF_ATTACHMENT FPDF_CALLCONV
@@ -242,8 +242,8 @@
   // Create the file stream and have the filespec dictionary link to it.
   std::unique_ptr<uint8_t, FxFreeDeleter> stream(FX_AllocUninit(uint8_t, len));
   memcpy(stream.get(), contents, len);
-  CPDF_Stream* pFileStream = pDoc->NewIndirect<CPDF_Stream>(
-      std::move(stream), len, std::move(pFileStreamDict));
+  auto pFileStream = pDoc->NewIndirect<CPDF_Stream>(std::move(stream), len,
+                                                    std::move(pFileStreamDict));
   CPDF_Dictionary* pEFDict =
       pFile->AsMutableDictionary()->SetNewFor<CPDF_Dictionary>("EF");
   pEFDict->SetNewFor<CPDF_Reference>("F", pDoc, pFileStream->GetObjNum());
diff --git a/fpdfsdk/fpdf_doc_unittest.cpp b/fpdfsdk/fpdf_doc_unittest.cpp
index 3346aae..6b786d3 100644
--- a/fpdfsdk/fpdf_doc_unittest.cpp
+++ b/fpdfsdk/fpdf_doc_unittest.cpp
@@ -28,14 +28,14 @@
  public:
   struct DictObjInfo {
     uint32_t num;
-    CPDF_Dictionary* obj;
+    RetainPtr<CPDF_Dictionary> obj;
   };
 
   void SetUp() override {
     TestWithPageModule::SetUp();
     auto pTestDoc = std::make_unique<CPDF_TestDocument>();
     m_pIndirectObjs = pTestDoc.get();
-    m_pRootObj.Reset(m_pIndirectObjs->NewIndirect<CPDF_Dictionary>());
+    m_pRootObj = m_pIndirectObjs->NewIndirect<CPDF_Dictionary>();
     pTestDoc->SetRoot(m_pRootObj.Get());
     m_pDoc.reset(FPDFDocumentFromCPDFDocument(pTestDoc.release()));
   }
@@ -50,8 +50,7 @@
   std::vector<DictObjInfo> CreateDictObjs(int num) {
     std::vector<DictObjInfo> info;
     for (int i = 0; i < num; ++i) {
-      // Objects created will be released by the document.
-      CPDF_Dictionary* obj = m_pIndirectObjs->NewIndirect<CPDF_Dictionary>();
+      auto obj = m_pIndirectObjs->NewIndirect<CPDF_Dictionary>();
       info.push_back({obj->GetObjNum(), obj});
     }
     return info;
@@ -117,12 +116,12 @@
 
     // Title with a match.
     title = GetFPDFWideString(L"Chapter 2");
-    EXPECT_EQ(FPDFBookmarkFromCPDFDictionary(bookmarks[2].obj),
+    EXPECT_EQ(FPDFBookmarkFromCPDFDictionary(bookmarks[2].obj.Get()),
               FPDFBookmark_Find(m_pDoc.get(), title.get()));
 
     // Title match is case insensitive.
     title = GetFPDFWideString(L"cHaPter 2");
-    EXPECT_EQ(FPDFBookmarkFromCPDFDictionary(bookmarks[2].obj),
+    EXPECT_EQ(FPDFBookmarkFromCPDFDictionary(bookmarks[2].obj.Get()),
               FPDFBookmark_Find(m_pDoc.get(), title.get()));
   }
   {
@@ -157,7 +156,7 @@
 
     // Title with a match.
     title = GetFPDFWideString(L"Chapter 2");
-    EXPECT_EQ(FPDFBookmarkFromCPDFDictionary(bookmarks[2].obj),
+    EXPECT_EQ(FPDFBookmarkFromCPDFDictionary(bookmarks[2].obj.Get()),
               FPDFBookmark_Find(m_pDoc.get(), title.get()));
   }
   {
@@ -198,7 +197,7 @@
 
     // Title with a match.
     title = GetFPDFWideString(L"Chapter 3");
-    EXPECT_EQ(FPDFBookmarkFromCPDFDictionary(bookmarks[3].obj),
+    EXPECT_EQ(FPDFBookmarkFromCPDFDictionary(bookmarks[3].obj.Get()),
               FPDFBookmark_Find(m_pDoc.get(), title.get()));
   }
 }
diff --git a/fpdfsdk/fpdf_edittext.cpp b/fpdfsdk/fpdf_edittext.cpp
index a58b64fa..2b61d1a 100644
--- a/fpdfsdk/fpdf_edittext.cpp
+++ b/fpdfsdk/fpdf_edittext.cpp
@@ -85,12 +85,13 @@
   return CFX_Font::kUntitledFontName;
 }
 
+// TODO(tsepez): return retained references.
 CPDF_Dictionary* LoadFontDesc(CPDF_Document* pDoc,
                               const ByteString& font_name,
                               CFX_Font* pFont,
                               pdfium::span<const uint8_t> span,
                               int font_type) {
-  CPDF_Dictionary* pFontDesc = pDoc->NewIndirect<CPDF_Dictionary>();
+  auto pFontDesc = pDoc->NewIndirect<CPDF_Dictionary>();
   pFontDesc->SetNewFor<CPDF_Name>("Type", "FontDescriptor");
   pFontDesc->SetNewFor<CPDF_Name>("FontName", font_name);
   int flags = 0;
@@ -120,7 +121,7 @@
   pFontDesc->SetNewFor<CPDF_Number>("CapHeight", pFont->GetAscent());
   pFontDesc->SetNewFor<CPDF_Number>("StemV", pFont->IsBold() ? 120 : 70);
 
-  CPDF_Stream* pStream = pDoc->NewIndirect<CPDF_Stream>();
+  auto pStream = pDoc->NewIndirect<CPDF_Stream>();
   pStream->SetData(span);
   // TODO(npm): Lengths for Type1 fonts.
   if (font_type == FPDF_FONT_TRUETYPE) {
@@ -129,7 +130,7 @@
   }
   ByteString fontFile = font_type == FPDF_FONT_TYPE1 ? "FontFile" : "FontFile2";
   pFontDesc->SetNewFor<CPDF_Reference>(fontFile, pDoc, pStream->GetObjNum());
-  return pFontDesc;
+  return pFontDesc.Get();
 }
 
 const char ToUnicodeStart[] =
@@ -178,6 +179,7 @@
 }
 
 // Loads the charcode to unicode mapping into a stream
+// TODO(tsepez): return retained result.
 CPDF_Stream* LoadUnicode(CPDF_Document* pDoc,
                          const std::multimap<uint32_t, uint32_t>& to_unicode) {
   // A map charcode->unicode
@@ -282,16 +284,16 @@
   buffer << "endbfrange\n";
   buffer << ToUnicodeEnd;
   // TODO(npm): Encrypt / Compress?
-  CPDF_Stream* stream = pDoc->NewIndirect<CPDF_Stream>();
+  auto stream = pDoc->NewIndirect<CPDF_Stream>();
   stream->SetDataFromStringstream(&buffer);
-  return stream;
+  return stream.Get();
 }
 
 RetainPtr<CPDF_Font> LoadSimpleFont(CPDF_Document* pDoc,
                                     std::unique_ptr<CFX_Font> pFont,
                                     pdfium::span<const uint8_t> span,
                                     int font_type) {
-  RetainPtr<CPDF_Dictionary> pFontDict(pDoc->NewIndirect<CPDF_Dictionary>());
+  auto pFontDict = pDoc->NewIndirect<CPDF_Dictionary>();
   pFontDict->SetNewFor<CPDF_Name>("Type", "Font");
   pFontDict->SetNewFor<CPDF_Name>(
       "Subtype", font_type == FPDF_FONT_TYPE1 ? "Type1" : "TrueType");
@@ -306,7 +308,7 @@
     return nullptr;
   pFontDict->SetNewFor<CPDF_Number>("FirstChar",
                                     static_cast<int>(dwCurrentChar));
-  CPDF_Array* widthsArray = pDoc->NewIndirect<CPDF_Array>();
+  auto widthsArray = pDoc->NewIndirect<CPDF_Array>();
   while (true) {
     widthsArray->AppendNew<CPDF_Number>(pFont->GetGlyphWidth(dwGlyphIndex));
     uint32_t nextChar = static_cast<uint32_t>(
@@ -334,7 +336,7 @@
                                        std::unique_ptr<CFX_Font> pFont,
                                        pdfium::span<const uint8_t> span,
                                        int font_type) {
-  RetainPtr<CPDF_Dictionary> pFontDict(pDoc->NewIndirect<CPDF_Dictionary>());
+  auto pFontDict = pDoc->NewIndirect<CPDF_Dictionary>();
   pFontDict->SetNewFor<CPDF_Name>("Type", "Font");
   pFontDict->SetNewFor<CPDF_Name>("Subtype", "Type0");
   // TODO(npm): Get the correct encoding, if it's not identity.
@@ -344,7 +346,7 @@
   pFontDict->SetNewFor<CPDF_Name>(
       "BaseFont", font_type == FPDF_FONT_TYPE1 ? name + "-" + encoding : name);
 
-  CPDF_Dictionary* pCIDFont = pDoc->NewIndirect<CPDF_Dictionary>();
+  auto pCIDFont = pDoc->NewIndirect<CPDF_Dictionary>();
   pCIDFont->SetNewFor<CPDF_Name>("Type", "Font");
   pCIDFont->SetNewFor<CPDF_Name>("Subtype", font_type == FPDF_FONT_TYPE1
                                                 ? "CIDFontType0"
@@ -353,7 +355,7 @@
 
   // TODO(npm): Maybe use FT_Get_CID_Registry_Ordering_Supplement to get the
   // CIDSystemInfo
-  CPDF_Dictionary* pCIDSystemInfo = pDoc->NewIndirect<CPDF_Dictionary>();
+  auto pCIDSystemInfo = pDoc->NewIndirect<CPDF_Dictionary>();
   pCIDSystemInfo->SetNewFor<CPDF_String>("Registry", "Adobe", false);
   pCIDSystemInfo->SetNewFor<CPDF_String>("Ordering", "Identity", false);
   pCIDSystemInfo->SetNewFor<CPDF_Number>("Supplement", 0);
@@ -387,7 +389,7 @@
     if (dwGlyphIndex == 0)
       break;
   }
-  CPDF_Array* widthsArray = pDoc->NewIndirect<CPDF_Array>();
+  auto widthsArray = pDoc->NewIndirect<CPDF_Array>();
   for (auto it = widths.begin(); it != widths.end(); ++it) {
     int ch = it->first;
     int w = it->second;
diff --git a/fpdfsdk/fpdf_flatten.cpp b/fpdfsdk/fpdf_flatten.cpp
index c0a0b18..2b0e18a 100644
--- a/fpdfsdk/fpdf_flatten.cpp
+++ b/fpdfsdk/fpdf_flatten.cpp
@@ -180,12 +180,13 @@
   return "q 1 0 0 1 0 0 cm /" + key + " Do Q";
 }
 
+// TODO(tsepez): return retained reference.
 CPDF_Object* NewIndirectContentsStream(CPDF_Document* pDocument,
                                        const ByteString& contents) {
-  CPDF_Stream* pNewContents = pDocument->NewIndirect<CPDF_Stream>(
+  auto pNewContents = pDocument->NewIndirect<CPDF_Stream>(
       nullptr, 0, pDocument->New<CPDF_Dictionary>());
   pNewContents->SetData(contents.raw_span());
-  return pNewContents;
+  return pNewContents.Get();
 }
 
 void SetPageContents(const ByteString& key,
@@ -220,7 +221,7 @@
       sStream += "\nQ";
     }
     pContentsStream->SetDataAndRemoveFilter(sStream.raw_span());
-    pContentsArray.Reset(pDocument->NewIndirect<CPDF_Array>());
+    pContentsArray = pDocument->NewIndirect<CPDF_Array>();
     pContentsArray->AppendNew<CPDF_Reference>(pDocument,
                                               pContentsStream->GetObjNum());
     pPage->SetNewFor<CPDF_Reference>(pdfium::page_object::kContents, pDocument,
@@ -297,7 +298,7 @@
 
   RetainPtr<CPDF_Dictionary> pRes =
       pPageDict->GetOrCreateDictFor(pdfium::page_object::kResources);
-  CPDF_Stream* pNewXObject = pDocument->NewIndirect<CPDF_Stream>(
+  auto pNewXObject = pDocument->NewIndirect<CPDF_Stream>(
       nullptr, 0, pDocument->New<CPDF_Dictionary>());
   RetainPtr<CPDF_Dictionary> pPageXObject = pRes->GetOrCreateDictFor("XObject");
 
@@ -399,8 +400,7 @@
 
     ByteString sStream;
     {
-      auto pAcc =
-          pdfium::MakeRetain<CPDF_StreamAcc>(pdfium::WrapRetain(pNewXObject));
+      auto pAcc = pdfium::MakeRetain<CPDF_StreamAcc>(pNewXObject);
       pAcc->LoadAllDataFiltered();
       sStream = ByteString(pAcc->GetSpan());
     }
diff --git a/fpdfsdk/fpdf_ppo.cpp b/fpdfsdk/fpdf_ppo.cpp
index 53459be..fa2ce50 100644
--- a/fpdfsdk/fpdf_ppo.cpp
+++ b/fpdfsdk/fpdf_ppo.cpp
@@ -269,7 +269,7 @@
   RetainPtr<CPDF_Dictionary> pNewPages =
       pElement ? ToDictionary(pElement->GetMutableDirect()) : nullptr;
   if (!pNewPages) {
-    pNewPages.Reset(dest()->NewIndirect<CPDF_Dictionary>());
+    pNewPages = dest()->NewIndirect<CPDF_Dictionary>();
     pNewRoot->SetNewFor<CPDF_Reference>("Pages", dest(),
                                         pNewPages->GetObjNum());
   }
@@ -278,7 +278,7 @@
     pNewPages->SetNewFor<CPDF_Name>("Type", "Pages");
 
   if (!pNewPages->GetArrayFor("Kids")) {
-    auto* pNewArray = dest()->NewIndirect<CPDF_Array>();
+    auto pNewArray = dest()->NewIndirect<CPDF_Array>();
     pNewPages->SetNewFor<CPDF_Number>("Count", 0);
     pNewPages->SetNewFor<CPDF_Reference>("Kids", dest(),
                                          pNewArray->GetObjNum());
@@ -598,13 +598,14 @@
   return ByteString(contentStream);
 }
 
+// TODO(tsepez): return retained object.
 CPDF_Stream* CPDF_NPageToOneExporter::MakeXObjectFromPageRaw(
     const RetainPtr<CPDF_Page>& pSrcPage) {
   const CPDF_Dictionary* pSrcPageDict = pSrcPage->GetDict();
   RetainPtr<const CPDF_Object> pSrcContentObj =
       pSrcPageDict->GetDirectObjectFor(pdfium::page_object::kContents);
 
-  CPDF_Stream* pNewXObject = dest()->NewIndirect<CPDF_Stream>(
+  auto pNewXObject = dest()->NewIndirect<CPDF_Stream>(
       nullptr, 0, dest()->New<CPDF_Dictionary>());
   RetainPtr<CPDF_Dictionary> pNewXObjectDict = pNewXObject->GetMutableDict();
   static const char kResourceString[] = "Resources";
@@ -634,15 +635,14 @@
         bsSrcContentStream += "\n";
       }
     } else {
-      const CPDF_Stream* pStream = pSrcContentObj->AsStream();
-      auto pAcc =
-          pdfium::MakeRetain<CPDF_StreamAcc>(pdfium::WrapRetain(pStream));
+      RetainPtr<const CPDF_Stream> pStream(pSrcContentObj->AsStream());
+      auto pAcc = pdfium::MakeRetain<CPDF_StreamAcc>(std::move(pStream));
       pAcc->LoadAllDataFiltered();
       bsSrcContentStream = ByteString(pAcc->GetSpan());
     }
     pNewXObject->SetDataAndRemoveFilter(bsSrcContentStream.raw_span());
   }
-  return pNewXObject;
+  return pNewXObject.Get();
 }
 
 ByteString CPDF_NPageToOneExporter::MakeXObjectFromPage(
@@ -680,8 +680,7 @@
     pPageXObject->SetNewFor<CPDF_Reference>(it.first, dest(), it.second);
 
   auto pDict = dest()->New<CPDF_Dictionary>();
-  CPDF_Stream* pStream =
-      dest()->NewIndirect<CPDF_Stream>(nullptr, 0, std::move(pDict));
+  auto pStream = dest()->NewIndirect<CPDF_Stream>(nullptr, 0, std::move(pDict));
   pStream->SetData(bsContent.raw_span());
   pDestPageDict->SetNewFor<CPDF_Reference>(pdfium::page_object::kContents,
                                            dest(), pStream->GetObjNum());
diff --git a/fpdfsdk/fpdf_save.cpp b/fpdfsdk/fpdf_save.cpp
index a2d9d04..b780259 100644
--- a/fpdfsdk/fpdf_save.cpp
+++ b/fpdfsdk/fpdf_save.cpp
@@ -117,7 +117,7 @@
           pDataSetsStream->InitStreamFromFile(pFileWrite, std::move(pDataDict));
         }
       } else {
-        CPDF_Stream* pData = pPDFDocument->NewIndirect<CPDF_Stream>();
+        auto pData = pPDFDocument->NewIndirect<CPDF_Stream>();
         pData->InitStreamFromFile(pFileWrite, std::move(pDataDict));
         int iLast = fxcrt::CollectionSize<int>(*pArray) - 2;
         pArray->InsertNewAt<CPDF_String>(iLast, "datasets", false);
@@ -137,7 +137,7 @@
         if (pFormStream)
           pFormStream->InitStreamFromFile(pFileWrite, std::move(pDataDict));
       } else {
-        CPDF_Stream* pData = pPDFDocument->NewIndirect<CPDF_Stream>();
+        auto pData = pPDFDocument->NewIndirect<CPDF_Stream>();
         pData->InitStreamFromFile(pFileWrite, std::move(pDataDict));
         int iLast = fxcrt::CollectionSize<int>(*pArray) - 2;
         pArray->InsertNewAt<CPDF_String>(iLast, "form", false);
diff --git a/fpdfsdk/fpdf_transformpage.cpp b/fpdfsdk/fpdf_transformpage.cpp
index 3b64868..4d48f39 100644
--- a/fpdfsdk/fpdf_transformpage.cpp
+++ b/fpdfsdk/fpdf_transformpage.cpp
@@ -228,11 +228,11 @@
   if (matrix)
     WriteMatrix(text_buf, CFXMatrixFromFSMatrix(*matrix)) << " cm ";
 
-  CPDF_Stream* pStream =
+  auto pStream =
       pDoc->NewIndirect<CPDF_Stream>(nullptr, 0, pDoc->New<CPDF_Dictionary>());
   pStream->SetDataFromStringstream(&text_buf);
 
-  CPDF_Stream* pEndStream =
+  auto pEndStream =
       pDoc->NewIndirect<CPDF_Stream>(nullptr, 0, pDoc->New<CPDF_Dictionary>());
   pEndStream->SetData(ByteStringView(" Q").raw_span());
 
@@ -241,7 +241,7 @@
     pContentArray->InsertNewAt<CPDF_Reference>(0, pDoc, pStream->GetObjNum());
     pContentArray->AppendNew<CPDF_Reference>(pDoc, pEndStream->GetObjNum());
   } else if (pContentObj->IsStream() && !pContentObj->IsInline()) {
-    pContentArray.Reset(pDoc->NewIndirect<CPDF_Array>());
+    pContentArray = pDoc->NewIndirect<CPDF_Array>();
     pContentArray->AppendNew<CPDF_Reference>(pDoc, pStream->GetObjNum());
     pContentArray->AppendNew<CPDF_Reference>(pDoc, pContentObj->GetObjNum());
     pContentArray->AppendNew<CPDF_Reference>(pDoc, pEndStream->GetObjNum());
@@ -406,7 +406,7 @@
   if (!pDoc)
     return;
 
-  CPDF_Stream* pStream =
+  auto pStream =
       pDoc->NewIndirect<CPDF_Stream>(nullptr, 0, pDoc->New<CPDF_Dictionary>());
   pStream->SetDataFromStringstream(&strClip);
 
@@ -414,7 +414,7 @@
   if (pArray) {
     pArray->InsertNewAt<CPDF_Reference>(0, pDoc, pStream->GetObjNum());
   } else if (pContentObj->IsStream() && !pContentObj->IsInline()) {
-    CPDF_Array* pContentArray = pDoc->NewIndirect<CPDF_Array>();
+    auto pContentArray = pDoc->NewIndirect<CPDF_Array>();
     pContentArray->AppendNew<CPDF_Reference>(pDoc, pStream->GetObjNum());
     pContentArray->AppendNew<CPDF_Reference>(pDoc, pContentObj->GetObjNum());
     pPageDict->SetNewFor<CPDF_Reference>(pdfium::page_object::kContents, pDoc,