Make CPDF_Dictionary use unique pointers.

Some changes were required to match underlying ctors
as invoked by the templated methods.

Many release() calls go away, a few WrapUniques() are
introduced to avoid going deeper into other code.

Review-Url: https://codereview.chromium.org/2510223002
diff --git a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
index 80450a8..8376972 100644
--- a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
+++ b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
@@ -16,6 +16,8 @@
 #include "core/fpdfapi/parser/cpdf_array.h"
 #include "core/fpdfapi/parser/cpdf_dictionary.h"
 #include "core/fpdfapi/parser/cpdf_document.h"
+#include "core/fpdfapi/parser/cpdf_name.h"
+#include "core/fpdfapi/parser/cpdf_reference.h"
 #include "core/fpdfapi/parser/cpdf_stream.h"
 #include "core/fpdfapi/parser/cpdf_stream_acc.h"
 #include "core/fpdfapi/parser/fpdf_parser_decode.h"
@@ -54,7 +56,8 @@
 
   CPDF_Stream* pStream = m_pDocument->NewIndirect<CPDF_Stream>();
   pStream->SetData(buf.GetBuffer(), buf.GetLength());
-  pPageDict->SetReferenceFor("Contents", m_pDocument, pStream);
+  pPageDict->SetNewFor<CPDF_Reference>("Contents", m_pDocument,
+                                       pStream->GetObjNum());
 }
 
 CFX_ByteString CPDF_PageContentGenerator::RealizeResource(
@@ -63,14 +66,13 @@
   ASSERT(dwResourceObjNum);
   if (!m_pPage->m_pResources) {
     m_pPage->m_pResources = m_pDocument->NewIndirect<CPDF_Dictionary>();
-    m_pPage->m_pFormDict->SetReferenceFor("Resources", m_pDocument,
-                                          m_pPage->m_pResources);
+    m_pPage->m_pFormDict->SetNewFor<CPDF_Reference>(
+        "Resources", m_pDocument, m_pPage->m_pResources->GetObjNum());
   }
   CPDF_Dictionary* pResList = m_pPage->m_pResources->GetDictFor(bsType);
-  if (!pResList) {
-    pResList = new CPDF_Dictionary(m_pDocument->GetByteStringPool());
-    m_pPage->m_pResources->SetFor(bsType, pResList);
-  }
+  if (!pResList)
+    pResList = m_pPage->m_pResources->SetNewFor<CPDF_Dictionary>(bsType);
+
   CFX_ByteString name;
   int idnum = 1;
   while (1) {
@@ -80,7 +82,7 @@
     }
     idnum++;
   }
-  pResList->SetReferenceFor(name, m_pDocument, dwResourceObjNum);
+  pResList->SetNewFor<CPDF_Reference>(name, m_pDocument, dwResourceObjNum);
   return name;
 }
 
@@ -126,8 +128,8 @@
 
   CPDF_Dictionary* pFormDict =
       new CPDF_Dictionary(m_pDocument->GetByteStringPool());
-  pFormDict->SetNameFor("Type", "XObject");
-  pFormDict->SetNameFor("Subtype", "Form");
+  pFormDict->SetNewFor<CPDF_Name>("Type", "XObject");
+  pFormDict->SetNewFor<CPDF_Name>("Subtype", "Form");
   pFormDict->SetRectFor("BBox", bbox);
 
   CPDF_Stream* pStream = m_pDocument->NewIndirect<CPDF_Stream>();
@@ -179,5 +181,6 @@
   }
   CPDF_Stream* pStream = m_pDocument->NewIndirect<CPDF_Stream>();
   pStream->SetData(buf.GetBuffer(), buf.GetLength());
-  m_pPage->m_pFormDict->SetReferenceFor("Contents", m_pDocument, pStream);
+  m_pPage->m_pFormDict->SetNewFor<CPDF_Reference>("Contents", m_pDocument,
+                                                  pStream->GetObjNum());
 }
diff --git a/core/fpdfapi/edit/fpdf_edit_create.cpp b/core/fpdfapi/edit/fpdf_edit_create.cpp
index 3604729..b2e3105 100644
--- a/core/fpdfapi/edit/fpdf_edit_create.cpp
+++ b/core/fpdfapi/edit/fpdf_edit_create.cpp
@@ -13,6 +13,8 @@
 #include "core/fpdfapi/parser/cpdf_crypto_handler.h"
 #include "core/fpdfapi/parser/cpdf_dictionary.h"
 #include "core/fpdfapi/parser/cpdf_document.h"
+#include "core/fpdfapi/parser/cpdf_name.h"
+#include "core/fpdfapi/parser/cpdf_number.h"
 #include "core/fpdfapi/parser/cpdf_parser.h"
 #include "core/fpdfapi/parser/cpdf_reference.h"
 #include "core/fpdfapi/parser/cpdf_security_handler.h"
@@ -128,7 +130,7 @@
       const CPDF_Dictionary* p = pObj->AsDictionary();
       for (const auto& it : *p) {
         const CFX_ByteString& key = it.first;
-        CPDF_Object* pValue = it.second;
+        CPDF_Object* pValue = it.second.get();
         if (pFile->AppendString("/") < 0) {
           return -1;
         }
@@ -197,7 +199,7 @@
     CPDF_Dictionary* p = pParser->GetTrailer();
     for (const auto& it : *p) {
       const CFX_ByteString& key = it.first;
-      CPDF_Object* pValue = it.second;
+      CPDF_Object* pValue = it.second.get();
       if (key == "Encrypt" || key == "Size" || key == "Filter" ||
           key == "Index" || key == "Length" || key == "Prev" || key == "W" ||
           key == "XRefStm" || key == "Type" || key == "ID") {
@@ -440,8 +442,8 @@
   // TODO(thestig): Move to Init() and check return value.
   ::FlateEncode(m_Acc.GetData(), m_Acc.GetSize(), &m_pData, &m_dwSize);
   m_pDict = ToDictionary(pStream->GetDict()->Clone().release());
-  m_pDict->SetIntegerFor("Length", m_dwSize);
-  m_pDict->SetNameFor("Filter", "FlateDecode");
+  m_pDict->SetNewFor<CPDF_Number>("Length", static_cast<int>(m_dwSize));
+  m_pDict->SetNewFor<CPDF_Name>("Filter", "FlateDecode");
   m_pDict->RemoveFor("DecodeParms");
 }
 
@@ -993,7 +995,8 @@
   if ((uint32_t)encoder.m_pDict->GetIntegerFor("Length") !=
       encryptor.m_dwSize) {
     encoder.CloneDict();
-    encoder.m_pDict->SetIntegerFor("Length", encryptor.m_dwSize);
+    encoder.m_pDict->SetNewFor<CPDF_Number>(
+        "Length", static_cast<int>(encryptor.m_dwSize));
   }
   if (WriteDirectObj(objnum, encoder.m_pDict) < 0) {
     return -1;
@@ -1106,7 +1109,8 @@
       if ((uint32_t)encoder.m_pDict->GetIntegerFor("Length") !=
           encryptor.m_dwSize) {
         encoder.CloneDict();
-        encoder.m_pDict->SetIntegerFor("Length", encryptor.m_dwSize);
+        encoder.m_pDict->SetNewFor<CPDF_Number>(
+            "Length", static_cast<int>(encryptor.m_dwSize));
       }
       if (WriteDirectObj(objnum, encoder.m_pDict) < 0) {
         return -1;
@@ -1189,7 +1193,7 @@
       for (const auto& it : *p) {
         bool bSignValue = false;
         const CFX_ByteString& key = it.first;
-        CPDF_Object* pValue = it.second;
+        CPDF_Object* pValue = it.second.get();
         if (m_File.AppendString("/") < 0) {
           return -1;
         }
@@ -1711,7 +1715,7 @@
       CPDF_Dictionary* p = m_pParser->GetTrailer();
       for (const auto& it : *p) {
         const CFX_ByteString& key = it.first;
-        CPDF_Object* pValue = it.second;
+        CPDF_Object* pValue = it.second.get();
         // TODO(ochang): Consolidate with similar check in
         // PDF_CreatorWriteTrailer.
         if (key == "Encrypt" || key == "Size" || key == "Filter" ||
diff --git a/core/fpdfapi/font/cpdf_font.cpp b/core/fpdfapi/font/cpdf_font.cpp
index c5da4ea..c7725c3 100644
--- a/core/fpdfapi/font/cpdf_font.cpp
+++ b/core/fpdfapi/font/cpdf_font.cpp
@@ -7,6 +7,7 @@
 #include "core/fpdfapi/font/cpdf_font.h"
 
 #include <memory>
+#include <utility>
 #include <vector>
 
 #include "core/fpdfapi/cpdf_modulemgr.h"
@@ -310,10 +311,10 @@
     return pFont;
 
   CPDF_Dictionary* pDict = new CPDF_Dictionary(pDoc->GetByteStringPool());
-  pDict->SetNameFor("Type", "Font");
-  pDict->SetNameFor("Subtype", "Type1");
-  pDict->SetNameFor("BaseFont", fontname);
-  pDict->SetNameFor("Encoding", "WinAnsiEncoding");
+  pDict->SetNewFor<CPDF_Name>("Type", "Font");
+  pDict->SetNewFor<CPDF_Name>("Subtype", "Type1");
+  pDict->SetNewFor<CPDF_Name>("BaseFont", fontname);
+  pDict->SetNewFor<CPDF_Name>("Encoding", "WinAnsiEncoding");
   return pFontGlobals->Set(pDoc, font_id, CPDF_Font::Create(nullptr, pDict));
 }
 
diff --git a/core/fpdfapi/font/cpdf_fontencoding.cpp b/core/fpdfapi/font/cpdf_fontencoding.cpp
index da607e6..df21267 100644
--- a/core/fpdfapi/font/cpdf_fontencoding.cpp
+++ b/core/fpdfapi/font/cpdf_fontencoding.cpp
@@ -6,6 +6,8 @@
 
 #include "core/fpdfapi/font/cpdf_fontencoding.h"
 
+#include <utility>
+
 #include "core/fpdfapi/parser/cpdf_array.h"
 #include "core/fpdfapi/parser/cpdf_dictionary.h"
 #include "core/fpdfapi/parser/cpdf_name.h"
@@ -1701,7 +1703,7 @@
   }
   const uint16_t* pStandard =
       PDF_UnicodesForPredefinedCharSet(PDFFONT_ENCODING_WINANSI);
-  CPDF_Array* pDiff = new CPDF_Array;
+  auto pDiff = pdfium::MakeUnique<CPDF_Array>();
   for (int i = 0; i < 256; i++) {
     if (pStandard[i] == m_Unicodes[i])
       continue;
@@ -1711,8 +1713,8 @@
   }
 
   CPDF_Dictionary* pDict = new CPDF_Dictionary(pPool);
-  pDict->SetNameFor("BaseEncoding", "WinAnsiEncoding");
-  pDict->SetFor("Differences", pDiff);
+  pDict->SetNewFor<CPDF_Name>("BaseEncoding", "WinAnsiEncoding");
+  pDict->SetFor("Differences", std::move(pDiff));
   return pDict;
 }
 
diff --git a/core/fpdfapi/page/cpdf_allstates.cpp b/core/fpdfapi/page/cpdf_allstates.cpp
index 012c134..f88342d 100644
--- a/core/fpdfapi/page/cpdf_allstates.cpp
+++ b/core/fpdfapi/page/cpdf_allstates.cpp
@@ -6,6 +6,8 @@
 
 #include "core/fpdfapi/page/cpdf_allstates.h"
 
+#include <algorithm>
+
 #include "core/fpdfapi/page/pageint.h"
 #include "core/fpdfapi/parser/cpdf_array.h"
 #include "core/fpdfapi/parser/cpdf_dictionary.h"
@@ -52,7 +54,7 @@
                                   CPDF_StreamContentParser* pParser) {
   for (const auto& it : *pGS) {
     const CFX_ByteString& key_str = it.first;
-    CPDF_Object* pElement = it.second;
+    CPDF_Object* pElement = it.second.get();
     CPDF_Object* pObject = pElement ? pElement->GetDirect() : nullptr;
     if (!pObject)
       continue;
diff --git a/core/fpdfapi/page/cpdf_colorspace.cpp b/core/fpdfapi/page/cpdf_colorspace.cpp
index 0c023d1..b1675d8 100644
--- a/core/fpdfapi/page/cpdf_colorspace.cpp
+++ b/core/fpdfapi/page/cpdf_colorspace.cpp
@@ -345,7 +345,7 @@
 
     for (const auto& it : *pDict) {
       std::unique_ptr<CPDF_ColorSpace> pRet;
-      CPDF_Object* pValue = it.second;
+      CPDF_Object* pValue = it.second.get();
       if (ToName(pValue))
         pRet.reset(ColorspaceFromName(pValue->GetString()));
       if (pRet)
diff --git a/core/fpdfapi/page/cpdf_docpagedata.cpp b/core/fpdfapi/page/cpdf_docpagedata.cpp
index b849bc4..3df7710 100644
--- a/core/fpdfapi/page/cpdf_docpagedata.cpp
+++ b/core/fpdfapi/page/cpdf_docpagedata.cpp
@@ -7,6 +7,7 @@
 #include "core/fpdfapi/page/cpdf_docpagedata.h"
 
 #include <algorithm>
+#include <memory>
 #include <set>
 
 #include "core/fdrm/crypto/fx_crypt.h"
@@ -21,6 +22,7 @@
 #include "core/fpdfapi/parser/cpdf_array.h"
 #include "core/fpdfapi/parser/cpdf_dictionary.h"
 #include "core/fpdfapi/parser/cpdf_document.h"
+#include "core/fpdfapi/parser/cpdf_name.h"
 #include "core/fpdfapi/parser/cpdf_stream_acc.h"
 #include "third_party/base/stl_util.h"
 
@@ -176,12 +178,13 @@
   }
 
   CPDF_Dictionary* pDict = m_pPDFDoc->NewIndirect<CPDF_Dictionary>();
-  pDict->SetNameFor("Type", "Font");
-  pDict->SetNameFor("Subtype", "Type1");
-  pDict->SetNameFor("BaseFont", fontName);
+  pDict->SetNewFor<CPDF_Name>("Type", "Font");
+  pDict->SetNewFor<CPDF_Name>("Subtype", "Type1");
+  pDict->SetNewFor<CPDF_Name>("BaseFont", fontName);
   if (pEncoding) {
-    pDict->SetFor("Encoding",
-                  pEncoding->Realize(m_pPDFDoc->GetByteStringPool()));
+    pDict->SetFor(
+        "Encoding",
+        pdfium::WrapUnique(pEncoding->Realize(m_pPDFDoc->GetByteStringPool())));
   }
 
   std::unique_ptr<CPDF_Font> pFont = CPDF_Font::Create(m_pPDFDoc, pDict);
diff --git a/core/fpdfapi/page/cpdf_image.cpp b/core/fpdfapi/page/cpdf_image.cpp
index 1c3aa89..8ded34e 100644
--- a/core/fpdfapi/page/cpdf_image.cpp
+++ b/core/fpdfapi/page/cpdf_image.cpp
@@ -8,6 +8,7 @@
 
 #include <algorithm>
 #include <memory>
+#include <utility>
 #include <vector>
 
 #include "core/fpdfapi/cpdf_modulemgr.h"
@@ -97,10 +98,10 @@
 
   CPDF_Dictionary* pDict =
       new CPDF_Dictionary(m_pDocument->GetByteStringPool());
-  pDict->SetNameFor("Type", "XObject");
-  pDict->SetNameFor("Subtype", "Image");
-  pDict->SetIntegerFor("Width", width);
-  pDict->SetIntegerFor("Height", height);
+  pDict->SetNewFor<CPDF_Name>("Type", "XObject");
+  pDict->SetNewFor<CPDF_Name>("Subtype", "Image");
+  pDict->SetNewFor<CPDF_Number>("Width", width);
+  pDict->SetNewFor<CPDF_Number>("Height", height);
   const FX_CHAR* csname = nullptr;
   if (num_comps == 1) {
     csname = "DeviceGray";
@@ -108,21 +109,18 @@
     csname = "DeviceRGB";
   } else if (num_comps == 4) {
     csname = "DeviceCMYK";
-    CPDF_Array* pDecode = new CPDF_Array;
+    CPDF_Array* pDecode = pDict->SetNewFor<CPDF_Array>("Decode");
     for (int n = 0; n < 4; n++) {
       pDecode->AddNew<CPDF_Number>(1);
       pDecode->AddNew<CPDF_Number>(0);
     }
-    pDict->SetFor("Decode", pDecode);
   }
-  pDict->SetNameFor("ColorSpace", csname);
-  pDict->SetIntegerFor("BitsPerComponent", bits);
-  pDict->SetNameFor("Filter", "DCTDecode");
+  pDict->SetNewFor<CPDF_Name>("ColorSpace", csname);
+  pDict->SetNewFor<CPDF_Number>("BitsPerComponent", bits);
+  pDict->SetNewFor<CPDF_Name>("Filter", "DCTDecode");
   if (!color_trans) {
-    CPDF_Dictionary* pParms =
-        new CPDF_Dictionary(m_pDocument->GetByteStringPool());
-    pDict->SetFor("DecodeParms", pParms);
-    pParms->SetIntegerFor("ColorTransform", 0);
+    CPDF_Dictionary* pParms = pDict->SetNewFor<CPDF_Dictionary>("DecodeParms");
+    pParms->SetNewFor<CPDF_Number>("ColorTransform", 0);
   }
   m_bIsMask = false;
   m_Width = width;
@@ -166,10 +164,10 @@
 
   CPDF_Dictionary* pDict =
       new CPDF_Dictionary(m_pDocument->GetByteStringPool());
-  pDict->SetNameFor("Type", "XObject");
-  pDict->SetNameFor("Subtype", "Image");
-  pDict->SetIntegerFor("Width", BitmapWidth);
-  pDict->SetIntegerFor("Height", BitmapHeight);
+  pDict->SetNewFor<CPDF_Name>("Type", "XObject");
+  pDict->SetNewFor<CPDF_Name>("Subtype", "Image");
+  pDict->SetNewFor<CPDF_Number>("Width", BitmapWidth);
+  pDict->SetNewFor<CPDF_Number>("Height", BitmapHeight);
   uint8_t* dest_buf = nullptr;
   FX_STRSIZE dest_pitch = 0, dest_size = 0, opType = -1;
   if (bpp == 1) {
@@ -181,15 +179,14 @@
       ArgbDecode(pBitmap->GetPaletteArgb(1), set_a, set_r, set_g, set_b);
     }
     if (set_a == 0 || reset_a == 0) {
-      pDict->SetFor("ImageMask", new CPDF_Boolean(true));
+      pDict->SetNewFor<CPDF_Boolean>("ImageMask", true);
       if (reset_a == 0) {
-        CPDF_Array* pArray = new CPDF_Array;
+        CPDF_Array* pArray = pDict->SetNewFor<CPDF_Array>("Decode");
         pArray->AddNew<CPDF_Number>(1);
         pArray->AddNew<CPDF_Number>(0);
-        pDict->SetFor("Decode", pArray);
       }
     } else {
-      CPDF_Array* pCS = new CPDF_Array;
+      CPDF_Array* pCS = pDict->SetNewFor<CPDF_Array>("ColorSpace");
       pCS->AddNew<CPDF_Name>("Indexed");
       pCS->AddNew<CPDF_Name>("DeviceRGB");
       pCS->AddNew<CPDF_Number>(1);
@@ -203,9 +200,8 @@
       pBuf[5] = (FX_CHAR)set_b;
       ct.ReleaseBuffer(6);
       pCS->AddNew<CPDF_String>(ct, true);
-      pDict->SetFor("ColorSpace", pCS);
     }
-    pDict->SetIntegerFor("BitsPerComponent", 1);
+    pDict->SetNewFor<CPDF_Number>("BitsPerComponent", 1);
     dest_pitch = (BitmapWidth + 7) / 8;
     if ((iCompress & 0x03) == PDF_IMAGE_NO_COMPRESS) {
       opType = 1;
@@ -232,11 +228,12 @@
           pColorTable, iPalette * 3,
           new CPDF_Dictionary(m_pDocument->GetByteStringPool()));
       pCS->AddNew<CPDF_Reference>(m_pDocument, pCTS->GetObjNum());
-      pDict->SetReferenceFor("ColorSpace", m_pDocument, pCS);
+      pDict->SetNewFor<CPDF_Reference>("ColorSpace", m_pDocument,
+                                       pCS->GetObjNum());
     } else {
-      pDict->SetNameFor("ColorSpace", "DeviceGray");
+      pDict->SetNewFor<CPDF_Name>("ColorSpace", "DeviceGray");
     }
-    pDict->SetIntegerFor("BitsPerComponent", 8);
+    pDict->SetNewFor<CPDF_Number>("BitsPerComponent", 8);
     if ((iCompress & 0x03) == PDF_IMAGE_NO_COMPRESS) {
       dest_pitch = BitmapWidth;
       opType = 1;
@@ -244,8 +241,8 @@
       opType = 0;
     }
   } else {
-    pDict->SetNameFor("ColorSpace", "DeviceRGB");
-    pDict->SetIntegerFor("BitsPerComponent", 8);
+    pDict->SetNewFor<CPDF_Name>("ColorSpace", "DeviceRGB");
+    pDict->SetNewFor<CPDF_Number>("BitsPerComponent", 8);
     if ((iCompress & 0x03) == PDF_IMAGE_NO_COMPRESS) {
       dest_pitch = BitmapWidth * 3;
       opType = 2;
@@ -266,12 +263,12 @@
     FX_STRSIZE mask_size = 0;
     CPDF_Dictionary* pMaskDict =
         new CPDF_Dictionary(m_pDocument->GetByteStringPool());
-    pMaskDict->SetNameFor("Type", "XObject");
-    pMaskDict->SetNameFor("Subtype", "Image");
-    pMaskDict->SetIntegerFor("Width", maskWidth);
-    pMaskDict->SetIntegerFor("Height", maskHeight);
-    pMaskDict->SetNameFor("ColorSpace", "DeviceGray");
-    pMaskDict->SetIntegerFor("BitsPerComponent", 8);
+    pMaskDict->SetNewFor<CPDF_Name>("Type", "XObject");
+    pMaskDict->SetNewFor<CPDF_Name>("Subtype", "Image");
+    pMaskDict->SetNewFor<CPDF_Number>("Width", maskWidth);
+    pMaskDict->SetNewFor<CPDF_Number>("Height", maskHeight);
+    pMaskDict->SetNewFor<CPDF_Name>("ColorSpace", "DeviceGray");
+    pMaskDict->SetNewFor<CPDF_Number>("BitsPerComponent", 8);
     if (pMaskBitmap->GetBPP() == 8 &&
         (iCompress & PDF_IMAGE_MASK_LOSSY_COMPRESS) != 0) {
     } else if (pMaskBitmap->GetFormat() == FXDIB_1bppMask) {
@@ -283,10 +280,11 @@
                      maskWidth);
       }
     }
-    pMaskDict->SetIntegerFor("Length", mask_size);
-    pDict->SetReferenceFor(
+    pMaskDict->SetNewFor<CPDF_Number>("Length", mask_size);
+    pDict->SetNewFor<CPDF_Reference>(
         "SMask", m_pDocument,
-        m_pDocument->NewIndirect<CPDF_Stream>(mask_buf, mask_size, pMaskDict));
+        m_pDocument->NewIndirect<CPDF_Stream>(mask_buf, mask_size, pMaskDict)
+            ->GetObjNum());
     if (bDeleteMask)
       delete pMaskBitmap;
   }
diff --git a/core/fpdfapi/page/cpdf_streamcontentparser.cpp b/core/fpdfapi/page/cpdf_streamcontentparser.cpp
index aed5d4b..6ddd278 100644
--- a/core/fpdfapi/page/cpdf_streamcontentparser.cpp
+++ b/core/fpdfapi/page/cpdf_streamcontentparser.cpp
@@ -30,6 +30,7 @@
 #include "core/fpdfapi/parser/cpdf_document.h"
 #include "core/fpdfapi/parser/cpdf_name.h"
 #include "core/fpdfapi/parser/cpdf_number.h"
+#include "core/fpdfapi/parser/cpdf_reference.h"
 #include "core/fpdfapi/parser/cpdf_stream.h"
 #include "core/fpdfapi/parser/fpdf_parser_decode.h"
 #include "core/fxcrt/fx_safe_types.h"
@@ -172,7 +173,7 @@
       std::vector<AbbrReplacementOp> replacements;
       for (const auto& it : *pDict) {
         CFX_ByteString key = it.first;
-        CPDF_Object* value = it.second;
+        CPDF_Object* value = it.second.get();
         CFX_ByteStringC fullname = FindFullName(
             InlineKeyAbbr, FX_ArraySize(InlineKeyAbbr), key.AsStringC());
         if (!fullname.IsEmpty()) {
@@ -203,7 +204,7 @@
         if (op.is_replace_key)
           pDict->ReplaceKey(op.key, CFX_ByteString(op.replacement));
         else
-          pDict->SetNameFor(op.key, CFX_ByteString(op.replacement));
+          pDict->SetNewFor<CPDF_Name>(op.key, CFX_ByteString(op.replacement));
       }
       break;
     }
@@ -650,13 +651,13 @@
     }
     CFX_ByteString key((const FX_CHAR*)m_pSyntax->GetWordBuf() + 1,
                        m_pSyntax->GetWordSize() - 1);
-    std::unique_ptr<CPDF_Object> pObj(m_pSyntax->ReadNextObject(false, 0));
+    auto pObj = pdfium::WrapUnique(m_pSyntax->ReadNextObject(false, 0));
     if (!key.IsEmpty()) {
       uint32_t dwObjNum = pObj ? pObj->GetObjNum() : 0;
       if (dwObjNum)
-        pDict->SetReferenceFor(key, m_pDocument, dwObjNum);
+        pDict->SetNewFor<CPDF_Reference>(key, m_pDocument, dwObjNum);
       else
-        pDict->SetFor(key, pObj.release());
+        pDict->SetFor(key, std::move(pObj));
     }
   }
   ReplaceAbbr(pDict);
@@ -667,14 +668,12 @@
       CFX_ByteString name = pCSObj->GetString();
       if (name != "DeviceRGB" && name != "DeviceGray" && name != "DeviceCMYK") {
         pCSObj = FindResourceObj("ColorSpace", name);
-        if (pCSObj && pCSObj->IsInline()) {
-          pCSObj = pCSObj->Clone().release();
-          pDict->SetFor("ColorSpace", pCSObj);
-        }
+        if (pCSObj && pCSObj->IsInline())
+          pDict->SetFor("ColorSpace", pCSObj->Clone());
       }
     }
   }
-  pDict->SetNameFor("Subtype", "Image");
+  pDict->SetNewFor<CPDF_Name>("Subtype", "Image");
   std::unique_ptr<CPDF_Stream> pStream(
       m_pSyntax->ReadInlineStream(m_pDocument, pDict, pCSObj));
   bool bGaveDictAway = !!pStream;
diff --git a/core/fpdfapi/page/cpdf_streamparser.cpp b/core/fpdfapi/page/cpdf_streamparser.cpp
index 2c2be0b..6b4a362 100644
--- a/core/fpdfapi/page/cpdf_streamparser.cpp
+++ b/core/fpdfapi/page/cpdf_streamparser.cpp
@@ -8,6 +8,8 @@
 
 #include <limits.h>
 
+#include <utility>
+
 #include "core/fpdfapi/cpdf_modulemgr.h"
 #include "core/fpdfapi/page/cpdf_docpagedata.h"
 #include "core/fpdfapi/parser/cpdf_array.h"
@@ -230,7 +232,7 @@
     FXSYS_memcpy(pData, m_pBuf + m_Pos, dwStreamSize);
     m_Pos += dwStreamSize;
   }
-  pDict->SetIntegerFor("Length", (int)dwStreamSize);
+  pDict->SetNewFor<CPDF_Number>("Length", (int)dwStreamSize);
   return new CPDF_Stream(pData, dwStreamSize, pDict);
 }
 
@@ -361,16 +363,13 @@
 
       CFX_ByteString key =
           PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1));
-      CPDF_Object* pObj = ReadNextObject(true, 0);
+      auto pObj = pdfium::WrapUnique(ReadNextObject(true, 0));
       if (!pObj) {
         delete pDict;
         return nullptr;
       }
-
-      if (key.IsEmpty())
-        delete pObj;
-      else
-        pDict->SetFor(key, pObj);
+      if (!key.IsEmpty())
+        pDict->SetFor(key, std::move(pObj));
     }
     return pDict;
   }
diff --git a/core/fpdfapi/parser/cfdf_document.cpp b/core/fpdfapi/parser/cfdf_document.cpp
index 0bfcb65..546308c 100644
--- a/core/fpdfapi/parser/cfdf_document.cpp
+++ b/core/fpdfapi/parser/cfdf_document.cpp
@@ -6,6 +6,9 @@
 
 #include "core/fpdfapi/parser/cfdf_document.h"
 
+#include <memory>
+#include <utility>
+
 #include "core/fpdfapi/edit/cpdf_creator.h"
 #include "core/fpdfapi/parser/cpdf_dictionary.h"
 #include "core/fpdfapi/parser/cpdf_syntax_parser.h"
@@ -25,8 +28,7 @@
 CFDF_Document* CFDF_Document::CreateNewDoc() {
   CFDF_Document* pDoc = new CFDF_Document;
   pDoc->m_pRootDict = pDoc->NewIndirect<CPDF_Dictionary>();
-  pDoc->m_pRootDict->SetFor("FDF",
-                            new CPDF_Dictionary(pDoc->GetByteStringPool()));
+  pDoc->m_pRootDict->SetNewFor<CPDF_Dictionary>("FDF");
   return pDoc;
 }
 
diff --git a/core/fpdfapi/parser/cpdf_data_avail.cpp b/core/fpdfapi/parser/cpdf_data_avail.cpp
index 6af2da6..1ac6e06 100644
--- a/core/fpdfapi/parser/cpdf_data_avail.cpp
+++ b/core/fpdfapi/parser/cpdf_data_avail.cpp
@@ -142,10 +142,8 @@
           continue;
 
         for (const auto& it : *pDict) {
-          const CFX_ByteString& key = it.first;
-          CPDF_Object* value = it.second;
-          if (key != "Parent")
-            new_obj_array.push_back(value);
+          if (it.first != "Parent")
+            new_obj_array.push_back(it.second.get());
         }
       } break;
       case CPDF_Object::REFERENCE: {
diff --git a/core/fpdfapi/parser/cpdf_dictionary.cpp b/core/fpdfapi/parser/cpdf_dictionary.cpp
index 3621dbc..4087753 100644
--- a/core/fpdfapi/parser/cpdf_dictionary.cpp
+++ b/core/fpdfapi/parser/cpdf_dictionary.cpp
@@ -26,12 +26,12 @@
     : m_pPool(pPool) {}
 
 CPDF_Dictionary::~CPDF_Dictionary() {
-  // Mark the object as deleted so that it will not be deleted again
-  // in case of cyclic references.
+  // Mark the object as deleted so that it will not be deleted again,
+  // and break cyclic references.
   m_ObjNum = kInvalidObjNum;
-  for (const auto& it : m_Map) {
-    if (it.second && it.second->GetObjNum() != kInvalidObjNum)
-      delete it.second;
+  for (auto& it : m_Map) {
+    if (it.second && it.second->GetObjNum() == kInvalidObjNum)
+      it.second.release();
   }
 }
 
@@ -67,10 +67,9 @@
   pVisited->insert(this);
   auto pCopy = pdfium::MakeUnique<CPDF_Dictionary>(m_pPool);
   for (const auto& it : *this) {
-    CPDF_Object* value = it.second;
-    if (!pdfium::ContainsKey(*pVisited, value)) {
+    if (!pdfium::ContainsKey(*pVisited, it.second.get())) {
       pCopy->m_Map.insert(std::make_pair(
-          it.first, value->CloneNonCyclic(bDirect, pVisited).release()));
+          it.first, it.second->CloneNonCyclic(bDirect, pVisited)));
     }
   }
   return std::move(pCopy);
@@ -78,7 +77,7 @@
 
 CPDF_Object* CPDF_Dictionary::GetObjectFor(const CFX_ByteString& key) const {
   auto it = m_Map.find(key);
-  return it != m_Map.end() ? it->second : nullptr;
+  return it != m_Map.end() ? it->second.get() : nullptr;
 }
 
 CPDF_Object* CPDF_Dictionary::GetDirectObjectFor(
@@ -173,23 +172,16 @@
   return pType && pType->GetString() == "Sig";
 }
 
-void CPDF_Dictionary::SetFor(const CFX_ByteString& key, CPDF_Object* pObj) {
-  CHECK(!pObj || pObj->IsInline());
-  auto it = m_Map.find(key);
-  if (it == m_Map.end()) {
-    if (pObj)
-      m_Map.insert(std::make_pair(MaybeIntern(key), pObj));
-    return;
+CPDF_Object* CPDF_Dictionary::SetFor(const CFX_ByteString& key,
+                                     std::unique_ptr<CPDF_Object> pObj) {
+  if (!pObj) {
+    m_Map.erase(key);
+    return nullptr;
   }
-
-  if (it->second == pObj)
-    return;
-  delete it->second;
-
-  if (pObj)
-    it->second = pObj;
-  else
-    m_Map.erase(it);
+  ASSERT(pObj->IsInline());
+  CPDF_Object* pRet = pObj.get();
+  m_Map[MaybeIntern(key)] = std::move(pObj);
+  return pRet;
 }
 
 void CPDF_Dictionary::ConvertToIndirectObjectFor(
@@ -199,18 +191,12 @@
   if (it == m_Map.end() || it->second->IsReference())
     return;
 
-  CPDF_Object* pObj =
-      pHolder->AddIndirectObject(pdfium::WrapUnique(it->second));
-  it->second = new CPDF_Reference(pHolder, pObj->GetObjNum());
+  CPDF_Object* pObj = pHolder->AddIndirectObject(std::move(it->second));
+  it->second = pdfium::MakeUnique<CPDF_Reference>(pHolder, pObj->GetObjNum());
 }
 
 void CPDF_Dictionary::RemoveFor(const CFX_ByteString& key) {
-  auto it = m_Map.find(key);
-  if (it == m_Map.end())
-    return;
-
-  delete it->second;
-  m_Map.erase(it);
+  m_Map.erase(key);
 }
 
 void CPDF_Dictionary::ReplaceKey(const CFX_ByteString& oldkey,
@@ -223,70 +209,28 @@
   if (new_it == old_it)
     return;
 
-  if (new_it != m_Map.end()) {
-    delete new_it->second;
-    new_it->second = old_it->second;
-  } else {
-    m_Map.insert(std::make_pair(MaybeIntern(newkey), old_it->second));
-  }
+  m_Map[MaybeIntern(newkey)] = std::move(old_it->second);
   m_Map.erase(old_it);
 }
 
-void CPDF_Dictionary::SetIntegerFor(const CFX_ByteString& key, int i) {
-  SetFor(key, new CPDF_Number(i));
-}
-
-void CPDF_Dictionary::SetNameFor(const CFX_ByteString& key,
-                                 const CFX_ByteString& name) {
-  SetFor(key, new CPDF_Name(GetByteStringPool(), name));
-}
-
-void CPDF_Dictionary::SetStringFor(const CFX_ByteString& key,
-                                   const CFX_ByteString& str) {
-  SetFor(key, new CPDF_String(GetByteStringPool(), str, false));
-}
-
-void CPDF_Dictionary::SetReferenceFor(const CFX_ByteString& key,
-                                      CPDF_IndirectObjectHolder* pDoc,
-                                      uint32_t objnum) {
-  SetFor(key, new CPDF_Reference(pDoc, objnum));
-}
-
-void CPDF_Dictionary::SetReferenceFor(const CFX_ByteString& key,
-                                      CPDF_IndirectObjectHolder* pDoc,
-                                      CPDF_Object* pObj) {
-  ASSERT(!pObj->IsInline());
-  SetFor(key, new CPDF_Reference(pDoc, pObj->GetObjNum()));
-}
-
-void CPDF_Dictionary::SetNumberFor(const CFX_ByteString& key, FX_FLOAT f) {
-  SetFor(key, new CPDF_Number(f));
-}
-
-void CPDF_Dictionary::SetBooleanFor(const CFX_ByteString& key, bool bValue) {
-  SetFor(key, new CPDF_Boolean(bValue));
-}
-
 void CPDF_Dictionary::SetRectFor(const CFX_ByteString& key,
                                  const CFX_FloatRect& rect) {
-  CPDF_Array* pArray = new CPDF_Array;
+  CPDF_Array* pArray = SetNewFor<CPDF_Array>(key);
   pArray->AddNew<CPDF_Number>(rect.left);
   pArray->AddNew<CPDF_Number>(rect.bottom);
   pArray->AddNew<CPDF_Number>(rect.right);
   pArray->AddNew<CPDF_Number>(rect.top);
-  SetFor(key, pArray);
 }
 
 void CPDF_Dictionary::SetMatrixFor(const CFX_ByteString& key,
                                    const CFX_Matrix& matrix) {
-  CPDF_Array* pArray = new CPDF_Array;
+  CPDF_Array* pArray = SetNewFor<CPDF_Array>(key);
   pArray->AddNew<CPDF_Number>(matrix.a);
   pArray->AddNew<CPDF_Number>(matrix.b);
   pArray->AddNew<CPDF_Number>(matrix.c);
   pArray->AddNew<CPDF_Number>(matrix.d);
   pArray->AddNew<CPDF_Number>(matrix.e);
   pArray->AddNew<CPDF_Number>(matrix.f);
-  SetFor(key, pArray);
 }
 
 CFX_ByteString CPDF_Dictionary::MaybeIntern(const CFX_ByteString& str) {
diff --git a/core/fpdfapi/parser/cpdf_dictionary.h b/core/fpdfapi/parser/cpdf_dictionary.h
index ebfd7e9..5d33380 100644
--- a/core/fpdfapi/parser/cpdf_dictionary.h
+++ b/core/fpdfapi/parser/cpdf_dictionary.h
@@ -8,6 +8,7 @@
 #define CORE_FPDFAPI_PARSER_CPDF_DICTIONARY_H_
 
 #include <map>
+#include <memory>
 #include <set>
 
 #include "core/fpdfapi/parser/cpdf_object.h"
@@ -21,8 +22,8 @@
 
 class CPDF_Dictionary : public CPDF_Object {
  public:
-  using iterator = std::map<CFX_ByteString, CPDF_Object*>::iterator;
-  using const_iterator = std::map<CFX_ByteString, CPDF_Object*>::const_iterator;
+  using const_iterator =
+      std::map<CFX_ByteString, std::unique_ptr<CPDF_Object>>::const_iterator;
 
   CPDF_Dictionary();
   explicit CPDF_Dictionary(const CFX_WeakPtr<CFX_ByteStringPool>& pPool);
@@ -60,19 +61,27 @@
   bool IsSignatureDict() const;
 
   // Set* functions invalidate iterators for the element with the key |key|.
-  void SetFor(const CFX_ByteString& key, CPDF_Object* pObj);
-  void SetBooleanFor(const CFX_ByteString& key, bool bValue);
-  void SetNameFor(const CFX_ByteString& key, const CFX_ByteString& name);
-  void SetStringFor(const CFX_ByteString& key, const CFX_ByteString& str);
-  void SetIntegerFor(const CFX_ByteString& key, int i);
-  void SetNumberFor(const CFX_ByteString& key, FX_FLOAT f);
-  void SetReferenceFor(const CFX_ByteString& key,
-                       CPDF_IndirectObjectHolder* pDoc,
-                       uint32_t objnum);
-  void SetReferenceFor(const CFX_ByteString& key,
-                       CPDF_IndirectObjectHolder* pDoc,
-                       CPDF_Object* pObj);
+  // Takes ownership of |pObj|, returns an unowned pointer to it.
+  CPDF_Object* SetFor(const CFX_ByteString& key,
+                      std::unique_ptr<CPDF_Object> pObj);
 
+  // Creates a new object owned by the dictionary and returns an unowned
+  // pointer to it.
+  template <typename T, typename... Args>
+  typename std::enable_if<!CanInternStrings<T>::value, T*>::type SetNewFor(
+      const CFX_ByteString& key,
+      Args... args) {
+    return static_cast<T*>(SetFor(key, pdfium::MakeUnique<T>(args...)));
+  }
+  template <typename T, typename... Args>
+  typename std::enable_if<CanInternStrings<T>::value, T*>::type SetNewFor(
+      const CFX_ByteString& key,
+      Args... args) {
+    return static_cast<T*>(
+        SetFor(key, pdfium::MakeUnique<T>(m_pPool, args...)));
+  }
+
+  // Convenience functions to convert native objects to array form.
   void SetRectFor(const CFX_ByteString& key, const CFX_FloatRect& rect);
   void SetMatrixFor(const CFX_ByteString& key, const CFX_Matrix& matrix);
 
@@ -85,8 +94,6 @@
   // Invalidates iterators for the element with the key |oldkey|.
   void ReplaceKey(const CFX_ByteString& oldkey, const CFX_ByteString& newkey);
 
-  iterator begin() { return m_Map.begin(); }
-  iterator end() { return m_Map.end(); }
   const_iterator begin() const { return m_Map.begin(); }
   const_iterator end() const { return m_Map.end(); }
 
@@ -99,7 +106,7 @@
       std::set<const CPDF_Object*>* visited) const override;
 
   CFX_WeakPtr<CFX_ByteStringPool> m_pPool;
-  std::map<CFX_ByteString, CPDF_Object*> m_Map;
+  std::map<CFX_ByteString, std::unique_ptr<CPDF_Object>> m_Map;
 };
 
 inline CPDF_Dictionary* ToDictionary(CPDF_Object* obj) {
diff --git a/core/fpdfapi/parser/cpdf_document.cpp b/core/fpdfapi/parser/cpdf_document.cpp
index bafeefe..97f55f8 100644
--- a/core/fpdfapi/parser/cpdf_document.cpp
+++ b/core/fpdfapi/parser/cpdf_document.cpp
@@ -8,6 +8,7 @@
 
 #include <memory>
 #include <set>
+#include <utility>
 #include <vector>
 
 #include "core/fpdfapi/cpdf_modulemgr.h"
@@ -22,6 +23,7 @@
 #include "core/fpdfapi/parser/cpdf_number.h"
 #include "core/fpdfapi/parser/cpdf_parser.h"
 #include "core/fpdfapi/parser/cpdf_reference.h"
+#include "core/fpdfapi/parser/cpdf_string.h"
 #include "core/fpdfapi/parser/cpdf_stream.h"
 #include "core/fpdfapi/render/cpdf_docrenderdata.h"
 #include "core/fpdfapi/render/render_int.h"
@@ -265,7 +267,7 @@
       count++;
     }
   }
-  pPages->SetIntegerFor("Count", count);
+  pPages->SetNewFor<CPDF_Number>("Count", count);
   return count;
 }
 
@@ -304,11 +306,11 @@
     basefont += ",Bold";
   else if (italic)
     basefont += ",Italic";
-  pBaseDict->SetNameFor("Subtype", "TrueType");
-  pBaseDict->SetNameFor("BaseFont", basefont);
-  pBaseDict->SetNumberFor("FirstChar", 32);
-  pBaseDict->SetNumberFor("LastChar", 255);
-  pBaseDict->SetFor("Widths", pWidths);
+  pBaseDict->SetNewFor<CPDF_Name>("Subtype", "TrueType");
+  pBaseDict->SetNewFor<CPDF_Name>("BaseFont", basefont);
+  pBaseDict->SetNewFor<CPDF_Number>("FirstChar", 32);
+  pBaseDict->SetNewFor<CPDF_Number>("LastChar", 255);
+  pBaseDict->SetFor("Widths", pdfium::WrapUnique(pWidths));
 }
 
 std::unique_ptr<CPDF_Dictionary> CalculateFontDesc(CPDF_Document* pDoc,
@@ -321,14 +323,14 @@
                                                    int32_t stemV) {
   auto pFontDesc =
       pdfium::MakeUnique<CPDF_Dictionary>(pDoc->GetByteStringPool());
-  pFontDesc->SetNameFor("Type", "FontDescriptor");
-  pFontDesc->SetNameFor("FontName", basefont);
-  pFontDesc->SetIntegerFor("Flags", flags);
-  pFontDesc->SetFor("FontBBox", bbox);
-  pFontDesc->SetIntegerFor("ItalicAngle", italicangle);
-  pFontDesc->SetIntegerFor("Ascent", ascend);
-  pFontDesc->SetIntegerFor("Descent", descend);
-  pFontDesc->SetIntegerFor("StemV", stemV);
+  pFontDesc->SetNewFor<CPDF_Name>("Type", "FontDescriptor");
+  pFontDesc->SetNewFor<CPDF_Name>("FontName", basefont);
+  pFontDesc->SetNewFor<CPDF_Number>("Flags", flags);
+  pFontDesc->SetFor("FontBBox", pdfium::WrapUnique(bbox));
+  pFontDesc->SetNewFor<CPDF_Number>("ItalicAngle", italicangle);
+  pFontDesc->SetNewFor<CPDF_Number>("Ascent", ascend);
+  pFontDesc->SetNewFor<CPDF_Number>("Descent", descend);
+  pFontDesc->SetNewFor<CPDF_Number>("StemV", stemV);
   return pFontDesc;
 }
 
@@ -649,19 +651,19 @@
 void CPDF_Document::CreateNewDoc() {
   ASSERT(!m_pRootDict && !m_pInfoDict);
   m_pRootDict = NewIndirect<CPDF_Dictionary>();
-  m_pRootDict->SetNameFor("Type", "Catalog");
+  m_pRootDict->SetNewFor<CPDF_Name>("Type", "Catalog");
 
   CPDF_Dictionary* pPages = NewIndirect<CPDF_Dictionary>();
-  pPages->SetNameFor("Type", "Pages");
-  pPages->SetNumberFor("Count", 0);
-  pPages->SetFor("Kids", new CPDF_Array);
-  m_pRootDict->SetReferenceFor("Pages", this, pPages);
+  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 = NewIndirect<CPDF_Dictionary>();
 }
 
 CPDF_Dictionary* CPDF_Document::CreateNewPage(int iPage) {
   CPDF_Dictionary* pDict = NewIndirect<CPDF_Dictionary>();
-  pDict->SetNameFor("Type", "Page");
+  pDict->SetNewFor<CPDF_Name>("Type", "Page");
   uint32_t dwObjNum = pDict->GetObjNum();
   if (!InsertNewPage(iPage, pDict)) {
     DeleteIndirectObject(dwObjNum);
@@ -688,11 +690,12 @@
       }
       if (bInsert) {
         pKidList->InsertNewAt<CPDF_Reference>(i, this, pPageDict->GetObjNum());
-        pPageDict->SetReferenceFor("Parent", this, pPages->GetObjNum());
+        pPageDict->SetNewFor<CPDF_Reference>("Parent", this,
+                                             pPages->GetObjNum());
       } else {
         pKidList->RemoveAt(i);
       }
-      pPages->SetIntegerFor(
+      pPages->SetNewFor<CPDF_Number>(
           "Count", pPages->GetIntegerFor("Count") + (bInsert ? 1 : -1));
       ResetTraversal();
       break;
@@ -709,8 +712,8 @@
     if (!InsertDeletePDFPage(pKid, nPagesToGo, pPageDict, bInsert, pVisited))
       return false;
 
-    pPages->SetIntegerFor("Count",
-                          pPages->GetIntegerFor("Count") + (bInsert ? 1 : -1));
+    pPages->SetNewFor<CPDF_Number>(
+        "Count", pPages->GetIntegerFor("Count") + (bInsert ? 1 : -1));
     break;
   }
   return true;
@@ -728,13 +731,11 @@
 
   if (iPage == nPages) {
     CPDF_Array* pPagesList = pPages->GetArrayFor("Kids");
-    if (!pPagesList) {
-      pPagesList = new CPDF_Array;
-      pPages->SetFor("Kids", pPagesList);
-    }
+    if (!pPagesList)
+      pPagesList = pPages->SetNewFor<CPDF_Array>("Kids");
     pPagesList->AddNew<CPDF_Reference>(this, pPageDict->GetObjNum());
-    pPages->SetIntegerFor("Count", nPages + 1);
-    pPageDict->SetReferenceFor("Parent", this, pPages->GetObjNum());
+    pPages->SetNewFor<CPDF_Number>("Count", nPages + 1);
+    pPageDict->SetNewFor<CPDF_Reference>("Parent", this, pPages->GetObjNum());
     ResetTraversal();
   } else {
     std::set<CPDF_Dictionary*> stack = {pPages};
@@ -780,9 +781,9 @@
     return i;
 
   CPDF_Dictionary* pEncodingDict = NewIndirect<CPDF_Dictionary>();
-  pEncodingDict->SetNameFor("BaseEncoding", "WinAnsiEncoding");
+  pEncodingDict->SetNewFor<CPDF_Name>("BaseEncoding", "WinAnsiEncoding");
 
-  CPDF_Array* pArray = new CPDF_Array;
+  CPDF_Array* pArray = pEncodingDict->SetNewFor<CPDF_Array>("Differences");
   pArray->AddNew<CPDF_Number>(128);
 
   const uint16_t* pUnicodes = g_FX_CharsetUnicodes[i].m_pUnicodes;
@@ -790,8 +791,8 @@
     CFX_ByteString name = PDF_AdobeNameFromUnicode(pUnicodes[j]);
     pArray->AddNew<CPDF_Name>(name.IsEmpty() ? ".notdef" : name);
   }
-  pEncodingDict->SetFor("Differences", pArray);
-  pBaseDict->SetReferenceFor("Encoding", this, pEncodingDict);
+  pBaseDict->SetNewFor<CPDF_Reference>("Encoding", this,
+                                       pEncodingDict->GetObjNum());
   return i;
 }
 
@@ -805,7 +806,7 @@
   CFX_ByteString cmap;
   CFX_ByteString ordering;
   int supplement = 0;
-  CPDF_Array* pWidthArray = new CPDF_Array;
+  CPDF_Array* pWidthArray = pFontDict->SetNewFor<CPDF_Array>("W");
   switch (charset) {
     case FXFONT_CHINESEBIG5_CHARSET:
       cmap = bVert ? "ETenms-B5-V" : "ETenms-B5-H";
@@ -844,20 +845,20 @@
       Insert(0x7e, 0x7e, pWidthArray);
       break;
   }
-  pBaseDict->SetNameFor("Subtype", "Type0");
-  pBaseDict->SetNameFor("BaseFont", basefont);
-  pBaseDict->SetNameFor("Encoding", cmap);
-  pFontDict->SetFor("W", pWidthArray);
-  pFontDict->SetNameFor("Type", "Font");
-  pFontDict->SetNameFor("Subtype", "CIDFontType2");
-  pFontDict->SetNameFor("BaseFont", basefont);
-  CPDF_Dictionary* pCIDSysInfo = new CPDF_Dictionary(GetByteStringPool());
-  pCIDSysInfo->SetStringFor("Registry", "Adobe");
-  pCIDSysInfo->SetStringFor("Ordering", ordering);
-  pCIDSysInfo->SetIntegerFor("Supplement", supplement);
-  pFontDict->SetFor("CIDSystemInfo", pCIDSysInfo);
-  CPDF_Array* pArray = new CPDF_Array;
-  pBaseDict->SetFor("DescendantFonts", pArray);
+  pBaseDict->SetNewFor<CPDF_Name>("Subtype", "Type0");
+  pBaseDict->SetNewFor<CPDF_Name>("BaseFont", basefont);
+  pBaseDict->SetNewFor<CPDF_Name>("Encoding", cmap);
+  pFontDict->SetNewFor<CPDF_Name>("Type", "Font");
+  pFontDict->SetNewFor<CPDF_Name>("Subtype", "CIDFontType2");
+  pFontDict->SetNewFor<CPDF_Name>("BaseFont", basefont);
+
+  CPDF_Dictionary* pCIDSysInfo =
+      pFontDict->SetNewFor<CPDF_Dictionary>("CIDSystemInfo");
+  pCIDSysInfo->SetNewFor<CPDF_String>("Registry", "Adobe", false);
+  pCIDSysInfo->SetNewFor<CPDF_String>("Ordering", ordering, false);
+  pCIDSysInfo->SetNewFor<CPDF_Number>("Supplement", supplement);
+
+  CPDF_Array* pArray = pBaseDict->SetNewFor<CPDF_Array>("DescendantFonts");
   pArray->AddNew<CPDF_Reference>(this, pFontDict->GetObjNum());
   return pFontDict;
 }
@@ -877,7 +878,7 @@
                      false, false, charset == FXFONT_SYMBOL_CHARSET);
 
   CPDF_Dictionary* pBaseDict = NewIndirect<CPDF_Dictionary>();
-  pBaseDict->SetNameFor("Type", "Font");
+  pBaseDict->SetNewFor<CPDF_Name>("Type", "Font");
   std::unique_ptr<CFX_UnicodeEncoding> pEncoding(
       new CFX_UnicodeEncoding(pFont));
   CPDF_Dictionary* pFontDict = pBaseDict;
@@ -890,7 +891,7 @@
     }
     if (charset == FXFONT_ANSI_CHARSET || charset == FXFONT_DEFAULT_CHARSET ||
         charset == FXFONT_SYMBOL_CHARSET) {
-      pBaseDict->SetNameFor("Encoding", "WinAnsiEncoding");
+      pBaseDict->SetNewFor<CPDF_Name>("Encoding", "WinAnsiEncoding");
       for (int charcode = 128; charcode <= 255; charcode++) {
         int glyph_index = pEncoding->GlyphFromCharCode(charcode);
         int char_width = pFont->GetGlyphWidth(glyph_index);
@@ -944,7 +945,8 @@
   CPDF_Dictionary* pFontDesc = ToDictionary(AddIndirectObject(
       CalculateFontDesc(this, basefont, flags, italicangle, pFont->GetAscent(),
                         pFont->GetDescent(), pBBox, nStemV)));
-  pFontDict->SetReferenceFor("FontDescriptor", this, pFontDesc);
+  pFontDict->SetNewFor<CPDF_Reference>("FontDescriptor", this,
+                                       pFontDesc->GetObjNum());
   return LoadFont(pBaseDict);
 }
 
@@ -1007,13 +1009,13 @@
   FX_Free(tm_buf);
   basefont.Replace(" ", "");
   CPDF_Dictionary* pBaseDict = NewIndirect<CPDF_Dictionary>();
-  pBaseDict->SetNameFor("Type", "Font");
+  pBaseDict->SetNewFor<CPDF_Name>("Type", "Font");
   CPDF_Dictionary* pFontDict = pBaseDict;
   if (!bCJK) {
     if (pLogFont->lfCharSet == FXFONT_ANSI_CHARSET ||
         pLogFont->lfCharSet == FXFONT_DEFAULT_CHARSET ||
         pLogFont->lfCharSet == FXFONT_SYMBOL_CHARSET) {
-      pBaseDict->SetNameFor("Encoding", "WinAnsiEncoding");
+      pBaseDict->SetNewFor<CPDF_Name>("Encoding", "WinAnsiEncoding");
     } else {
       CalculateEncodingDict(pLogFont->lfCharSet, pBaseDict);
     }
@@ -1037,9 +1039,10 @@
   std::unique_ptr<CPDF_Dictionary> pFontDesc =
       CalculateFontDesc(this, basefont, flags, italicangle, ascend, descend,
                         pBBox, pLogFont->lfWeight / 5);
-  pFontDesc->SetIntegerFor("CapHeight", capheight);
-  pFontDict->SetReferenceFor("FontDescriptor", this,
-                             AddIndirectObject(std::move(pFontDesc)));
+  pFontDesc->SetNewFor<CPDF_Number>("CapHeight", capheight);
+  pFontDict->SetNewFor<CPDF_Reference>(
+      "FontDescriptor", this,
+      AddIndirectObject(std::move(pFontDesc))->GetObjNum());
   hFont = SelectObject(hDC, hFont);
   DeleteObject(hFont);
   DeleteDC(hDC);
diff --git a/core/fpdfapi/parser/cpdf_document_unittest.cpp b/core/fpdfapi/parser/cpdf_document_unittest.cpp
index df90875..94cef55 100644
--- a/core/fpdfapi/parser/cpdf_document_unittest.cpp
+++ b/core/fpdfapi/parser/cpdf_document_unittest.cpp
@@ -5,13 +5,17 @@
 #include "core/fpdfapi/parser/cpdf_document.h"
 
 #include <memory>
+#include <utility>
 
 #include "core/fpdfapi/cpdf_modulemgr.h"
 #include "core/fpdfapi/parser/cpdf_array.h"
+#include "core/fpdfapi/parser/cpdf_boolean.h"
 #include "core/fpdfapi/parser/cpdf_dictionary.h"
 #include "core/fpdfapi/parser/cpdf_linearized_header.h"
+#include "core/fpdfapi/parser/cpdf_number.h"
 #include "core/fpdfapi/parser/cpdf_parser.h"
 #include "core/fpdfapi/parser/cpdf_reference.h"
+#include "core/fpdfapi/parser/cpdf_string.h"
 #include "core/fxcrt/fx_memory.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/base/ptr_util.h"
@@ -23,18 +27,20 @@
                                     int count) {
   CPDF_Array* pUnowned = pDoc->AddIndirectObject(std::move(kids))->AsArray();
   CPDF_Dictionary* pageNode = pDoc->NewIndirect<CPDF_Dictionary>();
-  pageNode->SetStringFor("Type", "Pages");
-  pageNode->SetReferenceFor("Kids", pDoc, pUnowned);
-  pageNode->SetIntegerFor("Count", count);
-  for (size_t i = 0; i < pUnowned->GetCount(); i++)
-    pUnowned->GetDictAt(i)->SetReferenceFor("Parent", pDoc, pageNode);
+  pageNode->SetNewFor<CPDF_String>("Type", "Pages", false);
+  pageNode->SetNewFor<CPDF_Reference>("Kids", pDoc, pUnowned->GetObjNum());
+  pageNode->SetNewFor<CPDF_Number>("Count", count);
+  for (size_t i = 0; i < pUnowned->GetCount(); i++) {
+    pUnowned->GetDictAt(i)->SetNewFor<CPDF_Reference>("Parent", pDoc,
+                                                      pageNode->GetObjNum());
+  }
   return pageNode;
 }
 
 std::unique_ptr<CPDF_Dictionary> CreateNumberedPage(size_t number) {
   auto page = pdfium::MakeUnique<CPDF_Dictionary>();
-  page->SetStringFor("Type", "Page");
-  page->SetIntegerFor("PageNumbering", number);
+  page->SetNewFor<CPDF_String>("Type", "Page", false);
+  page->SetNewFor<CPDF_Number>("PageNumbering", static_cast<int>(number));
   return page;
 }
 
@@ -79,7 +85,8 @@
         CreatePageTreeNode(std::move(allPages), this, 7);
 
     m_pOwnedRootDict = pdfium::MakeUnique<CPDF_Dictionary>();
-    m_pOwnedRootDict->SetReferenceFor("Pages", this, pagesDict);
+    m_pOwnedRootDict->SetNewFor<CPDF_Reference>("Pages", this,
+                                                pagesDict->GetObjNum());
     m_pRootDict = m_pOwnedRootDict.get();
     m_PageList.SetSize(7);
   }
@@ -102,7 +109,8 @@
     CPDF_Dictionary* pagesDict =
         CreatePageTreeNode(std::move(allPages), this, 3);
     m_pOwnedRootDict.reset(new CPDF_Dictionary());
-    m_pOwnedRootDict->SetReferenceFor("Pages", this, pagesDict->GetObjNum());
+    m_pOwnedRootDict->SetNewFor<CPDF_Reference>("Pages", this,
+                                                pagesDict->GetObjNum());
     m_pRootDict = m_pOwnedRootDict.get();
     m_PageList.SetSize(3);
   }
@@ -194,9 +202,9 @@
   // (case, when hint table is used to page check in CPDF_DataAvail).
   CPDF_Document document(pdfium::MakeUnique<CPDF_Parser>());
   auto dict = pdfium::MakeUnique<CPDF_Dictionary>();
-  dict->SetBooleanFor("Linearized", true);
+  dict->SetNewFor<CPDF_Boolean>("Linearized", true);
   const int page_count = 100;
-  dict->SetIntegerFor("N", page_count);
+  dict->SetNewFor<CPDF_Number>("N", page_count);
   TestLinearized linearized(dict.get());
   document.LoadLinearizedDoc(&linearized);
   ASSERT_EQ(page_count, document.GetPageCount());
diff --git a/core/fpdfapi/parser/cpdf_object_unittest.cpp b/core/fpdfapi/parser/cpdf_object_unittest.cpp
index 2de6256..8664593 100644
--- a/core/fpdfapi/parser/cpdf_object_unittest.cpp
+++ b/core/fpdfapi/parser/cpdf_object_unittest.cpp
@@ -14,6 +14,7 @@
 
 #include <memory>
 #include <string>
+#include <utility>
 #include <vector>
 
 #include "core/fpdfapi/parser/cpdf_indirect_object_holder.h"
@@ -53,8 +54,8 @@
     CPDF_Number* number_int_obj = new CPDF_Number(1245);
     CPDF_Number* number_float_obj = new CPDF_Number(9.00345f);
     // String objects.
-    CPDF_String* str_reg_obj = new CPDF_String(L"A simple test");
-    CPDF_String* str_spec_obj = new CPDF_String(L"\t\n");
+    CPDF_String* str_reg_obj = new CPDF_String(nullptr, L"A simple test");
+    CPDF_String* str_spec_obj = new CPDF_String(nullptr, L"\t\n");
     // Name object.
     CPDF_Name* name_obj = new CPDF_Name(nullptr, "space");
     // Array object.
@@ -63,16 +64,16 @@
     m_ArrayObj->InsertNewAt<CPDF_Name>(1, "address");
     // Dictionary object.
     m_DictObj = new CPDF_Dictionary();
-    m_DictObj->SetFor("bool", new CPDF_Boolean(false));
-    m_DictObj->SetFor("num", new CPDF_Number(0.23f));
+    m_DictObj->SetNewFor<CPDF_Boolean>("bool", false);
+    m_DictObj->SetNewFor<CPDF_Number>("num", 0.23f);
     // Stream object.
     const char content[] = "abcdefghijklmnopqrstuvwxyz";
     size_t buf_len = FX_ArraySize(content);
     uint8_t* buf = reinterpret_cast<uint8_t*>(malloc(buf_len));
     memcpy(buf, content, buf_len);
     m_StreamDictObj = new CPDF_Dictionary();
-    m_StreamDictObj->SetFor("key1", new CPDF_String(L" test dict"));
-    m_StreamDictObj->SetFor("key2", new CPDF_Number(-1));
+    m_StreamDictObj->SetNewFor<CPDF_String>("key1", L" test dict");
+    m_StreamDictObj->SetNewFor<CPDF_Number>("key2", -1);
     CPDF_Stream* stream_obj = new CPDF_Stream(buf, buf_len, m_StreamDictObj);
     // Null Object.
     CPDF_Null* null_obj = new CPDF_Null;
@@ -136,7 +137,7 @@
           return false;
         for (CPDF_Dictionary::const_iterator it = dict1->begin();
              it != dict1->end(); ++it) {
-          if (!Equal(it->second, dict2->GetObjectFor(it->first)))
+          if (!Equal(it->second.get(), dict2->GetObjectFor(it->first)))
             return false;
         }
         return true;
@@ -555,7 +556,7 @@
         char buf[33];
         key.append(FXSYS_itoa(j, buf, 10));
         int value = j + 200;
-        vals[i]->SetFor(key.c_str(), new CPDF_Number(value));
+        vals[i]->SetNewFor<CPDF_Number>(key.c_str(), value);
       }
     }
     for (size_t i = 0; i < 3; ++i) {
@@ -581,7 +582,7 @@
         char buf[33];
         key.append(FXSYS_itoa(j, buf, 10));
         int value = j + 200;
-        vals[i]->SetFor(key.c_str(), new CPDF_Number(value));
+        vals[i]->SetNewFor<CPDF_Number>(key.c_str(), value);
       }
       uint8_t content[] = "content: this is a stream";
       size_t data_size = FX_ArraySize(content);
@@ -620,12 +621,12 @@
     arr_val->AddNew<CPDF_Number>(2);
 
     CPDF_Dictionary* dict_val = arr->InsertNewAt<CPDF_Dictionary>(12);
-    dict_val->SetFor("key1", new CPDF_String(nullptr, "Linda", false));
-    dict_val->SetFor("key2", new CPDF_String(nullptr, "Zoe", false));
+    dict_val->SetNewFor<CPDF_String>("key1", "Linda", false);
+    dict_val->SetNewFor<CPDF_String>("key2", "Zoe", false);
 
     CPDF_Dictionary* stream_dict = new CPDF_Dictionary();
-    stream_dict->SetFor("key1", new CPDF_String(nullptr, "John", false));
-    stream_dict->SetFor("key2", new CPDF_String(nullptr, "King", false));
+    stream_dict->SetNewFor<CPDF_String>("key1", "John", false);
+    stream_dict->SetNewFor<CPDF_String>("key2", "King", false);
     uint8_t data[] = "A stream for test";
     // The data buffer will be owned by stream object, so it needs to be
     // dynamically allocated.
@@ -778,7 +779,7 @@
 TEST(PDFDictionaryTest, CloneDirectObject) {
   CPDF_IndirectObjectHolder objects_holder;
   std::unique_ptr<CPDF_Dictionary> dict(new CPDF_Dictionary());
-  dict->SetReferenceFor("foo", &objects_holder, 1234);
+  dict->SetNewFor<CPDF_Reference>("foo", &objects_holder, 1234);
   ASSERT_EQ(1U, dict->GetCount());
   CPDF_Object* obj = dict->GetObjectFor("foo");
   ASSERT_TRUE(obj);
@@ -797,10 +798,12 @@
 
 TEST(PDFObjectTest, CloneCheckLoop) {
   {
-    // Create a dictionary/array pair with a reference loop.
+    // Create a dictionary/array pair with a reference loop. It takes
+    // some work to do this nowadays, in particular we need the
+    // anti-pattern pdfium::WrapUnique(arr.get()).
     auto arr_obj = pdfium::MakeUnique<CPDF_Array>();
     CPDF_Dictionary* dict_obj = arr_obj->InsertNewAt<CPDF_Dictionary>(0);
-    dict_obj->SetFor("arr", arr_obj.get());
+    dict_obj->SetFor("arr", pdfium::WrapUnique(arr_obj.get()));
     // Clone this object to see whether stack overflow will be triggered.
     std::unique_ptr<CPDF_Array> cloned_array = ToArray(arr_obj->Clone());
     // Cloned object should be the same as the original.
@@ -814,11 +817,9 @@
   }
   {
     // Create a dictionary/stream pair with a reference loop.
-    CPDF_Dictionary* dict_obj = new CPDF_Dictionary();
-    std::unique_ptr<CPDF_Stream> stream_obj(
-        new CPDF_Stream(nullptr, 0, dict_obj));
-    dict_obj->SetFor("stream", stream_obj.get());
-
+    auto dict_obj = pdfium::MakeUnique<CPDF_Dictionary>();
+    CPDF_Stream* stream_obj =
+        dict_obj->SetNewFor<CPDF_Stream>("stream", nullptr, 0, dict_obj.get());
     // Clone this object to see whether stack overflow will be triggered.
     std::unique_ptr<CPDF_Stream> cloned_stream = ToStream(stream_obj->Clone());
     // Cloned object should be the same as the original.
@@ -837,7 +838,7 @@
     arr_obj->InsertNewAt<CPDF_Reference>(0, &objects_holder,
                                          dict_obj->GetObjNum());
     CPDF_Object* elem0 = arr_obj->GetObjectAt(0);
-    dict_obj->SetFor("arr", arr_obj.release());
+    dict_obj->SetFor("arr", std::move(arr_obj));
     EXPECT_EQ(1u, dict_obj->GetObjNum());
     ASSERT_TRUE(elem0);
     ASSERT_TRUE(elem0->IsReference());
@@ -861,8 +862,7 @@
 TEST(PDFDictionaryTest, ConvertIndirect) {
   CPDF_IndirectObjectHolder objects_holder;
   std::unique_ptr<CPDF_Dictionary> dict(new CPDF_Dictionary);
-  CPDF_Object* pObj = new CPDF_Number(42);
-  dict->SetFor("clams", pObj);
+  CPDF_Object* pObj = dict->SetNewFor<CPDF_Number>("clams", 42);
   dict->ConvertToIndirectObjectFor("clams", &objects_holder);
   CPDF_Object* pRef = dict->GetObjectFor("clams");
   CPDF_Object* pNum = dict->GetDirectObjectFor("clams");
diff --git a/core/fpdfapi/parser/cpdf_parser.cpp b/core/fpdfapi/parser/cpdf_parser.cpp
index c43614f..5354417 100644
--- a/core/fpdfapi/parser/cpdf_parser.cpp
+++ b/core/fpdfapi/parser/cpdf_parser.cpp
@@ -6,6 +6,8 @@
 
 #include "core/fpdfapi/parser/cpdf_parser.h"
 
+#include <algorithm>
+#include <utility>
 #include <vector>
 
 #include "core/fpdfapi/parser/cpdf_array.h"
@@ -802,16 +804,15 @@
                         auto it = pTrailer->begin();
                         while (it != pTrailer->end()) {
                           const CFX_ByteString& key = it->first;
-                          CPDF_Object* pElement = it->second;
+                          CPDF_Object* pElement = it->second.get();
                           ++it;
                           uint32_t dwObjNum =
                               pElement ? pElement->GetObjNum() : 0;
                           if (dwObjNum) {
-                            m_pTrailer->SetReferenceFor(key, m_pDocument,
-                                                        dwObjNum);
+                            m_pTrailer->SetNewFor<CPDF_Reference>(
+                                key, m_pDocument, dwObjNum);
                           } else {
-                            m_pTrailer->SetFor(key,
-                                               pElement->Clone().release());
+                            m_pTrailer->SetFor(key, pElement->Clone());
                           }
                         }
                       }
@@ -1075,7 +1076,7 @@
 
   if (CPDF_Reference* pRef = pID->AsReference()) {
     pID = ParseIndirectObject(nullptr, pRef->GetRefObjNum()).release();
-    m_pTrailer->SetFor("ID", pID);
+    m_pTrailer->SetFor("ID", pdfium::WrapUnique(pID));
   }
   return ToArray(pID);
 }
diff --git a/core/fpdfapi/parser/cpdf_security_handler.cpp b/core/fpdfapi/parser/cpdf_security_handler.cpp
index bebda4d..f6f4aef 100644
--- a/core/fpdfapi/parser/cpdf_security_handler.cpp
+++ b/core/fpdfapi/parser/cpdf_security_handler.cpp
@@ -8,12 +8,17 @@
 
 #include <time.h>
 
+#include <algorithm>
+#include <utility>
+#include <vector>
+
 #include "core/fdrm/crypto/fx_crypt.h"
 #include "core/fpdfapi/parser/cpdf_array.h"
 #include "core/fpdfapi/parser/cpdf_crypto_handler.h"
 #include "core/fpdfapi/parser/cpdf_dictionary.h"
 #include "core/fpdfapi/parser/cpdf_object.h"
 #include "core/fpdfapi/parser/cpdf_parser.h"
+#include "core/fpdfapi/parser/cpdf_string.h"
 
 namespace {
 
@@ -570,7 +575,8 @@
         CRYPT_ArcFourCryptBlock(passcode, 32, tempkey, key_len);
       }
     }
-    pEncryptDict->SetStringFor("O", CFX_ByteString(passcode, 32));
+    pEncryptDict->SetNewFor<CPDF_String>("O", CFX_ByteString(passcode, 32),
+                                         false);
   }
   CalcEncryptKey(m_pEncryptDict, (uint8_t*)user_pass, user_size, m_EncryptKey,
                  key_len, false, pIdArray);
@@ -578,7 +584,8 @@
     uint8_t tempbuf[32];
     FXSYS_memcpy(tempbuf, defpasscode, 32);
     CRYPT_ArcFourCryptBlock(tempbuf, 32, m_EncryptKey, key_len);
-    pEncryptDict->SetStringFor("U", CFX_ByteString(tempbuf, 32));
+    pEncryptDict->SetNewFor<CPDF_String>("U", CFX_ByteString(tempbuf, 32),
+                                         false);
   } else {
     uint8_t md5[100];
     CRYPT_MD5Start(md5);
@@ -598,7 +605,8 @@
       CRYPT_ArcFourCryptBlock(digest, 16, tempkey, key_len);
     }
     CRYPT_MD5Generate(digest, 16, digest + 16);
-    pEncryptDict->SetStringFor("U", CFX_ByteString(digest, 32));
+    pEncryptDict->SetNewFor<CPDF_String>("U", CFX_ByteString(digest, 32),
+                                         false);
   }
 }
 void CPDF_SecurityHandler::OnCreate(CPDF_Dictionary* pEncryptDict,
@@ -645,7 +653,8 @@
     CRYPT_SHA256Finish(sha, digest1);
   }
   FXSYS_memcpy(digest1 + 32, digest, 16);
-  pEncryptDict->SetStringFor(bOwner ? "O" : "U", CFX_ByteString(digest1, 48));
+  pEncryptDict->SetNewFor<CPDF_String>(bOwner ? "O" : "U",
+                                       CFX_ByteString(digest1, 48), false);
   if (m_Revision >= 6) {
     Revision6_Hash(password, size, digest + 8,
                    bOwner ? ukey.raw_str() : nullptr, digest1);
@@ -665,8 +674,10 @@
   CRYPT_AESSetIV(aes, iv);
   CRYPT_AESEncrypt(aes, digest1, key, 32);
   FX_Free(aes);
-  pEncryptDict->SetStringFor(bOwner ? "OE" : "UE", CFX_ByteString(digest1, 32));
+  pEncryptDict->SetNewFor<CPDF_String>(bOwner ? "OE" : "UE",
+                                       CFX_ByteString(digest1, 32), false);
 }
+
 void CPDF_SecurityHandler::AES256_SetPerms(CPDF_Dictionary* pEncryptDict,
                                            uint32_t permissions,
                                            bool bEncryptMetadata,
@@ -691,5 +702,6 @@
   CRYPT_AESSetIV(aes, iv);
   CRYPT_AESEncrypt(aes, buf1, buf, 16);
   FX_Free(aes);
-  pEncryptDict->SetStringFor("Perms", CFX_ByteString(buf1, 16));
+  pEncryptDict->SetNewFor<CPDF_String>("Perms", CFX_ByteString(buf1, 16),
+                                       false);
 }
diff --git a/core/fpdfapi/parser/cpdf_stream.cpp b/core/fpdfapi/parser/cpdf_stream.cpp
index 64261b1..fd7f08f 100644
--- a/core/fpdfapi/parser/cpdf_stream.cpp
+++ b/core/fpdfapi/parser/cpdf_stream.cpp
@@ -7,6 +7,7 @@
 #include "core/fpdfapi/parser/cpdf_stream.h"
 
 #include "core/fpdfapi/parser/cpdf_dictionary.h"
+#include "core/fpdfapi/parser/cpdf_number.h"
 #include "core/fpdfapi/parser/cpdf_stream_acc.h"
 #include "core/fpdfapi/parser/fpdf_parser_decode.h"
 #include "third_party/base/numerics/safe_conversions.h"
@@ -54,7 +55,7 @@
     FXSYS_memcpy(m_pDataBuf.get(), pData, size);
   m_dwSize = size;
   if (m_pDict)
-    m_pDict->SetIntegerFor("Length", m_dwSize);
+    m_pDict->SetNewFor<CPDF_Number>("Length", static_cast<int>(m_dwSize));
 }
 
 void CPDF_Stream::InitStreamFromFile(IFX_SeekableReadStream* pFile,
@@ -65,7 +66,7 @@
   m_pFile = pFile;
   m_dwSize = pdfium::base::checked_cast<uint32_t>(pFile->GetSize());
   if (m_pDict)
-    m_pDict->SetIntegerFor("Length", m_dwSize);
+    m_pDict->SetNewFor<CPDF_Number>("Length", static_cast<int>(m_dwSize));
 }
 
 std::unique_ptr<CPDF_Object> CPDF_Stream::Clone() const {
@@ -96,7 +97,7 @@
   m_dwSize = size;
   if (!m_pDict)
     m_pDict.reset(new CPDF_Dictionary());
-  m_pDict->SetIntegerFor("Length", size);
+  m_pDict->SetNewFor<CPDF_Number>("Length", static_cast<int>(size));
   m_pDict->RemoveFor("Filter");
   m_pDict->RemoveFor("DecodeParms");
 }
diff --git a/core/fpdfapi/parser/cpdf_string.cpp b/core/fpdfapi/parser/cpdf_string.cpp
index fd4ff04..06bae54 100644
--- a/core/fpdfapi/parser/cpdf_string.cpp
+++ b/core/fpdfapi/parser/cpdf_string.cpp
@@ -6,6 +6,8 @@
 
 #include "core/fpdfapi/parser/cpdf_string.h"
 
+#include <utility>
+
 #include "core/fpdfapi/parser/fpdf_parser_decode.h"
 #include "third_party/base/ptr_util.h"
 
@@ -19,8 +21,11 @@
     m_String = pPool->Intern(m_String);
 }
 
-CPDF_String::CPDF_String(const CFX_WideString& str) : m_bHex(false) {
-  m_String = PDF_EncodeText(str);
+CPDF_String::CPDF_String(CFX_WeakPtr<CFX_ByteStringPool> pPool,
+                         const CFX_WideString& str)
+    : m_String(PDF_EncodeText(str)), m_bHex(false) {
+  if (pPool)
+    m_String = pPool->Intern(m_String);
 }
 
 CPDF_String::~CPDF_String() {}
diff --git a/core/fpdfapi/parser/cpdf_string.h b/core/fpdfapi/parser/cpdf_string.h
index 616e3b5..6698d8c 100644
--- a/core/fpdfapi/parser/cpdf_string.h
+++ b/core/fpdfapi/parser/cpdf_string.h
@@ -7,6 +7,8 @@
 #ifndef CORE_FPDFAPI_PARSER_CPDF_STRING_H_
 #define CORE_FPDFAPI_PARSER_CPDF_STRING_H_
 
+#include <memory>
+
 #include "core/fpdfapi/parser/cpdf_object.h"
 #include "core/fxcrt/cfx_string_pool_template.h"
 #include "core/fxcrt/cfx_weak_ptr.h"
@@ -19,7 +21,7 @@
   CPDF_String(CFX_WeakPtr<CFX_ByteStringPool> pPool,
               const CFX_ByteString& str,
               bool bHex);
-  explicit CPDF_String(const CFX_WideString& str);
+  CPDF_String(CFX_WeakPtr<CFX_ByteStringPool> pPool, const CFX_WideString& str);
   ~CPDF_String() override;
 
   // CPDF_Object:
diff --git a/core/fpdfapi/parser/cpdf_syntax_parser.cpp b/core/fpdfapi/parser/cpdf_syntax_parser.cpp
index 6a38ce8..4a0fd3a 100644
--- a/core/fpdfapi/parser/cpdf_syntax_parser.cpp
+++ b/core/fpdfapi/parser/cpdf_syntax_parser.cpp
@@ -6,6 +6,8 @@
 
 #include "core/fpdfapi/parser/cpdf_syntax_parser.h"
 
+#include <algorithm>
+#include <utility>
 #include <vector>
 
 #include "core/fpdfapi/cpdf_modulemgr.h"
@@ -458,7 +460,7 @@
         continue;
 
       CFX_ByteString keyNoSlash(key.raw_str() + 1, key.GetLength() - 1);
-      pDict->SetFor(keyNoSlash, pObj.release());
+      pDict->SetFor(keyNoSlash, std::move(pObj));
     }
 
     // Only when this is a signature dictionary and has contents, we reset the
@@ -466,8 +468,7 @@
     if (pDict->IsSignatureDict() && dwSignValuePos) {
       CFX_AutoRestorer<FX_FILESIZE> save_pos(&m_Pos);
       m_Pos = dwSignValuePos;
-      pDict->SetFor("Contents",
-                    GetObject(pObjList, objnum, gennum, false).release());
+      pDict->SetFor("Contents", GetObject(pObjList, objnum, gennum, false));
     }
 
     FX_FILESIZE SavedPos = m_Pos;
@@ -576,7 +577,7 @@
 
       if (key.GetLength() > 1) {
         pDict->SetFor(CFX_ByteString(key.c_str() + 1, key.GetLength() - 1),
-                      obj.release());
+                      std::move(obj));
       }
     }
 
@@ -722,7 +723,7 @@
         delete pDict;
         return nullptr;
       }
-      pDict->SetIntegerFor("Length", len);
+      pDict->SetNewFor<CPDF_Number>("Length", static_cast<int>(len));
     }
     m_Pos = streamStartPos;
   }
diff --git a/core/fpdfapi/parser/fpdf_parser_utility.cpp b/core/fpdfapi/parser/fpdf_parser_utility.cpp
index 630754a..ef37d8f 100644
--- a/core/fpdfapi/parser/fpdf_parser_utility.cpp
+++ b/core/fpdfapi/parser/fpdf_parser_utility.cpp
@@ -7,6 +7,7 @@
 #include "core/fpdfapi/parser/fpdf_parser_utility.h"
 
 #include "core/fpdfapi/parser/cpdf_array.h"
+#include "core/fpdfapi/parser/cpdf_boolean.h"
 #include "core/fpdfapi/parser/cpdf_dictionary.h"
 #include "core/fpdfapi/parser/cpdf_number.h"
 #include "core/fpdfapi/parser/cpdf_reference.h"
@@ -193,7 +194,7 @@
       buf << "<<";
       for (const auto& it : *p) {
         const CFX_ByteString& key = it.first;
-        CPDF_Object* pValue = it.second;
+        CPDF_Object* pValue = it.second.get();
         buf << "/" << PDF_NameEncode(key);
         if (pValue && !pValue->IsInline()) {
           buf << " " << pValue->GetObjNum() << " 0 R ";
diff --git a/core/fpdfdoc/cpdf_annot.cpp b/core/fpdfdoc/cpdf_annot.cpp
index a213f51..a7d2101 100644
--- a/core/fpdfdoc/cpdf_annot.cpp
+++ b/core/fpdfdoc/cpdf_annot.cpp
@@ -9,6 +9,7 @@
 #include "core/fpdfapi/page/cpdf_form.h"
 #include "core/fpdfapi/page/cpdf_page.h"
 #include "core/fpdfapi/parser/cpdf_array.h"
+#include "core/fpdfapi/parser/cpdf_boolean.h"
 #include "core/fpdfapi/parser/cpdf_document.h"
 #include "core/fpdfapi/render/cpdf_rendercontext.h"
 #include "core/fpdfapi/render/cpdf_renderoptions.h"
@@ -109,7 +110,7 @@
     result = CPVT_GenerateAP::GenerateUnderlineAP(m_pDocument, m_pAnnotDict);
 
   if (result) {
-    m_pAnnotDict->SetBooleanFor(kPDFiumKey_HasGeneratedAP, result);
+    m_pAnnotDict->SetNewFor<CPDF_Boolean>(kPDFiumKey_HasGeneratedAP, result);
     m_bHasGeneratedAP = result;
   }
 }
diff --git a/core/fpdfdoc/cpdf_annotlist.cpp b/core/fpdfdoc/cpdf_annotlist.cpp
index 91cff45..e68e08a 100644
--- a/core/fpdfdoc/cpdf_annotlist.cpp
+++ b/core/fpdfdoc/cpdf_annotlist.cpp
@@ -11,7 +11,10 @@
 
 #include "core/fpdfapi/page/cpdf_page.h"
 #include "core/fpdfapi/parser/cpdf_document.h"
+#include "core/fpdfapi/parser/cpdf_name.h"
+#include "core/fpdfapi/parser/cpdf_number.h"
 #include "core/fpdfapi/parser/cpdf_reference.h"
+#include "core/fpdfapi/parser/cpdf_string.h"
 #include "core/fpdfapi/render/cpdf_renderoptions.h"
 #include "core/fpdfdoc/cpdf_annot.h"
 #include "core/fpdfdoc/cpdf_interform.h"
@@ -36,10 +39,11 @@
 
   auto pAnnotDict =
       pdfium::MakeUnique<CPDF_Dictionary>(pDocument->GetByteStringPool());
-  pAnnotDict->SetNameFor("Type", "Annot");
-  pAnnotDict->SetNameFor("Subtype", "Popup");
-  pAnnotDict->SetStringFor("T", pParentDict->GetStringFor("T"));
-  pAnnotDict->SetStringFor("Contents", sContents.UTF8Encode());
+  pAnnotDict->SetNewFor<CPDF_Name>("Type", "Annot");
+  pAnnotDict->SetNewFor<CPDF_Name>("Subtype", "Popup");
+  pAnnotDict->SetNewFor<CPDF_String>("T", pParentDict->GetStringFor("T"),
+                                     false);
+  pAnnotDict->SetNewFor<CPDF_String>("Contents", sContents.UTF8Encode(), false);
 
   CFX_FloatRect rect = pParentDict->GetRectFor("Rect");
   rect.Normalize();
@@ -47,7 +51,7 @@
   popupRect.Translate(rect.left, rect.bottom - popupRect.Height());
 
   pAnnotDict->SetRectFor("Rect", popupRect);
-  pAnnotDict->SetIntegerFor("F", 0);
+  pAnnotDict->SetNewFor<CPDF_Number>("F", 0);
 
   auto pPopupAnnot =
       pdfium::MakeUnique<CPDF_Annot>(std::move(pAnnotDict), pDocument);
diff --git a/core/fpdfdoc/cpdf_filespec.cpp b/core/fpdfdoc/cpdf_filespec.cpp
index 46b7f8a..d6a66f7 100644
--- a/core/fpdfdoc/cpdf_filespec.cpp
+++ b/core/fpdfdoc/cpdf_filespec.cpp
@@ -7,7 +7,9 @@
 #include "core/fpdfdoc/cpdf_filespec.h"
 
 #include "core/fpdfapi/parser/cpdf_dictionary.h"
+#include "core/fpdfapi/parser/cpdf_name.h"
 #include "core/fpdfapi/parser/cpdf_object.h"
+#include "core/fpdfapi/parser/cpdf_string.h"
 #include "core/fpdfapi/parser/fpdf_parser_decode.h"
 #include "core/fxcrt/fx_system.h"
 
@@ -112,7 +114,7 @@
 
 CPDF_FileSpec::CPDF_FileSpec(const CFX_WeakPtr<CFX_ByteStringPool>& pPool) {
   m_pObj = new CPDF_Dictionary(pPool);
-  m_pObj->AsDictionary()->SetNameFor("Type", "Filespec");
+  m_pObj->AsDictionary()->SetNewFor<CPDF_Name>("Type", "Filespec");
 }
 
 CFX_WideString CPDF_FileSpec::EncodeFileName(const CFX_WideStringC& filepath) {
@@ -161,7 +163,8 @@
   if (m_pObj->IsString()) {
     m_pObj->SetString(CFX_ByteString::FromUnicode(wsStr));
   } else if (CPDF_Dictionary* pDict = m_pObj->AsDictionary()) {
-    pDict->SetStringFor("F", CFX_ByteString::FromUnicode(wsStr));
-    pDict->SetStringFor("UF", PDF_EncodeText(wsStr));
+    pDict->SetNewFor<CPDF_String>("F", CFX_ByteString::FromUnicode(wsStr),
+                                  false);
+    pDict->SetNewFor<CPDF_String>("UF", PDF_EncodeText(wsStr), false);
   }
 }
diff --git a/core/fpdfdoc/cpdf_filespec_unittest.cpp b/core/fpdfdoc/cpdf_filespec_unittest.cpp
index 4da5019..d164165 100644
--- a/core/fpdfdoc/cpdf_filespec_unittest.cpp
+++ b/core/fpdfdoc/cpdf_filespec_unittest.cpp
@@ -67,7 +67,8 @@
       L"/docs/test.pdf"
 #endif
     };
-    std::unique_ptr<CPDF_Object> str_obj(new CPDF_String(test_data.input));
+    std::unique_ptr<CPDF_Object> str_obj(
+        new CPDF_String(nullptr, test_data.input));
     CPDF_FileSpec file_spec(str_obj.get());
     CFX_WideString file_name;
     EXPECT_TRUE(file_spec.GetFileName(&file_name));
@@ -102,13 +103,13 @@
     CPDF_FileSpec file_spec(dict_obj.get());
     CFX_WideString file_name;
     for (int i = 0; i < 5; ++i) {
-      dict_obj->SetFor(keywords[i], new CPDF_String(test_data[i].input));
+      dict_obj->SetNewFor<CPDF_String>(keywords[i], test_data[i].input);
       EXPECT_TRUE(file_spec.GetFileName(&file_name));
       EXPECT_TRUE(file_name == test_data[i].expected);
     }
 
     // With all the former fields and 'FS' field suggests 'URL' type.
-    dict_obj->SetStringFor("FS", "URL");
+    dict_obj->SetNewFor<CPDF_String>("FS", "URL", false);
     EXPECT_TRUE(file_spec.GetFileName(&file_name));
     // Url string is not decoded.
     EXPECT_TRUE(file_name == test_data[4].input);
@@ -136,7 +137,7 @@
 #endif
   };
   // String object.
-  std::unique_ptr<CPDF_Object> str_obj(new CPDF_String(L"babababa"));
+  std::unique_ptr<CPDF_Object> str_obj(new CPDF_String(nullptr, L"babababa"));
   CPDF_FileSpec file_spec1(str_obj.get());
   file_spec1.SetFileName(test_data.input);
   // Check internal object value.
diff --git a/core/fpdfdoc/cpdf_formcontrol.cpp b/core/fpdfdoc/cpdf_formcontrol.cpp
index b01784b..54edb49 100644
--- a/core/fpdfdoc/cpdf_formcontrol.cpp
+++ b/core/fpdfdoc/cpdf_formcontrol.cpp
@@ -11,6 +11,7 @@
 #include "core/fpdfapi/page/cpdf_form.h"
 #include "core/fpdfapi/parser/cpdf_array.h"
 #include "core/fpdfapi/parser/cpdf_document.h"
+#include "core/fpdfapi/parser/cpdf_name.h"
 #include "core/fpdfapi/parser/cpdf_stream.h"
 #include "core/fpdfapi/parser/fpdf_parser_decode.h"
 #include "core/fpdfapi/render/cpdf_rendercontext.h"
@@ -61,14 +62,14 @@
 
   CFX_ByteString csAS = m_pWidgetDict->GetStringFor("AS", "Off");
   if (csAS != "Off")
-    m_pWidgetDict->SetNameFor("AS", csValue);
+    m_pWidgetDict->SetNewFor<CPDF_Name>("AS", csValue);
 
   CPDF_Dictionary* pAP = m_pWidgetDict->GetDictFor("AP");
   if (!pAP)
     return;
 
   for (const auto& it : *pAP) {
-    CPDF_Object* pObj1 = it.second;
+    CPDF_Object* pObj1 = it.second.get();
     if (!pObj1)
       continue;
 
@@ -80,7 +81,7 @@
     auto subdict_it = pSubDict->begin();
     while (subdict_it != pSubDict->end()) {
       const CFX_ByteString& csKey2 = subdict_it->first;
-      CPDF_Object* pObj2 = subdict_it->second;
+      CPDF_Object* pObj2 = subdict_it->second.get();
       ++subdict_it;
       if (!pObj2)
         continue;
@@ -155,7 +156,7 @@
     csAS = csOn;
   if (csOldAS == csAS)
     return;
-  m_pWidgetDict->SetNameFor("AS", csAS);
+  m_pWidgetDict->SetNewFor<CPDF_Name>("AS", csAS);
 }
 
 void CPDF_FormControl::DrawControl(CFX_RenderDevice* pDevice,
diff --git a/core/fpdfdoc/cpdf_formfield.cpp b/core/fpdfdoc/cpdf_formfield.cpp
index 3a2213f..cc7054d 100644
--- a/core/fpdfdoc/cpdf_formfield.cpp
+++ b/core/fpdfdoc/cpdf_formfield.cpp
@@ -6,11 +6,14 @@
 
 #include "core/fpdfdoc/cpdf_formfield.h"
 
+#include <memory>
 #include <set>
+#include <utility>
 
 #include "core/fpdfapi/parser/cfdf_document.h"
 #include "core/fpdfapi/parser/cpdf_array.h"
 #include "core/fpdfapi/parser/cpdf_document.h"
+#include "core/fpdfapi/parser/cpdf_name.h"
 #include "core/fpdfapi/parser/cpdf_number.h"
 #include "core/fpdfapi/parser/cpdf_simple_parser.h"
 #include "core/fpdfapi/parser/cpdf_string.h"
@@ -223,11 +226,9 @@
         if (!pClone)
           return false;
 
-        m_pDict->SetFor("V", pClone.release());
-        if (pRV) {
-          std::unique_ptr<CPDF_Object> pCloneR = pDV->Clone();
-          m_pDict->SetFor("RV", pCloneR.release());
-        }
+        m_pDict->SetFor("V", std::move(pClone));
+        if (pRV)
+          m_pDict->SetFor("RV", pDV->Clone());
       } else {
         m_pDict->RemoveFor("V");
         m_pDict->RemoveFor("RV");
@@ -361,15 +362,16 @@
       if (bNotify && !NotifyBeforeValueChange(csValue))
         return false;
 
+      CFX_ByteString key(bDefault ? "DV" : "V");
       int iIndex = FindOptionValue(csValue);
       if (iIndex < 0) {
         CFX_ByteString bsEncodeText = PDF_EncodeText(csValue);
-        m_pDict->SetStringFor(bDefault ? "DV" : "V", bsEncodeText);
+        m_pDict->SetNewFor<CPDF_String>(key, bsEncodeText, false);
         if (m_Type == RichText && !bDefault)
-          m_pDict->SetStringFor("RV", bsEncodeText);
+          m_pDict->SetNewFor<CPDF_String>("RV", bsEncodeText, false);
         m_pDict->RemoveFor("I");
       } else {
-        m_pDict->SetStringFor(bDefault ? "DV" : "V", PDF_EncodeText(csValue));
+        m_pDict->SetNewFor<CPDF_String>(key, PDF_EncodeText(csValue), false);
         if (!bDefault) {
           ClearSelection();
           SetItemSelection(iIndex, true);
@@ -549,22 +551,20 @@
     if (GetType() == ListBox) {
       SelectOption(index, true);
       if (!(m_Flags & kFormListMultiSelect)) {
-        m_pDict->SetStringFor("V", PDF_EncodeText(opt_value));
+        m_pDict->SetNewFor<CPDF_String>("V", PDF_EncodeText(opt_value), false);
       } else {
-        CPDF_Array* pArray = new CPDF_Array;
+        CPDF_Array* pArray = m_pDict->SetNewFor<CPDF_Array>("V");
         for (int i = 0; i < CountOptions(); i++) {
           if (i == index || IsItemSelected(i)) {
             opt_value = GetOptionValue(i);
             pArray->AddNew<CPDF_String>(PDF_EncodeText(opt_value), false);
           }
         }
-        m_pDict->SetFor("V", pArray);
       }
     } else {
-      m_pDict->SetStringFor("V", PDF_EncodeText(opt_value));
-      CPDF_Array* pI = new CPDF_Array;
+      m_pDict->SetNewFor<CPDF_String>("V", PDF_EncodeText(opt_value), false);
+      CPDF_Array* pI = m_pDict->SetNewFor<CPDF_Array>("I");
       pI->AddNew<CPDF_Number>(index);
-      m_pDict->SetFor("I", pI);
     }
   } else {
     CPDF_Object* pValue = FPDF_GetFieldAttr(m_pDict, "V");
@@ -583,7 +583,7 @@
             }
           }
           if (pArray->GetCount() > 0)
-            m_pDict->SetFor("V", pArray.release());  // std::move someday
+            m_pDict->SetFor("V", std::move(pArray));
         }
       } else {
         m_pDict->RemoveFor("V");
@@ -675,12 +675,9 @@
 
   CFX_ByteString csStr =
       PDF_EncodeText(csOptLabel.c_str(), csOptLabel.GetLength());
-  CPDF_Object* pValue = FPDF_GetFieldAttr(m_pDict, "Opt");
-  CPDF_Array* pOpt = ToArray(pValue);
-  if (!pOpt) {
-    pOpt = new CPDF_Array;
-    m_pDict->SetFor("Opt", pOpt);
-  }
+  CPDF_Array* pOpt = ToArray(FPDF_GetFieldAttr(m_pDict, "Opt"));
+  if (!pOpt)
+    pOpt = m_pDict->SetNewFor<CPDF_Array>("Opt");
 
   int iCount = pdfium::base::checked_cast<int>(pOpt->GetCount());
   if (index >= iCount) {
@@ -755,19 +752,19 @@
   CPDF_Object* pOpt = FPDF_GetFieldAttr(m_pDict, "Opt");
   if (!ToArray(pOpt)) {
     if (bChecked) {
-      m_pDict->SetNameFor("V", csBExport);
+      m_pDict->SetNewFor<CPDF_Name>("V", csBExport);
     } else {
       CFX_ByteString csV;
       CPDF_Object* pV = FPDF_GetFieldAttr(m_pDict, "V");
       if (pV)
         csV = pV->GetString();
       if (csV == csBExport)
-        m_pDict->SetNameFor("V", "Off");
+        m_pDict->SetNewFor<CPDF_Name>("V", "Off");
     }
   } else if (bChecked) {
     CFX_ByteString csIndex;
     csIndex.Format("%d", iControlIndex);
-    m_pDict->SetNameFor("V", csIndex);
+    m_pDict->SetNewFor<CPDF_Name>("V", csIndex);
   }
   if (bNotify && m_pForm->m_pFormNotify)
     m_pForm->m_pFormNotify->AfterCheckedStatusChange(this);
@@ -848,8 +845,7 @@
     if (!bSelected)
       return true;
 
-    pArray = new CPDF_Array;
-    m_pDict->SetFor("I", pArray);
+    pArray = m_pDict->SetNewFor<CPDF_Array>("I");
   }
 
   bool bReturn = false;
diff --git a/core/fpdfdoc/cpdf_formfield_unittest.cpp b/core/fpdfdoc/cpdf_formfield_unittest.cpp
index f69df1d..4aeda84 100644
--- a/core/fpdfdoc/cpdf_formfield_unittest.cpp
+++ b/core/fpdfdoc/cpdf_formfield_unittest.cpp
@@ -4,6 +4,8 @@
 
 #include "core/fpdfapi/parser/cpdf_dictionary.h"
 #include "core/fpdfapi/parser/cpdf_indirect_object_holder.h"
+#include "core/fpdfapi/parser/cpdf_name.h"
+#include "core/fpdfapi/parser/cpdf_reference.h"
 #include "core/fpdfdoc/cpdf_formfield.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -13,29 +15,28 @@
 
   CPDF_IndirectObjectHolder obj_holder;
   CPDF_Dictionary* root = obj_holder.NewIndirect<CPDF_Dictionary>();
-  root->SetNameFor("T", "foo");
+  root->SetNewFor<CPDF_Name>("T", "foo");
   name = FPDF_GetFullName(root);
   EXPECT_STREQ("foo", name.UTF8Encode().c_str());
 
   CPDF_Dictionary* dict1 = obj_holder.NewIndirect<CPDF_Dictionary>();
-  root->SetReferenceFor("Parent", &obj_holder, dict1);
-  dict1->SetNameFor("T", "bar");
+  root->SetNewFor<CPDF_Reference>("Parent", &obj_holder, dict1->GetObjNum());
+  dict1->SetNewFor<CPDF_Name>("T", "bar");
   name = FPDF_GetFullName(root);
   EXPECT_STREQ("bar.foo", name.UTF8Encode().c_str());
 
-  CPDF_Dictionary* dict2 = new CPDF_Dictionary();
-  dict1->SetFor("Parent", dict2);
+  CPDF_Dictionary* dict2 = dict1->SetNewFor<CPDF_Dictionary>("Parent");
   name = FPDF_GetFullName(root);
   EXPECT_STREQ("bar.foo", name.UTF8Encode().c_str());
 
   CPDF_Dictionary* dict3 = obj_holder.NewIndirect<CPDF_Dictionary>();
-  dict2->SetReferenceFor("Parent", &obj_holder, dict3);
+  dict2->SetNewFor<CPDF_Reference>("Parent", &obj_holder, dict3->GetObjNum());
 
-  dict3->SetNameFor("T", "qux");
+  dict3->SetNewFor<CPDF_Name>("T", "qux");
   name = FPDF_GetFullName(root);
   EXPECT_STREQ("qux.bar.foo", name.UTF8Encode().c_str());
 
-  dict3->SetReferenceFor("Parent", &obj_holder, root->GetObjNum());
+  dict3->SetNewFor<CPDF_Reference>("Parent", &obj_holder, root->GetObjNum());
   name = FPDF_GetFullName(root);
   EXPECT_STREQ("qux.bar.foo", name.UTF8Encode().c_str());
   name = FPDF_GetFullName(dict1);
diff --git a/core/fpdfdoc/cpdf_interform.cpp b/core/fpdfdoc/cpdf_interform.cpp
index f541d70..377a360 100644
--- a/core/fpdfdoc/cpdf_interform.cpp
+++ b/core/fpdfdoc/cpdf_interform.cpp
@@ -4,6 +4,9 @@
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
+#include "core/fpdfdoc/cpdf_interform.h"
+
+#include <utility>
 #include <vector>
 
 #include "core/fpdfapi/font/cpdf_font.h"
@@ -12,11 +15,11 @@
 #include "core/fpdfapi/parser/cfdf_document.h"
 #include "core/fpdfapi/parser/cpdf_array.h"
 #include "core/fpdfapi/parser/cpdf_document.h"
+#include "core/fpdfapi/parser/cpdf_name.h"
 #include "core/fpdfapi/parser/cpdf_reference.h"
 #include "core/fpdfapi/parser/cpdf_string.h"
 #include "core/fpdfdoc/cpdf_filespec.h"
 #include "core/fpdfdoc/cpdf_formcontrol.h"
-#include "core/fpdfdoc/cpdf_interform.h"
 #include "core/fxge/cfx_substfont.h"
 #include "core/fxge/fx_font.h"
 #include "third_party/base/stl_util.h"
@@ -60,8 +63,8 @@
 
   if (!pFormDict) {
     pFormDict = pDocument->NewIndirect<CPDF_Dictionary>();
-    pDocument->GetRoot()->SetReferenceFor("AcroForm", pDocument,
-                                          pFormDict->GetObjNum());
+    pDocument->GetRoot()->SetNewFor<CPDF_Reference>("AcroForm", pDocument,
+                                                    pFormDict->GetObjNum());
   }
 
   CFX_ByteString csDA;
@@ -94,7 +97,7 @@
 
   csDA += "0 g";
   if (!pFormDict->KeyExist("DA"))
-    pFormDict->SetStringFor("DA", csDA);
+    pFormDict->SetNewFor<CPDF_String>("DA", csDA, false);
 }
 
 CPDF_Font* GetFont(CPDF_Dictionary* pFormDict,
@@ -138,11 +141,10 @@
 
   for (const auto& it : *pFonts) {
     const CFX_ByteString& csKey = it.first;
-    CPDF_Object* pObj = it.second;
-    if (!pObj)
+    if (!it.second)
       continue;
 
-    CPDF_Dictionary* pElement = ToDictionary(pObj->GetDirect());
+    CPDF_Dictionary* pElement = ToDictionary(it.second->GetDirect());
     if (!pElement)
       continue;
     if (pElement->GetStringFor("Type") != "Font")
@@ -179,11 +181,9 @@
 
   for (const auto& it : *pFonts) {
     const CFX_ByteString& csKey = it.first;
-    CPDF_Object* pObj = it.second;
-    if (!pObj)
+    if (!it.second)
       continue;
-
-    CPDF_Dictionary* pElement = ToDictionary(pObj->GetDirect());
+    CPDF_Dictionary* pElement = ToDictionary(it.second->GetDirect());
     if (!pElement)
       continue;
     if (pElement->GetStringFor("Type") != "Font")
@@ -216,16 +216,14 @@
 
   for (const auto& it : *pFonts) {
     const CFX_ByteString& csKey = it.first;
-    CPDF_Object* pObj = it.second;
-    if (!pObj)
+    if (!it.second)
       continue;
 
-    CPDF_Dictionary* pElement = ToDictionary(pObj->GetDirect());
+    CPDF_Dictionary* pElement = ToDictionary(it.second->GetDirect());
     if (!pElement)
       continue;
     if (pElement->GetStringFor("Type") != "Font")
       continue;
-
     pFont = pDocument->LoadFont(pElement);
     if (!pFont)
       continue;
@@ -259,23 +257,21 @@
     InitDict(pFormDict, pDocument);
 
   CPDF_Dictionary* pDR = pFormDict->GetDictFor("DR");
-  if (!pDR) {
-    pDR = new CPDF_Dictionary(pDocument->GetByteStringPool());
-    pFormDict->SetFor("DR", pDR);
-  }
+  if (!pDR)
+    pDR = pFormDict->SetNewFor<CPDF_Dictionary>("DR");
+
   CPDF_Dictionary* pFonts = pDR->GetDictFor("Font");
-  if (!pFonts) {
-    pFonts = new CPDF_Dictionary(pDocument->GetByteStringPool());
-    pDR->SetFor("Font", pFonts);
-  }
+  if (!pFonts)
+    pFonts = pDR->SetNewFor<CPDF_Dictionary>("Font");
+
   if (csNameTag.IsEmpty())
     csNameTag = pFont->GetBaseFont();
 
   csNameTag.Remove(' ');
   csNameTag = CPDF_InterForm::GenerateNewResourceName(pDR, "Font", 4,
                                                       csNameTag.c_str());
-  pFonts->SetReferenceFor(csNameTag, pDocument,
-                          pFont->GetFontDict()->GetObjNum());
+  pFonts->SetNewFor<CPDF_Reference>(csNameTag, pDocument,
+                                    pFont->GetFontDict()->GetObjNum());
 }
 
 CPDF_Font* AddNativeFont(CPDF_Dictionary*& pFormDict,
@@ -1105,13 +1101,13 @@
       if (pFieldDict->KeyExist("FT")) {
         CPDF_Object* pFTValue = pFieldDict->GetDirectObjectFor("FT");
         if (pFTValue)
-          pParent->SetFor("FT", pFTValue->Clone().release());
+          pParent->SetFor("FT", pFTValue->Clone());
       }
 
       if (pFieldDict->KeyExist("Ff")) {
         CPDF_Object* pFfValue = pFieldDict->GetDirectObjectFor("Ff");
         if (pFfValue)
-          pParent->SetFor("Ff", pFfValue->Clone().release());
+          pParent->SetFor("Ff", pFfValue->Clone());
       }
     }
 
@@ -1120,9 +1116,9 @@
     if (ToReference(pTObj)) {
       std::unique_ptr<CPDF_Object> pClone = pTObj->CloneDirectObject();
       if (pClone)
-        pDict->SetFor("T", pClone.release());
+        pDict->SetFor("T", std::move(pClone));
       else
-        pDict->SetNameFor("T", "");
+        pDict->SetNewFor<CPDF_Name>("T", "");
     }
     m_pFieldTree->SetField(csWName, pField);
   }
@@ -1210,17 +1206,18 @@
   if (!pdf_path.IsEmpty()) {
     if (bSimpleFileSpec) {
       CFX_WideString wsFilePath = CPDF_FileSpec::EncodeFileName(pdf_path);
-      pMainDict->SetStringFor("F", CFX_ByteString::FromUnicode(wsFilePath));
-      pMainDict->SetStringFor("UF", PDF_EncodeText(wsFilePath));
+      pMainDict->SetNewFor<CPDF_String>(
+          "F", CFX_ByteString::FromUnicode(wsFilePath), false);
+      pMainDict->SetNewFor<CPDF_String>("UF", PDF_EncodeText(wsFilePath),
+                                        false);
     } else {
       CPDF_FileSpec filespec(pDoc->GetByteStringPool());
       filespec.SetFileName(pdf_path);
-      pMainDict->SetFor("F", filespec.GetObj());
+      pMainDict->SetFor("F", pdfium::WrapUnique(filespec.GetObj()));
     }
   }
 
-  CPDF_Array* pFields = new CPDF_Array;
-  pMainDict->SetFor("Fields", pFields);
+  CPDF_Array* pFields = pMainDict->SetNewFor<CPDF_Array>("Fields");
   size_t nCount = m_pFieldTree->m_Root.CountFields();
   for (size_t i = 0; i < nCount; ++i) {
     CPDF_FormField* pField = m_pFieldTree->m_Root.GetFieldAtIndex(i);
@@ -1238,20 +1235,20 @@
       CFX_WideString fullname = FPDF_GetFullName(pField->GetFieldDict());
       auto pFieldDict =
           pdfium::MakeUnique<CPDF_Dictionary>(pDoc->GetByteStringPool());
-      pFieldDict->SetFor("T", new CPDF_String(fullname));
+      pFieldDict->SetNewFor<CPDF_String>("T", fullname);
       if (pField->GetType() == CPDF_FormField::CheckBox ||
           pField->GetType() == CPDF_FormField::RadioButton) {
         CFX_WideString csExport = pField->GetCheckValue(false);
         CFX_ByteString csBExport = PDF_EncodeText(csExport);
         CPDF_Object* pOpt = FPDF_GetFieldAttr(pField->m_pDict, "Opt");
         if (pOpt)
-          pFieldDict->SetStringFor("V", csBExport);
+          pFieldDict->SetNewFor<CPDF_String>("V", csBExport, false);
         else
-          pFieldDict->SetNameFor("V", csBExport);
+          pFieldDict->SetNewFor<CPDF_Name>("V", csBExport);
       } else {
         CPDF_Object* pV = FPDF_GetFieldAttr(pField->m_pDict, "V");
         if (pV)
-          pFieldDict->SetFor("V", pV->CloneDirectObject().release());
+          pFieldDict->SetFor("V", pV->CloneDirectObject());
       }
       pFields->Add(std::move(pFieldDict));
     }
@@ -1289,23 +1286,20 @@
   CFX_WideString csWValue = GetFieldValue(*pFieldDict, m_bsEncoding);
   int iType = pField->GetFieldType();
   if (bNotify && m_pFormNotify) {
-    int iRet = 0;
-    if (iType == FIELDTYPE_LISTBOX)
-      iRet = m_pFormNotify->BeforeSelectionChange(pField, csWValue);
-    else if (iType == FIELDTYPE_COMBOBOX || iType == FIELDTYPE_TEXTFIELD)
-      iRet = m_pFormNotify->BeforeValueChange(pField, csWValue);
-
-    if (iRet < 0)
-      return;
+    if (iType == FIELDTYPE_LISTBOX) {
+      if (m_pFormNotify->BeforeSelectionChange(pField, csWValue) < 0)
+        return;
+    } else if (iType == FIELDTYPE_COMBOBOX || iType == FIELDTYPE_TEXTFIELD) {
+      if (m_pFormNotify->BeforeValueChange(pField, csWValue) < 0)
+        return;
+    }
   }
-
   pField->SetValue(csWValue);
   CPDF_FormField::Type eType = pField->GetType();
   if ((eType == CPDF_FormField::ListBox || eType == CPDF_FormField::ComboBox) &&
       pFieldDict->KeyExist("Opt")) {
     pField->m_pDict->SetFor(
-        "Opt",
-        pFieldDict->GetDirectObjectFor("Opt")->CloneDirectObject().release());
+        "Opt", pFieldDict->GetDirectObjectFor("Opt")->CloneDirectObject());
   }
 
   if (bNotify && m_pFormNotify) {
diff --git a/core/fpdfdoc/cpvt_fontmap.cpp b/core/fpdfdoc/cpvt_fontmap.cpp
index a47595a..283f600 100644
--- a/core/fpdfdoc/cpvt_fontmap.cpp
+++ b/core/fpdfdoc/cpvt_fontmap.cpp
@@ -9,6 +9,7 @@
 #include "core/fpdfapi/font/cpdf_font.h"
 #include "core/fpdfapi/parser/cpdf_dictionary.h"
 #include "core/fpdfapi/parser/cpdf_document.h"
+#include "core/fpdfapi/parser/cpdf_reference.h"
 #include "core/fpdfdoc/cpdf_interform.h"
 
 CPVT_FontMap::CPVT_FontMap(CPDF_Document* pDoc,
@@ -39,8 +40,8 @@
 
   CPDF_Dictionary* pFontList = pResDict->GetDictFor("Font");
   if (pFontList && !pFontList->KeyExist(sSysFontAlias)) {
-    pFontList->SetReferenceFor(sSysFontAlias, pDoc,
-                               pPDFFont->GetFontDict()->GetObjNum());
+    pFontList->SetNewFor<CPDF_Reference>(sSysFontAlias, pDoc,
+                                         pPDFFont->GetFontDict()->GetObjNum());
   }
   pSysFont = pPDFFont;
 }
diff --git a/core/fpdfdoc/cpvt_generateap.cpp b/core/fpdfdoc/cpvt_generateap.cpp
index 31d2242..4bb244f 100644
--- a/core/fpdfdoc/cpvt_generateap.cpp
+++ b/core/fpdfdoc/cpvt_generateap.cpp
@@ -11,10 +11,15 @@
 #include <utility>
 
 #include "core/fpdfapi/font/cpdf_font.h"
+#include "core/fpdfapi/parser/cpdf_boolean.h"
 #include "core/fpdfapi/parser/cpdf_dictionary.h"
 #include "core/fpdfapi/parser/cpdf_document.h"
+#include "core/fpdfapi/parser/cpdf_name.h"
+#include "core/fpdfapi/parser/cpdf_number.h"
+#include "core/fpdfapi/parser/cpdf_reference.h"
 #include "core/fpdfapi/parser/cpdf_simple_parser.h"
 #include "core/fpdfapi/parser/cpdf_stream.h"
+#include "core/fpdfapi/parser/cpdf_string.h"
 #include "core/fpdfapi/parser/fpdf_parser_decode.h"
 #include "core/fpdfdoc/cpdf_annot.h"
 #include "core/fpdfdoc/cpdf_formfield.h"
@@ -62,11 +67,12 @@
   CPDF_Dictionary* pFontDict = pDRFontDict->GetDictFor(sFontName.Mid(1));
   if (!pFontDict) {
     pFontDict = pDoc->NewIndirect<CPDF_Dictionary>();
-    pFontDict->SetNameFor("Type", "Font");
-    pFontDict->SetNameFor("Subtype", "Type1");
-    pFontDict->SetNameFor("BaseFont", "Helvetica");
-    pFontDict->SetNameFor("Encoding", "WinAnsiEncoding");
-    pDRFontDict->SetReferenceFor(sFontName.Mid(1), pDoc, pFontDict);
+    pFontDict->SetNewFor<CPDF_Name>("Type", "Font");
+    pFontDict->SetNewFor<CPDF_Name>("Subtype", "Type1");
+    pFontDict->SetNewFor<CPDF_Name>("BaseFont", "Helvetica");
+    pFontDict->SetNewFor<CPDF_Name>("Encoding", "WinAnsiEncoding");
+    pDRFontDict->SetNewFor<CPDF_Reference>(sFontName.Mid(1), pDoc,
+                                           pFontDict->GetObjNum());
   }
   CPDF_Font* pDefFont = pDoc->LoadFont(pFontDict);
   if (!pDefFont)
@@ -163,18 +169,15 @@
       CFX_FloatRect(rcBBox.left + fBorderWidth, rcBBox.bottom + fBorderWidth,
                     rcBBox.right - fBorderWidth, rcBBox.top - fBorderWidth);
   rcBody.Normalize();
+
   CPDF_Dictionary* pAPDict = pAnnotDict->GetDictFor("AP");
-  if (!pAPDict) {
-    auto pNewAPDict =
-        pdfium::MakeUnique<CPDF_Dictionary>(pDoc->GetByteStringPool());
-    // Ownership passes to |pAnnotDict|.
-    pAPDict = pNewAPDict.release();
-    pAnnotDict->SetFor("AP", pAPDict);
-  }
+  if (!pAPDict)
+    pAPDict = pAnnotDict->SetNewFor<CPDF_Dictionary>("AP");
+
   CPDF_Stream* pNormalStream = pAPDict->GetStreamFor("N");
   if (!pNormalStream) {
     pNormalStream = pDoc->NewIndirect<CPDF_Stream>();
-    pAPDict->SetReferenceFor("N", pDoc, pNormalStream);
+    pAPDict->SetNewFor<CPDF_Reference>("N", pDoc, pNormalStream->GetObjNum());
   }
   CPDF_Dictionary* pStreamDict = pNormalStream->GetDict();
   if (pStreamDict) {
@@ -183,18 +186,14 @@
     CPDF_Dictionary* pStreamResList = pStreamDict->GetDictFor("Resources");
     if (pStreamResList) {
       CPDF_Dictionary* pStreamResFontList = pStreamResList->GetDictFor("Font");
-      if (!pStreamResFontList) {
-        auto pNewStreamResFontList =
-            pdfium::MakeUnique<CPDF_Dictionary>(pDoc->GetByteStringPool());
-        // Ownership passes to |pStreamResList|.
-        pStreamResFontList = pNewStreamResFontList.release();
-        pStreamResList->SetFor("Font", pStreamResFontList);
+      if (!pStreamResFontList)
+        pStreamResFontList = pStreamResList->SetNewFor<CPDF_Dictionary>("Font");
+      if (!pStreamResFontList->KeyExist(sFontName)) {
+        pStreamResFontList->SetNewFor<CPDF_Reference>(sFontName, pDoc,
+                                                      pFontDict->GetObjNum());
       }
-      if (!pStreamResFontList->KeyExist(sFontName))
-        pStreamResFontList->SetReferenceFor(sFontName, pDoc, pFontDict);
     } else {
-      pStreamDict->SetFor("Resources",
-                          pFormDict->GetDictFor("DR")->Clone().release());
+      pStreamDict->SetFor("Resources", pFormDict->GetDictFor("DR")->Clone());
       pStreamResList = pStreamDict->GetDictFor("Resources");
     }
   }
@@ -438,17 +437,15 @@
         CPDF_Dictionary* pStreamResFontList =
             pStreamResList->GetDictFor("Font");
         if (!pStreamResFontList) {
-          auto pNewStreamResFontList =
-              pdfium::MakeUnique<CPDF_Dictionary>(pDoc->GetByteStringPool());
-          // Ownership passes to |pStreamResList|.
-          pStreamResFontList = pNewStreamResFontList.release();
-          pStreamResList->SetFor("Font", pStreamResFontList);
+          pStreamResFontList =
+              pStreamResList->SetNewFor<CPDF_Dictionary>("Font");
         }
-        if (!pStreamResFontList->KeyExist(sFontName))
-          pStreamResFontList->SetReferenceFor(sFontName, pDoc, pFontDict);
+        if (!pStreamResFontList->KeyExist(sFontName)) {
+          pStreamResFontList->SetNewFor<CPDF_Reference>(sFontName, pDoc,
+                                                        pFontDict->GetObjNum());
+        }
       } else {
-        pStreamDict->SetFor("Resources",
-                            pFormDict->GetDictFor("DR")->Clone().release());
+        pStreamDict->SetFor("Resources", pFormDict->GetDictFor("DR")->Clone());
         pStreamResList = pStreamDict->GetDictFor("Resources");
       }
     }
@@ -554,18 +551,18 @@
     const CFX_ByteString& sBlendMode) {
   auto pGSDict =
       pdfium::MakeUnique<CPDF_Dictionary>(pAnnotDict.GetByteStringPool());
-  pGSDict->SetStringFor("Type", "ExtGState");
+  pGSDict->SetNewFor<CPDF_String>("Type", "ExtGState", false);
 
   FX_FLOAT fOpacity =
       pAnnotDict.KeyExist("CA") ? pAnnotDict.GetNumberFor("CA") : 1;
-  pGSDict->SetNumberFor("CA", fOpacity);
-  pGSDict->SetNumberFor("ca", fOpacity);
-  pGSDict->SetBooleanFor("AIS", false);
-  pGSDict->SetStringFor("BM", sBlendMode);
+  pGSDict->SetNewFor<CPDF_Number>("CA", fOpacity);
+  pGSDict->SetNewFor<CPDF_Number>("ca", fOpacity);
+  pGSDict->SetNewFor<CPDF_Boolean>("AIS", false);
+  pGSDict->SetNewFor<CPDF_String>("BM", sBlendMode, false);
 
   auto pExtGStateDict =
       pdfium::MakeUnique<CPDF_Dictionary>(pAnnotDict.GetByteStringPool());
-  pExtGStateDict->SetFor(sExtGSDictName, pGSDict.release());
+  pExtGStateDict->SetFor(sExtGSDictName, std::move(pGSDict));
   return pExtGStateDict;
 }
 
@@ -573,14 +570,15 @@
     CPDF_Document* pDoc,
     const CFX_ByteString& sFontDictName) {
   CPDF_Dictionary* pFontDict = pDoc->NewIndirect<CPDF_Dictionary>();
-  pFontDict->SetNameFor("Type", "Font");
-  pFontDict->SetNameFor("Subtype", "Type1");
-  pFontDict->SetNameFor("BaseFont", "Helvetica");
-  pFontDict->SetNameFor("Encoding", "WinAnsiEncoding");
+  pFontDict->SetNewFor<CPDF_Name>("Type", "Font");
+  pFontDict->SetNewFor<CPDF_Name>("Subtype", "Type1");
+  pFontDict->SetNewFor<CPDF_Name>("BaseFont", "Helvetica");
+  pFontDict->SetNewFor<CPDF_Name>("Encoding", "WinAnsiEncoding");
 
   auto pResourceFontDict =
       pdfium::MakeUnique<CPDF_Dictionary>(pDoc->GetByteStringPool());
-  pResourceFontDict->SetReferenceFor(sFontDictName, pDoc, pFontDict);
+  pResourceFontDict->SetNewFor<CPDF_Reference>(sFontDictName, pDoc,
+                                               pFontDict->GetObjNum());
   return pResourceFontDict;
 }
 
@@ -591,9 +589,9 @@
   auto pResourceDict =
       pdfium::MakeUnique<CPDF_Dictionary>(pDoc->GetByteStringPool());
   if (pExtGStateDict)
-    pResourceDict->SetFor("ExtGState", pExtGStateDict.release());
+    pResourceDict->SetFor("ExtGState", std::move(pExtGStateDict));
   if (pResourceFontDict)
-    pResourceDict->SetFor("Font", pResourceFontDict.release());
+    pResourceDict->SetFor("Font", std::move(pResourceFontDict));
   return pResourceDict;
 }
 
@@ -605,20 +603,19 @@
   CPDF_Stream* pNormalStream = pDoc->NewIndirect<CPDF_Stream>();
   pNormalStream->SetData(sAppStream.GetBuffer(), sAppStream.GetSize());
 
-  auto pAPDict = pdfium::MakeUnique<CPDF_Dictionary>(pDoc->GetByteStringPool());
-  pAPDict->SetReferenceFor("N", pDoc, pNormalStream);
-  pAnnotDict->SetFor("AP", pAPDict.release());
+  CPDF_Dictionary* pAPDict = pAnnotDict->SetNewFor<CPDF_Dictionary>("AP");
+  pAPDict->SetNewFor<CPDF_Reference>("N", pDoc, pNormalStream->GetObjNum());
 
   CPDF_Dictionary* pStreamDict = pNormalStream->GetDict();
-  pStreamDict->SetIntegerFor("FormType", 1);
-  pStreamDict->SetStringFor("Subtype", "Form");
+  pStreamDict->SetNewFor<CPDF_Number>("FormType", 1);
+  pStreamDict->SetNewFor<CPDF_String>("Subtype", "Form", false);
   pStreamDict->SetMatrixFor("Matrix", CFX_Matrix());
 
   CFX_FloatRect rect = bIsTextMarkupAnnotation
                            ? CPDF_Annot::RectFromQuadPoints(pAnnotDict)
                            : pAnnotDict->GetRectFor("Rect");
   pStreamDict->SetRectFor("BBox", rect);
-  pStreamDict->SetFor("Resources", pResourceDict.release());
+  pStreamDict->SetFor("Resources", std::move(pResourceDict));
 }
 
 CFX_ByteString GetPaintOperatorString(bool bIsStrokeRect, bool bIsFillRect) {
@@ -693,7 +690,6 @@
 
   CPDF_Object* pFieldFlagsObj = FPDF_GetFieldAttr(pAnnotDict, "Ff");
   uint32_t flags = pFieldFlagsObj ? pFieldFlagsObj->GetInteger() : 0;
-
   if (field_type == "Ch") {
     return (flags & (1 << 17))
                ? CPVT_GenerateAP::GenerateComboBoxAP(pDoc, pAnnotDict)
@@ -705,7 +701,8 @@
       if (!pAnnotDict->KeyExist("AS")) {
         if (CPDF_Dictionary* pParentDict = pAnnotDict->GetDictFor("Parent")) {
           if (pParentDict->KeyExist("AS")) {
-            pAnnotDict->SetStringFor("AS", pParentDict->GetStringFor("AS"));
+            pAnnotDict->SetNewFor<CPDF_String>(
+                "AS", pParentDict->GetStringFor("AS"), false);
           }
         }
       }
diff --git a/core/fxge/dib/fx_dib_engine_unittest.cpp b/core/fxge/dib/fx_dib_engine_unittest.cpp
index 57e829e..faacebd 100644
--- a/core/fxge/dib/fx_dib_engine_unittest.cpp
+++ b/core/fxge/dib/fx_dib_engine_unittest.cpp
@@ -18,8 +18,8 @@
   FX_RECT clip_rect;
   std::unique_ptr<CPDF_Dictionary> dict_obj =
       pdfium::MakeUnique<CPDF_Dictionary>();
-  dict_obj->SetFor("Width", new CPDF_Number(71000));
-  dict_obj->SetFor("Height", new CPDF_Number(12500));
+  dict_obj->SetNewFor<CPDF_Number>("Width", 71000);
+  dict_obj->SetNewFor<CPDF_Number>("Height", 12500);
   std::unique_ptr<CPDF_Stream> stream =
       pdfium::MakeUnique<CPDF_Stream>(nullptr, 0, dict_obj.release());
   CPDF_DIBSource dib_source;
diff --git a/fpdfsdk/cpdfsdk_annothandlermgr.cpp b/fpdfsdk/cpdfsdk_annothandlermgr.cpp
index 51ce88e..898b9cc 100644
--- a/fpdfsdk/cpdfsdk_annothandlermgr.cpp
+++ b/fpdfsdk/cpdfsdk_annothandlermgr.cpp
@@ -6,6 +6,8 @@
 
 #include "fpdfsdk/cpdfsdk_annothandlermgr.h"
 
+#include "core/fpdfapi/parser/cpdf_number.h"
+#include "core/fpdfapi/parser/cpdf_string.h"
 #include "core/fpdfdoc/cpdf_annot.h"
 #include "fpdfsdk/cba_annotiterator.h"
 #include "fpdfsdk/cpdfsdk_annot.h"
@@ -62,8 +64,9 @@
   CPDF_Annot* pPDFAnnot = pAnnot->GetPDFAnnot();
 
   CPDFSDK_DateTime curTime;
-  pPDFAnnot->GetAnnotDict()->SetStringFor("M", curTime.ToPDFDateTimeString());
-  pPDFAnnot->GetAnnotDict()->SetNumberFor("F", 0);
+  pPDFAnnot->GetAnnotDict()->SetNewFor<CPDF_String>(
+      "M", curTime.ToPDFDateTimeString(), false);
+  pPDFAnnot->GetAnnotDict()->SetNewFor<CPDF_Number>("F", 0);
 }
 
 void CPDFSDK_AnnotHandlerMgr::Annot_OnLoad(CPDFSDK_Annot* pAnnot) {
diff --git a/fpdfsdk/cpdfsdk_baannot.cpp b/fpdfsdk/cpdfsdk_baannot.cpp
index ee4b55d..9fb1e88 100644
--- a/fpdfsdk/cpdfsdk_baannot.cpp
+++ b/fpdfsdk/cpdfsdk_baannot.cpp
@@ -6,10 +6,15 @@
 
 #include "fpdfsdk/cpdfsdk_baannot.h"
 
+#include <algorithm>
+
 #include "core/fpdfapi/parser/cpdf_array.h"
 #include "core/fpdfapi/parser/cpdf_document.h"
+#include "core/fpdfapi/parser/cpdf_name.h"
 #include "core/fpdfapi/parser/cpdf_number.h"
+#include "core/fpdfapi/parser/cpdf_reference.h"
 #include "core/fpdfapi/parser/cpdf_stream.h"
+#include "core/fpdfapi/parser/cpdf_string.h"
 #include "core/fpdfapi/parser/fpdf_parser_decode.h"
 #include "fpdfsdk/cpdfsdk_datetime.h"
 #include "fpdfsdk/cpdfsdk_pageview.h"
@@ -89,11 +94,12 @@
 }
 
 void CPDFSDK_BAAnnot::SetContents(const CFX_WideString& sContents) {
-  if (sContents.IsEmpty())
+  if (sContents.IsEmpty()) {
     m_pAnnot->GetAnnotDict()->RemoveFor("Contents");
-  else
-    m_pAnnot->GetAnnotDict()->SetStringFor("Contents",
-                                           PDF_EncodeText(sContents));
+  } else {
+    m_pAnnot->GetAnnotDict()->SetNewFor<CPDF_String>(
+        "Contents", PDF_EncodeText(sContents), false);
+  }
 }
 
 CFX_WideString CPDFSDK_BAAnnot::GetContents() const {
@@ -101,10 +107,12 @@
 }
 
 void CPDFSDK_BAAnnot::SetAnnotName(const CFX_WideString& sName) {
-  if (sName.IsEmpty())
+  if (sName.IsEmpty()) {
     m_pAnnot->GetAnnotDict()->RemoveFor("NM");
-  else
-    m_pAnnot->GetAnnotDict()->SetStringFor("NM", PDF_EncodeText(sName));
+  } else {
+    m_pAnnot->GetAnnotDict()->SetNewFor<CPDF_String>(
+        "NM", PDF_EncodeText(sName), false);
+  }
 }
 
 CFX_WideString CPDFSDK_BAAnnot::GetAnnotName() const {
@@ -114,25 +122,23 @@
 void CPDFSDK_BAAnnot::SetModifiedDate(const FX_SYSTEMTIME& st) {
   CPDFSDK_DateTime dt(st);
   CFX_ByteString str = dt.ToPDFDateTimeString();
-
   if (str.IsEmpty())
     m_pAnnot->GetAnnotDict()->RemoveFor("M");
   else
-    m_pAnnot->GetAnnotDict()->SetStringFor("M", str);
+    m_pAnnot->GetAnnotDict()->SetNewFor<CPDF_String>("M", str, false);
 }
 
 FX_SYSTEMTIME CPDFSDK_BAAnnot::GetModifiedDate() const {
   FX_SYSTEMTIME systime;
   CFX_ByteString str = m_pAnnot->GetAnnotDict()->GetStringFor("M");
-
   CPDFSDK_DateTime dt(str);
   dt.ToSystemTime(systime);
-
   return systime;
 }
 
 void CPDFSDK_BAAnnot::SetFlags(uint32_t nFlags) {
-  m_pAnnot->GetAnnotDict()->SetIntegerFor("F", nFlags);
+  m_pAnnot->GetAnnotDict()->SetNewFor<CPDF_Number>("F",
+                                                   static_cast<int>(nFlags));
 }
 
 uint32_t CPDFSDK_BAAnnot::GetFlags() const {
@@ -143,7 +149,7 @@
   if (str.IsEmpty())
     m_pAnnot->GetAnnotDict()->RemoveFor("AS");
   else
-    m_pAnnot->GetAnnotDict()->SetStringFor("AS", str);
+    m_pAnnot->GetAnnotDict()->SetNewFor<CPDF_String>("AS", str, false);
 }
 
 CFX_ByteString CPDFSDK_BAAnnot::GetAppState() const {
@@ -151,7 +157,7 @@
 }
 
 void CPDFSDK_BAAnnot::SetStructParent(int key) {
-  m_pAnnot->GetAnnotDict()->SetIntegerFor("StructParent", key);
+  m_pAnnot->GetAnnotDict()->SetNewFor<CPDF_Number>("StructParent", key);
 }
 
 int CPDFSDK_BAAnnot::GetStructParent() const {
@@ -165,12 +171,10 @@
     pBorder->SetNewAt<CPDF_Number>(2, nWidth);
   } else {
     CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDictFor("BS");
-    if (!pBSDict) {
-      pBSDict =
-          new CPDF_Dictionary(m_pAnnot->GetDocument()->GetByteStringPool());
-      m_pAnnot->GetAnnotDict()->SetFor("BS", pBSDict);
-    }
-    pBSDict->SetIntegerFor("W", nWidth);
+    if (!pBSDict)
+      pBSDict = m_pAnnot->GetAnnotDict()->SetNewFor<CPDF_Dictionary>("BS");
+
+    pBSDict->SetNewFor<CPDF_Number>("W", nWidth);
   }
 }
 
@@ -186,26 +190,24 @@
 
 void CPDFSDK_BAAnnot::SetBorderStyle(BorderStyle nStyle) {
   CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDictFor("BS");
-  if (!pBSDict) {
-    pBSDict = new CPDF_Dictionary(m_pAnnot->GetDocument()->GetByteStringPool());
-    m_pAnnot->GetAnnotDict()->SetFor("BS", pBSDict);
-  }
+  if (!pBSDict)
+    pBSDict = m_pAnnot->GetAnnotDict()->SetNewFor<CPDF_Dictionary>("BS");
 
   switch (nStyle) {
     case BorderStyle::SOLID:
-      pBSDict->SetNameFor("S", "S");
+      pBSDict->SetNewFor<CPDF_Name>("S", "S");
       break;
     case BorderStyle::DASH:
-      pBSDict->SetNameFor("S", "D");
+      pBSDict->SetNewFor<CPDF_Name>("S", "D");
       break;
     case BorderStyle::BEVELED:
-      pBSDict->SetNameFor("S", "B");
+      pBSDict->SetNewFor<CPDF_Name>("S", "B");
       break;
     case BorderStyle::INSET:
-      pBSDict->SetNameFor("S", "I");
+      pBSDict->SetNewFor<CPDF_Name>("S", "I");
       break;
     case BorderStyle::UNDERLINE:
-      pBSDict->SetNameFor("S", "U");
+      pBSDict->SetNewFor<CPDF_Name>("S", "U");
       break;
     default:
       break;
@@ -241,14 +243,13 @@
 }
 
 void CPDFSDK_BAAnnot::SetColor(FX_COLORREF color) {
-  CPDF_Array* pArray = new CPDF_Array;
+  CPDF_Array* pArray = m_pAnnot->GetAnnotDict()->SetNewFor<CPDF_Array>("C");
   pArray->AddNew<CPDF_Number>(static_cast<FX_FLOAT>(FXSYS_GetRValue(color)) /
                               255.0f);
   pArray->AddNew<CPDF_Number>(static_cast<FX_FLOAT>(FXSYS_GetGValue(color)) /
                               255.0f);
   pArray->AddNew<CPDF_Number>(static_cast<FX_FLOAT>(FXSYS_GetBValue(color)) /
                               255.0f);
-  m_pAnnot->GetAnnotDict()->SetFor("C", pArray);
 }
 
 void CPDFSDK_BAAnnot::RemoveColor() {
@@ -297,10 +298,8 @@
                                       const CFX_ByteString& sContents,
                                       const CFX_ByteString& sAPState) {
   CPDF_Dictionary* pAPDict = m_pAnnot->GetAnnotDict()->GetDictFor("AP");
-  if (!pAPDict) {
-    pAPDict = new CPDF_Dictionary(m_pAnnot->GetDocument()->GetByteStringPool());
-    m_pAnnot->GetAnnotDict()->SetFor("AP", pAPDict);
-  }
+  if (!pAPDict)
+    pAPDict = m_pAnnot->GetAnnotDict()->SetNewFor<CPDF_Dictionary>("AP");
 
   CPDF_Stream* pStream = nullptr;
   CPDF_Dictionary* pParentDict = nullptr;
@@ -309,11 +308,9 @@
     pStream = pAPDict->GetStreamFor(sAPType);
   } else {
     CPDF_Dictionary* pAPTypeDict = pAPDict->GetDictFor(sAPType);
-    if (!pAPTypeDict) {
-      pAPTypeDict =
-          new CPDF_Dictionary(m_pAnnot->GetDocument()->GetByteStringPool());
-      pAPDict->SetFor(sAPType, pAPTypeDict);
-    }
+    if (!pAPTypeDict)
+      pAPTypeDict = pAPDict->SetNewFor<CPDF_Dictionary>(sAPType);
+
     pParentDict = pAPTypeDict;
     pStream = pAPTypeDict->GetStreamFor(sAPState);
   }
@@ -321,16 +318,16 @@
   if (!pStream) {
     CPDF_Document* pDoc = m_pPageView->GetPDFDocument();
     pStream = pDoc->NewIndirect<CPDF_Stream>();
-    pParentDict->SetReferenceFor(sAPType, pDoc, pStream);
+    pParentDict->SetNewFor<CPDF_Reference>(sAPType, pDoc, pStream->GetObjNum());
   }
 
   CPDF_Dictionary* pStreamDict = pStream->GetDict();
   if (!pStreamDict) {
     pStreamDict =
         new CPDF_Dictionary(m_pAnnot->GetDocument()->GetByteStringPool());
-    pStreamDict->SetNameFor("Type", "XObject");
-    pStreamDict->SetNameFor("Subtype", "Form");
-    pStreamDict->SetIntegerFor("FormType", 1);
+    pStreamDict->SetNewFor<CPDF_Name>("Type", "XObject");
+    pStreamDict->SetNewFor<CPDF_Name>("Subtype", "Form");
+    pStreamDict->SetNewFor<CPDF_Number>("FormType", 1);
     pStream->InitStream(nullptr, 0, pStreamDict);
   }
 
@@ -358,7 +355,8 @@
     CPDF_Document* pDoc = m_pPageView->GetPDFDocument();
     if (pDict->IsInline())
       pDict = pDoc->AddIndirectObject(pDict->Clone())->AsDictionary();
-    m_pAnnot->GetAnnotDict()->SetReferenceFor("A", pDoc, pDict);
+    m_pAnnot->GetAnnotDict()->SetNewFor<CPDF_Reference>("A", pDoc,
+                                                        pDict->GetObjNum());
   }
 }
 
@@ -372,7 +370,7 @@
 
 void CPDFSDK_BAAnnot::SetAAction(const CPDF_AAction& aa) {
   if (aa.GetDict() != m_pAnnot->GetAnnotDict()->GetDictFor("AA"))
-    m_pAnnot->GetAnnotDict()->SetFor("AA", aa.GetDict());
+    m_pAnnot->GetAnnotDict()->SetFor("AA", pdfium::WrapUnique(aa.GetDict()));
 }
 
 void CPDFSDK_BAAnnot::RemoveAAction() {
@@ -381,7 +379,6 @@
 
 CPDF_Action CPDFSDK_BAAnnot::GetAAction(CPDF_AAction::AActionType eAAT) {
   CPDF_AAction AAction = GetAAction();
-
   if (AAction.ActionExist(eAAT))
     return AAction.GetAction(eAAT);
 
diff --git a/fpdfsdk/cpdfsdk_widget.cpp b/fpdfsdk/cpdfsdk_widget.cpp
index b1c3379..1086906 100644
--- a/fpdfsdk/cpdfsdk_widget.cpp
+++ b/fpdfsdk/cpdfsdk_widget.cpp
@@ -8,9 +8,12 @@
 
 #include <memory>
 
+#include "core/fpdfapi/parser/cpdf_array.h"
 #include "core/fpdfapi/parser/cpdf_dictionary.h"
 #include "core/fpdfapi/parser/cpdf_document.h"
+#include "core/fpdfapi/parser/cpdf_reference.h"
 #include "core/fpdfapi/parser/cpdf_stream.h"
+#include "core/fpdfapi/parser/cpdf_string.h"
 #include "core/fpdfdoc/cpdf_defaultappearance.h"
 #include "core/fpdfdoc/cpdf_formcontrol.h"
 #include "core/fpdfdoc/cpdf_formfield.h"
@@ -966,21 +969,21 @@
   if (pNormalIcon) {
     if (CPDF_Dictionary* pImageDict = pNormalIcon->GetDict()) {
       if (pImageDict->GetStringFor("Name").IsEmpty())
-        pImageDict->SetStringFor("Name", "ImgA");
+        pImageDict->SetNewFor<CPDF_String>("Name", "ImgA", false);
     }
   }
 
   if (pRolloverIcon) {
     if (CPDF_Dictionary* pImageDict = pRolloverIcon->GetDict()) {
       if (pImageDict->GetStringFor("Name").IsEmpty())
-        pImageDict->SetStringFor("Name", "ImgB");
+        pImageDict->SetNewFor<CPDF_String>("Name", "ImgB", false);
     }
   }
 
   if (pDownIcon) {
     if (CPDF_Dictionary* pImageDict = pDownIcon->GetDict()) {
       if (pImageDict->GetStringFor("Name").IsEmpty())
-        pImageDict->SetStringFor("Name", "ImgC");
+        pImageDict->SetNewFor<CPDF_String>("Name", "ImgC", false);
     }
   }
 
@@ -1804,14 +1807,12 @@
 
   CPDF_Document* pDoc = m_pPageView->GetPDFDocument();
   CPDF_Dictionary* pStreamResList = pStreamDict->GetDictFor("Resources");
-  if (!pStreamResList) {
-    pStreamResList = new CPDF_Dictionary(pDoc->GetByteStringPool());
-    pStreamDict->SetFor("Resources", pStreamResList);
-  }
+  if (!pStreamResList)
+    pStreamResList = pStreamDict->SetNewFor<CPDF_Dictionary>("Resources");
 
-  CPDF_Dictionary* pXObject = new CPDF_Dictionary(pDoc->GetByteStringPool());
-  pXObject->SetReferenceFor(sImageAlias, pDoc, pImage->GetObjNum());
-  pStreamResList->SetFor("XObject", pXObject);
+  CPDF_Dictionary* pXObject =
+      pStreamResList->SetNewFor<CPDF_Dictionary>("XObject");
+  pXObject->SetNewFor<CPDF_Reference>(sImageAlias, pDoc, pImage->GetObjNum());
 }
 
 void CPDFSDK_Widget::RemoveAppearance(const CFX_ByteString& sAPType) {
diff --git a/fpdfsdk/formfiller/cba_fontmap.cpp b/fpdfsdk/formfiller/cba_fontmap.cpp
index fd9304b..83e4579 100644
--- a/fpdfsdk/formfiller/cba_fontmap.cpp
+++ b/fpdfsdk/formfiller/cba_fontmap.cpp
@@ -9,6 +9,7 @@
 #include "core/fpdfapi/font/cpdf_font.h"
 #include "core/fpdfapi/page/cpdf_page.h"
 #include "core/fpdfapi/parser/cpdf_document.h"
+#include "core/fpdfapi/parser/cpdf_reference.h"
 #include "core/fpdfapi/parser/cpdf_simple_parser.h"
 #include "core/fpdfapi/parser/cpdf_stream.h"
 #include "core/fpdfapi/parser/fpdf_parser_decode.h"
@@ -119,11 +120,10 @@
   CPDF_Font* pFind = nullptr;
   for (const auto& it : *pFonts) {
     const CFX_ByteString& csKey = it.first;
-    CPDF_Object* pObj = it.second;
-    if (!pObj)
+    if (!it.second)
       continue;
 
-    CPDF_Dictionary* pElement = ToDictionary(pObj->GetDirect());
+    CPDF_Dictionary* pElement = ToDictionary(it.second->GetDirect());
     if (!pElement)
       continue;
     if (pElement->GetStringFor("Type") != "Font")
@@ -154,10 +154,8 @@
     return;
 
   CPDF_Dictionary* pAPDict = m_pAnnotDict->GetDictFor("AP");
-  if (!pAPDict) {
-    pAPDict = new CPDF_Dictionary(m_pDocument->GetByteStringPool());
-    m_pAnnotDict->SetFor("AP", pAPDict);
-  }
+  if (!pAPDict)
+    pAPDict = m_pAnnotDict->SetNewFor<CPDF_Dictionary>("AP");
 
   // to avoid checkbox and radiobutton
   CPDF_Object* pObject = pAPDict->GetObjectFor(m_sAPType);
@@ -167,7 +165,8 @@
   CPDF_Stream* pStream = pAPDict->GetStreamFor(m_sAPType);
   if (!pStream) {
     pStream = m_pDocument->NewIndirect<CPDF_Stream>();
-    pAPDict->SetReferenceFor(m_sAPType, m_pDocument, pStream);
+    pAPDict->SetNewFor<CPDF_Reference>(m_sAPType, m_pDocument,
+                                       pStream->GetObjNum());
   }
 
   CPDF_Dictionary* pStreamDict = pStream->GetDict();
@@ -178,18 +177,17 @@
 
   if (pStreamDict) {
     CPDF_Dictionary* pStreamResList = pStreamDict->GetDictFor("Resources");
-    if (!pStreamResList) {
-      pStreamResList = new CPDF_Dictionary(m_pDocument->GetByteStringPool());
-      pStreamDict->SetFor("Resources", pStreamResList);
-    }
+    if (!pStreamResList)
+      pStreamResList = pStreamDict->SetNewFor<CPDF_Dictionary>("Resources");
     CPDF_Dictionary* pStreamResFontList = pStreamResList->GetDictFor("Font");
     if (!pStreamResFontList) {
       pStreamResFontList = m_pDocument->NewIndirect<CPDF_Dictionary>();
-      pStreamResList->SetReferenceFor("Font", m_pDocument, pStreamResFontList);
+      pStreamResList->SetNewFor<CPDF_Reference>(
+          "Font", m_pDocument, pStreamResFontList->GetObjNum());
     }
     if (!pStreamResFontList->KeyExist(sAlias)) {
-      pStreamResFontList->SetReferenceFor(sAlias, m_pDocument,
-                                          pFont->GetFontDict()->GetObjNum());
+      pStreamResFontList->SetNewFor<CPDF_Reference>(
+          sAlias, m_pDocument, pFont->GetFontDict()->GetObjNum());
     }
   }
 }
diff --git a/fpdfsdk/fpdf_flatten.cpp b/fpdfsdk/fpdf_flatten.cpp
index cb0a625..ccbb7b8 100644
--- a/fpdfsdk/fpdf_flatten.cpp
+++ b/fpdfsdk/fpdf_flatten.cpp
@@ -7,11 +7,15 @@
 #include "public/fpdf_flatten.h"
 
 #include <algorithm>
+#include <memory>
+#include <utility>
+#include <vector>
 
 #include "core/fpdfapi/page/cpdf_page.h"
 #include "core/fpdfapi/page/cpdf_pageobject.h"
 #include "core/fpdfapi/parser/cpdf_array.h"
 #include "core/fpdfapi/parser/cpdf_document.h"
+#include "core/fpdfapi/parser/cpdf_name.h"
 #include "core/fpdfapi/parser/cpdf_number.h"
 #include "core/fpdfapi/parser/cpdf_reference.h"
 #include "core/fpdfapi/parser/cpdf_stream.h"
@@ -190,8 +194,8 @@
     pContentsArray = pPage->GetArrayFor("Contents");
     if (!pContentsArray) {
       if (!key.IsEmpty()) {
-        pPage->SetReferenceFor("Contents", pDocument,
-                               NewIndirectContentsStream(key, pDocument));
+        pPage->SetNewFor<CPDF_Reference>(
+            "Contents", pDocument, NewIndirectContentsStream(key, pDocument));
       }
       return;
     }
@@ -208,7 +212,8 @@
     pContentsStream->SetData(sStream.raw_str(), sStream.GetLength());
     pContentsArray->AddNew<CPDF_Reference>(pDocument,
                                            pContentsStream->GetObjNum());
-    pPage->SetReferenceFor("Contents", pDocument, pContentsArray);
+    pPage->SetNewFor<CPDF_Reference>("Contents", pDocument,
+                                     pContentsArray->GetObjNum());
   }
   if (!key.IsEmpty()) {
     pContentsArray->AddNew<CPDF_Reference>(
@@ -271,38 +276,32 @@
     rcOriginalCB = rcOriginalMB;
 
   if (!rcOriginalMB.IsEmpty()) {
-    CPDF_Array* pMediaBox = new CPDF_Array();
+    CPDF_Array* pMediaBox = pPageDict->SetNewFor<CPDF_Array>("MediaBox");
     pMediaBox->AddNew<CPDF_Number>(rcOriginalMB.left);
     pMediaBox->AddNew<CPDF_Number>(rcOriginalMB.bottom);
     pMediaBox->AddNew<CPDF_Number>(rcOriginalMB.right);
     pMediaBox->AddNew<CPDF_Number>(rcOriginalMB.top);
-    pPageDict->SetFor("MediaBox", pMediaBox);
   }
 
   if (!rcOriginalCB.IsEmpty()) {
-    CPDF_Array* pCropBox = new CPDF_Array();
+    CPDF_Array* pCropBox = pPageDict->SetNewFor<CPDF_Array>("ArtBox");
     pCropBox->AddNew<CPDF_Number>(rcOriginalCB.left);
     pCropBox->AddNew<CPDF_Number>(rcOriginalCB.bottom);
     pCropBox->AddNew<CPDF_Number>(rcOriginalCB.right);
     pCropBox->AddNew<CPDF_Number>(rcOriginalCB.top);
-    pPageDict->SetFor("ArtBox", pCropBox);
   }
 
   CPDF_Dictionary* pRes = pPageDict->GetDictFor("Resources");
-  if (!pRes) {
-    pRes = new CPDF_Dictionary(pDocument->GetByteStringPool());
-    pPageDict->SetFor("Resources", pRes);
-  }
+  if (!pRes)
+    pRes = pPageDict->SetNewFor<CPDF_Dictionary>("Resources");
 
   CPDF_Stream* pNewXObject = pDocument->NewIndirect<CPDF_Stream>(
       nullptr, 0, new CPDF_Dictionary(pDocument->GetByteStringPool()));
 
   uint32_t dwObjNum = pNewXObject->GetObjNum();
   CPDF_Dictionary* pPageXObject = pRes->GetDictFor("XObject");
-  if (!pPageXObject) {
-    pPageXObject = new CPDF_Dictionary(pDocument->GetByteStringPool());
-    pRes->SetFor("XObject", pPageXObject);
-  }
+  if (!pPageXObject)
+    pPageXObject = pRes->SetNewFor<CPDF_Dictionary>("XObject");
 
   CFX_ByteString key = "";
   int nStreams = pdfium::CollectionSize<int>(ObjectArray);
@@ -320,14 +319,13 @@
 
   CPDF_Dictionary* pNewXORes = nullptr;
   if (!key.IsEmpty()) {
-    pPageXObject->SetReferenceFor(key, pDocument, dwObjNum);
+    pPageXObject->SetNewFor<CPDF_Reference>(key, pDocument, dwObjNum);
     CPDF_Dictionary* pNewOXbjectDic = pNewXObject->GetDict();
-    pNewXORes = new CPDF_Dictionary(pDocument->GetByteStringPool());
-    pNewOXbjectDic->SetFor("Resources", pNewXORes);
-    pNewOXbjectDic->SetNameFor("Type", "XObject");
-    pNewOXbjectDic->SetNameFor("Subtype", "Form");
-    pNewOXbjectDic->SetIntegerFor("FormType", 1);
-    pNewOXbjectDic->SetNameFor("Name", "FRM");
+    pNewXORes = pNewOXbjectDic->SetNewFor<CPDF_Dictionary>("Resources");
+    pNewOXbjectDic->SetNewFor<CPDF_Name>("Type", "XObject");
+    pNewOXbjectDic->SetNewFor<CPDF_Name>("Subtype", "Form");
+    pNewOXbjectDic->SetNewFor<CPDF_Number>("FormType", 1);
+    pNewOXbjectDic->SetNewFor<CPDF_Name>("Name", "FRM");
     CFX_FloatRect rcBBox = pPageDict->GetRectFor("ArtBox");
     pNewOXbjectDic->SetRectFor("BBox", rcBBox);
   }
@@ -356,7 +354,7 @@
       } else {
         auto it = pAPDic->begin();
         if (it != pAPDic->end()) {
-          CPDF_Object* pFirstObj = it->second;
+          CPDF_Object* pFirstObj = it->second.get();
           if (pFirstObj) {
             if (pFirstObj->IsReference())
               pFirstObj = pFirstObj->GetDirect();
@@ -389,19 +387,18 @@
 
     CPDF_Dictionary* pObjDic = pObj->GetDict();
     if (pObjDic) {
-      pObjDic->SetNameFor("Type", "XObject");
-      pObjDic->SetNameFor("Subtype", "Form");
+      pObjDic->SetNewFor<CPDF_Name>("Type", "XObject");
+      pObjDic->SetNewFor<CPDF_Name>("Subtype", "Form");
     }
 
     CPDF_Dictionary* pXObject = pNewXORes->GetDictFor("XObject");
-    if (!pXObject) {
-      pXObject = new CPDF_Dictionary(pDocument->GetByteStringPool());
-      pNewXORes->SetFor("XObject", pXObject);
-    }
+    if (!pXObject)
+      pXObject = pNewXORes->SetNewFor<CPDF_Dictionary>("XObject");
 
     CFX_ByteString sFormName;
     sFormName.Format("F%d", i);
-    pXObject->SetReferenceFor(sFormName, pDocument, pObj->GetObjNum());
+    pXObject->SetNewFor<CPDF_Reference>(sFormName, pDocument,
+                                        pObj->GetObjNum());
 
     CPDF_StreamAcc acc;
     acc.LoadAllData(pNewXObject);
diff --git a/fpdfsdk/fpdf_transformpage.cpp b/fpdfsdk/fpdf_transformpage.cpp
index beaa6c4..b1e8da0 100644
--- a/fpdfsdk/fpdf_transformpage.cpp
+++ b/fpdfsdk/fpdf_transformpage.cpp
@@ -26,12 +26,11 @@
                     float bottom,
                     float right,
                     float top) {
-  CPDF_Array* pBoundingBoxArray = new CPDF_Array;
+  CPDF_Array* pBoundingBoxArray = page->m_pFormDict->SetNewFor<CPDF_Array>(key);
   pBoundingBoxArray->AddNew<CPDF_Number>(left);
   pBoundingBoxArray->AddNew<CPDF_Number>(bottom);
   pBoundingBoxArray->AddNew<CPDF_Number>(right);
   pBoundingBoxArray->AddNew<CPDF_Number>(top);
-  page->m_pFormDict->SetFor(key, pBoundingBoxArray);
 }
 
 bool GetBoundingBox(CPDF_Page* page,
@@ -158,7 +157,8 @@
         pContentArray->AddNew<CPDF_Reference>(pDoc, pStream->GetObjNum());
         pContentArray->AddNew<CPDF_Reference>(pDoc, pDirectObj->GetObjNum());
         pContentArray->AddNew<CPDF_Reference>(pDoc, pEndStream->GetObjNum());
-        pPageDic->SetReferenceFor("Contents", pDoc, pContentArray);
+        pPageDic->SetNewFor<CPDF_Reference>("Contents", pDoc,
+                                            pContentArray->GetObjNum());
       }
     }
   }
@@ -169,7 +169,7 @@
     CPDF_Dictionary* pPattenDict = pRes->GetDictFor("Pattern");
     if (pPattenDict) {
       for (const auto& it : *pPattenDict) {
-        CPDF_Object* pObj = it.second;
+        CPDF_Object* pObj = it.second.get();
         if (pObj->IsReference())
           pObj = pObj->GetDirect();
 
@@ -328,6 +328,7 @@
     CPDF_Array* pContentArray = pDoc->NewIndirect<CPDF_Array>();
     pContentArray->AddNew<CPDF_Reference>(pDoc, pStream->GetObjNum());
     pContentArray->AddNew<CPDF_Reference>(pDoc, pDirectObj->GetObjNum());
-    pPageDic->SetReferenceFor("Contents", pDoc, pContentArray);
+    pPageDic->SetNewFor<CPDF_Reference>("Contents", pDoc,
+                                        pContentArray->GetObjNum());
   }
 }
diff --git a/fpdfsdk/fpdfdoc_unittest.cpp b/fpdfsdk/fpdfdoc_unittest.cpp
index d049b4e..664ce39 100644
--- a/fpdfsdk/fpdfdoc_unittest.cpp
+++ b/fpdfsdk/fpdfdoc_unittest.cpp
@@ -105,7 +105,7 @@
   }
   {
     // Empty bookmark tree.
-    m_pRootObj->SetFor("Outlines", new CPDF_Dictionary());
+    m_pRootObj->SetNewFor<CPDF_Dictionary>("Outlines");
     std::unique_ptr<unsigned short, pdfium::FreeDeleter> title =
         GetFPDFWideString(L"");
     EXPECT_EQ(nullptr, FPDFBookmark_Find(m_pDoc.get(), title.get()));
@@ -117,27 +117,27 @@
     // Check on a regular bookmark tree.
     auto bookmarks = CreateDictObjs(3);
 
-    bookmarks[1].obj->SetFor("Title", new CPDF_String(L"Chapter 1"));
-    bookmarks[1].obj->SetFor(
-        "Parent", new CPDF_Reference(m_pIndirectObjs, bookmarks[0].num));
-    bookmarks[1].obj->SetFor(
-        "Next", new CPDF_Reference(m_pIndirectObjs, bookmarks[2].num));
+    bookmarks[1].obj->SetNewFor<CPDF_String>("Title", L"Chapter 1");
+    bookmarks[1].obj->SetNewFor<CPDF_Reference>("Parent", m_pIndirectObjs,
+                                                bookmarks[0].num);
+    bookmarks[1].obj->SetNewFor<CPDF_Reference>("Next", m_pIndirectObjs,
+                                                bookmarks[2].num);
 
-    bookmarks[2].obj->SetFor("Title", new CPDF_String(L"Chapter 2"));
-    bookmarks[2].obj->SetFor(
-        "Parent", new CPDF_Reference(m_pIndirectObjs, bookmarks[0].num));
-    bookmarks[2].obj->SetFor(
-        "Prev", new CPDF_Reference(m_pIndirectObjs, bookmarks[1].num));
+    bookmarks[2].obj->SetNewFor<CPDF_String>("Title", L"Chapter 2");
+    bookmarks[2].obj->SetNewFor<CPDF_Reference>("Parent", m_pIndirectObjs,
+                                                bookmarks[0].num);
+    bookmarks[2].obj->SetNewFor<CPDF_Reference>("Prev", m_pIndirectObjs,
+                                                bookmarks[1].num);
 
-    bookmarks[0].obj->SetFor("Type", new CPDF_Name(nullptr, "Outlines"));
-    bookmarks[0].obj->SetFor("Count", new CPDF_Number(2));
-    bookmarks[0].obj->SetFor(
-        "First", new CPDF_Reference(m_pIndirectObjs, bookmarks[1].num));
-    bookmarks[0].obj->SetFor(
-        "Last", new CPDF_Reference(m_pIndirectObjs, bookmarks[2].num));
+    bookmarks[0].obj->SetNewFor<CPDF_Name>("Type", "Outlines");
+    bookmarks[0].obj->SetNewFor<CPDF_Number>("Count", 2);
+    bookmarks[0].obj->SetNewFor<CPDF_Reference>("First", m_pIndirectObjs,
+                                                bookmarks[1].num);
+    bookmarks[0].obj->SetNewFor<CPDF_Reference>("Last", m_pIndirectObjs,
+                                                bookmarks[2].num);
 
-    m_pRootObj->SetFor("Outlines",
-                       new CPDF_Reference(m_pIndirectObjs, bookmarks[0].num));
+    m_pRootObj->SetNewFor<CPDF_Reference>("Outlines", m_pIndirectObjs,
+                                          bookmarks[0].num);
 
     // Title with no match.
     std::unique_ptr<unsigned short, pdfium::FreeDeleter> title =
@@ -160,27 +160,27 @@
     // Circular bookmarks in depth.
     auto bookmarks = CreateDictObjs(3);
 
-    bookmarks[1].obj->SetFor("Title", new CPDF_String(L"Chapter 1"));
-    bookmarks[1].obj->SetFor(
-        "Parent", new CPDF_Reference(m_pIndirectObjs, bookmarks[0].num));
-    bookmarks[1].obj->SetFor(
-        "First", new CPDF_Reference(m_pIndirectObjs, bookmarks[2].num));
+    bookmarks[1].obj->SetNewFor<CPDF_String>("Title", L"Chapter 1");
+    bookmarks[1].obj->SetNewFor<CPDF_Reference>("Parent", m_pIndirectObjs,
+                                                bookmarks[0].num);
+    bookmarks[1].obj->SetNewFor<CPDF_Reference>("First", m_pIndirectObjs,
+                                                bookmarks[2].num);
 
-    bookmarks[2].obj->SetFor("Title", new CPDF_String(L"Chapter 2"));
-    bookmarks[2].obj->SetFor(
-        "Parent", new CPDF_Reference(m_pIndirectObjs, bookmarks[1].num));
-    bookmarks[2].obj->SetFor(
-        "First", new CPDF_Reference(m_pIndirectObjs, bookmarks[1].num));
+    bookmarks[2].obj->SetNewFor<CPDF_String>("Title", L"Chapter 2");
+    bookmarks[2].obj->SetNewFor<CPDF_Reference>("Parent", m_pIndirectObjs,
+                                                bookmarks[1].num);
+    bookmarks[2].obj->SetNewFor<CPDF_Reference>("First", m_pIndirectObjs,
+                                                bookmarks[1].num);
 
-    bookmarks[0].obj->SetFor("Type", new CPDF_Name(nullptr, "Outlines"));
-    bookmarks[0].obj->SetFor("Count", new CPDF_Number(2));
-    bookmarks[0].obj->SetFor(
-        "First", new CPDF_Reference(m_pIndirectObjs, bookmarks[1].num));
-    bookmarks[0].obj->SetFor(
-        "Last", new CPDF_Reference(m_pIndirectObjs, bookmarks[2].num));
+    bookmarks[0].obj->SetNewFor<CPDF_Name>("Type", "Outlines");
+    bookmarks[0].obj->SetNewFor<CPDF_Number>("Count", 2);
+    bookmarks[0].obj->SetNewFor<CPDF_Reference>("First", m_pIndirectObjs,
+                                                bookmarks[1].num);
+    bookmarks[0].obj->SetNewFor<CPDF_Reference>("Last", m_pIndirectObjs,
+                                                bookmarks[2].num);
 
-    m_pRootObj->SetFor("Outlines",
-                       new CPDF_Reference(m_pIndirectObjs, bookmarks[0].num));
+    m_pRootObj->SetNewFor<CPDF_Reference>("Outlines", m_pIndirectObjs,
+                                          bookmarks[0].num);
 
     // Title with no match.
     std::unique_ptr<unsigned short, pdfium::FreeDeleter> title =
@@ -195,33 +195,33 @@
     // Circular bookmarks in breadth.
     auto bookmarks = CreateDictObjs(4);
 
-    bookmarks[1].obj->SetFor("Title", new CPDF_String(L"Chapter 1"));
-    bookmarks[1].obj->SetFor(
-        "Parent", new CPDF_Reference(m_pIndirectObjs, bookmarks[0].num));
-    bookmarks[1].obj->SetFor(
-        "Next", new CPDF_Reference(m_pIndirectObjs, bookmarks[2].num));
+    bookmarks[1].obj->SetNewFor<CPDF_String>("Title", L"Chapter 1");
+    bookmarks[1].obj->SetNewFor<CPDF_Reference>("Parent", m_pIndirectObjs,
+                                                bookmarks[0].num);
+    bookmarks[1].obj->SetNewFor<CPDF_Reference>("Next", m_pIndirectObjs,
+                                                bookmarks[2].num);
 
-    bookmarks[2].obj->SetFor("Title", new CPDF_String(L"Chapter 2"));
-    bookmarks[2].obj->SetFor(
-        "Parent", new CPDF_Reference(m_pIndirectObjs, bookmarks[0].num));
-    bookmarks[2].obj->SetFor(
-        "Next", new CPDF_Reference(m_pIndirectObjs, bookmarks[3].num));
+    bookmarks[2].obj->SetNewFor<CPDF_String>("Title", L"Chapter 2");
+    bookmarks[2].obj->SetNewFor<CPDF_Reference>("Parent", m_pIndirectObjs,
+                                                bookmarks[0].num);
+    bookmarks[2].obj->SetNewFor<CPDF_Reference>("Next", m_pIndirectObjs,
+                                                bookmarks[3].num);
 
-    bookmarks[3].obj->SetFor("Title", new CPDF_String(L"Chapter 3"));
-    bookmarks[3].obj->SetFor(
-        "Parent", new CPDF_Reference(m_pIndirectObjs, bookmarks[0].num));
-    bookmarks[3].obj->SetFor(
-        "Next", new CPDF_Reference(m_pIndirectObjs, bookmarks[1].num));
+    bookmarks[3].obj->SetNewFor<CPDF_String>("Title", L"Chapter 3");
+    bookmarks[3].obj->SetNewFor<CPDF_Reference>("Parent", m_pIndirectObjs,
+                                                bookmarks[0].num);
+    bookmarks[3].obj->SetNewFor<CPDF_Reference>("Next", m_pIndirectObjs,
+                                                bookmarks[1].num);
 
-    bookmarks[0].obj->SetFor("Type", new CPDF_Name(nullptr, "Outlines"));
-    bookmarks[0].obj->SetFor("Count", new CPDF_Number(2));
-    bookmarks[0].obj->SetFor(
-        "First", new CPDF_Reference(m_pIndirectObjs, bookmarks[1].num));
-    bookmarks[0].obj->SetFor(
-        "Last", new CPDF_Reference(m_pIndirectObjs, bookmarks[2].num));
+    bookmarks[0].obj->SetNewFor<CPDF_Name>("Type", "Outlines");
+    bookmarks[0].obj->SetNewFor<CPDF_Number>("Count", 2);
+    bookmarks[0].obj->SetNewFor<CPDF_Reference>("First", m_pIndirectObjs,
+                                                bookmarks[1].num);
+    bookmarks[0].obj->SetNewFor<CPDF_Reference>("Last", m_pIndirectObjs,
+                                                bookmarks[2].num);
 
-    m_pRootObj->SetFor("Outlines",
-                       new CPDF_Reference(m_pIndirectObjs, bookmarks[0].num));
+    m_pRootObj->SetNewFor<CPDF_Reference>("Outlines", m_pIndirectObjs,
+                                          bookmarks[0].num);
 
     // Title with no match.
     std::unique_ptr<unsigned short, pdfium::FreeDeleter> title =
diff --git a/fpdfsdk/fpdfeditpage.cpp b/fpdfsdk/fpdfeditpage.cpp
index 847adac..c864b82 100644
--- a/fpdfsdk/fpdfeditpage.cpp
+++ b/fpdfsdk/fpdfeditpage.cpp
@@ -83,11 +83,9 @@
   CPDF_Dictionary* pInfoDict = nullptr;
   pInfoDict = pDoc->GetInfo();
   if (pInfoDict) {
-    if (FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS)) {
-      pInfoDict->SetFor("CreationDate",
-                        new CPDF_String(nullptr, DateStr, false));
-    }
-    pInfoDict->SetFor("Creator", new CPDF_String(L"PDFium"));
+    if (FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS))
+      pInfoDict->SetNewFor<CPDF_String>("CreationDate", DateStr, false);
+    pInfoDict->SetNewFor<CPDF_String>("Creator", L"PDFium");
   }
 
   return FPDFDocumentFromCPDFDocument(pDoc);
@@ -111,15 +109,13 @@
   if (!pPageDict)
     return nullptr;
 
-  CPDF_Array* pMediaBoxArray = new CPDF_Array;
+  CPDF_Array* pMediaBoxArray = pPageDict->SetNewFor<CPDF_Array>("MediaBox");
   pMediaBoxArray->AddNew<CPDF_Number>(0);
   pMediaBoxArray->AddNew<CPDF_Number>(0);
   pMediaBoxArray->AddNew<CPDF_Number>(static_cast<FX_FLOAT>(width));
   pMediaBoxArray->AddNew<CPDF_Number>(static_cast<FX_FLOAT>(height));
-  pPageDict->SetFor("MediaBox", pMediaBoxArray);
-  pPageDict->SetFor("Rotate", new CPDF_Number(0));
-  pPageDict->SetFor("Resources",
-                    new CPDF_Dictionary(pDoc->GetByteStringPool()));
+  pPageDict->SetNewFor<CPDF_Number>("Rotate", 0);
+  pPageDict->SetNewFor<CPDF_Dictionary>("Resources");
 
 #ifdef PDF_ENABLE_XFA
   CPDFXFA_Page* pPage =
@@ -296,10 +292,9 @@
     rect.Transform(&matrix);
 
     CPDF_Array* pRectArray = pAnnot->GetAnnotDict()->GetArrayFor("Rect");
-    if (!pRectArray) {
-      pRectArray = new CPDF_Array;
-      pAnnot->GetAnnotDict()->SetFor("Rect", pRectArray);
-    }
+    if (!pRectArray)
+      pRectArray = pAnnot->GetAnnotDict()->SetNewFor<CPDF_Array>("Rect");
+
     pRectArray->SetNewAt<CPDF_Number>(0, rect.left);
     pRectArray->SetNewAt<CPDF_Number>(1, rect.bottom);
     pRectArray->SetNewAt<CPDF_Number>(2, rect.right);
@@ -316,5 +311,5 @@
 
   CPDF_Dictionary* pDict = pPage->m_pFormDict;
   rotate %= 4;
-  pDict->SetFor("Rotate", new CPDF_Number(rotate * 90));
+  pDict->SetNewFor<CPDF_Number>("Rotate", rotate * 90);
 }
diff --git a/fpdfsdk/fpdfppo.cpp b/fpdfsdk/fpdfppo.cpp
index 915de1a..4e06856 100644
--- a/fpdfsdk/fpdfppo.cpp
+++ b/fpdfsdk/fpdfppo.cpp
@@ -8,6 +8,7 @@
 
 #include <map>
 #include <memory>
+#include <utility>
 #include <vector>
 
 #include "core/fpdfapi/parser/cpdf_array.h"
@@ -64,7 +65,7 @@
   if (!pInheritable)
     return false;
 
-  pCurPageDict->SetFor(key, pInheritable->Clone().release());
+  pCurPageDict->SetFor(key, pInheritable->Clone());
   return true;
 }
 
@@ -158,31 +159,30 @@
   if (!pDocInfoDict)
     return false;
 
-  CFX_ByteString producerstr;
-  producerstr.Format("PDFium");
-  pDocInfoDict->SetFor("Producer",
-                       new CPDF_String(nullptr, producerstr, false));
+  pDocInfoDict->SetNewFor<CPDF_String>("Producer", "PDFium", false);
 
   CFX_ByteString cbRootType = pNewRoot->GetStringFor("Type", "");
   if (cbRootType.IsEmpty())
-    pNewRoot->SetFor("Type", new CPDF_Name(nullptr, "Catalog"));
+    pNewRoot->SetNewFor<CPDF_Name>("Type", "Catalog");
 
   CPDF_Object* pElement = pNewRoot->GetObjectFor("Pages");
   CPDF_Dictionary* pNewPages =
       pElement ? ToDictionary(pElement->GetDirect()) : nullptr;
   if (!pNewPages) {
     pNewPages = m_pDestPDFDoc->NewIndirect<CPDF_Dictionary>();
-    pNewRoot->SetReferenceFor("Pages", m_pDestPDFDoc, pNewPages);
+    pNewRoot->SetNewFor<CPDF_Reference>("Pages", m_pDestPDFDoc,
+                                        pNewPages->GetObjNum());
   }
 
   CFX_ByteString cbPageType = pNewPages->GetStringFor("Type", "");
   if (cbPageType.IsEmpty())
-    pNewPages->SetFor("Type", new CPDF_Name(nullptr, "Pages"));
+    pNewPages->SetNewFor<CPDF_Name>("Type", "Pages");
 
   if (!pNewPages->GetArrayFor("Kids")) {
-    pNewPages->SetIntegerFor("Count", 0);
-    pNewPages->SetReferenceFor("Kids", m_pDestPDFDoc,
-                               m_pDestPDFDoc->NewIndirect<CPDF_Array>());
+    pNewPages->SetNewFor<CPDF_Number>("Count", 0);
+    pNewPages->SetNewFor<CPDF_Reference>(
+        "Kids", m_pDestPDFDoc,
+        m_pDestPDFDoc->NewIndirect<CPDF_Array>()->GetObjNum());
   }
 
   return true;
@@ -202,11 +202,11 @@
     // Clone the page dictionary
     for (const auto& it : *pSrcPageDict) {
       const CFX_ByteString& cbSrcKeyStr = it.first;
-      CPDF_Object* pObj = it.second;
       if (cbSrcKeyStr == "Type" || cbSrcKeyStr == "Parent")
         continue;
 
-      pCurPageDict->SetFor(cbSrcKeyStr, pObj->Clone().release());
+      CPDF_Object* pObj = it.second.get();
+      pCurPageDict->SetFor(cbSrcKeyStr, pObj->Clone());
     }
 
     // inheritable item
@@ -217,15 +217,14 @@
       CPDF_Object* pInheritable =
           PageDictGetInheritableTag(pSrcPageDict, "CropBox");
       if (pInheritable) {
-        pCurPageDict->SetFor("MediaBox", pInheritable->Clone().release());
+        pCurPageDict->SetFor("MediaBox", pInheritable->Clone());
       } else {
         // Make the default size to be letter size (8.5'x11')
-        CPDF_Array* pArray = new CPDF_Array;
+        CPDF_Array* pArray = pCurPageDict->SetNewFor<CPDF_Array>("MediaBox");
         pArray->AddNew<CPDF_Number>(0);
         pArray->AddNew<CPDF_Number>(0);
         pArray->AddNew<CPDF_Number>(612);
         pArray->AddNew<CPDF_Number>(792);
-        pCurPageDict->SetFor("MediaBox", pArray);
       }
     }
 
@@ -265,7 +264,7 @@
       auto it = pDict->begin();
       while (it != pDict->end()) {
         const CFX_ByteString& key = it->first;
-        CPDF_Object* pNextObj = it->second;
+        CPDF_Object* pNextObj = it->second.get();
         ++it;
         if (key == "Parent" || key == "Prev" || key == "First")
           continue;
@@ -386,7 +385,6 @@
   if (!pDstDict)
     return false;
 
-  pDstDict->SetFor("ViewerPreferences",
-                   pSrcDict->CloneDirectObject().release());
+  pDstDict->SetFor("ViewerPreferences", pSrcDict->CloneDirectObject());
   return true;
 }
diff --git a/fpdfsdk/fpdfview.cpp b/fpdfsdk/fpdfview.cpp
index 334c14c..d5f9a0e 100644
--- a/fpdfsdk/fpdfview.cpp
+++ b/fpdfsdk/fpdfview.cpp
@@ -1082,7 +1082,7 @@
     int i = 0;
     for (const auto& it : *pDest) {
       bsName = it.first;
-      pDestObj = it.second;
+      pDestObj = it.second.get();
       if (!pDestObj)
         continue;
       if (i == index)
diff --git a/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.cpp b/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.cpp
index 26227c0..9bb1418 100644
--- a/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.cpp
+++ b/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.cpp
@@ -6,6 +6,8 @@
 
 #include "fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.h"
 
+#include <memory>
+
 #include "core/fpdfapi/parser/cpdf_array.h"
 #include "core/fpdfapi/parser/cpdf_stream_acc.h"
 #include "core/fpdfapi/parser/cpdf_string.h"
@@ -398,7 +400,7 @@
     return;
 
   if (CPDF_Dictionary* pInfoDict = m_pContext->GetPDFDoc()->GetInfo())
-    pInfoDict->SetFor("Title", new CPDF_String(wsTitle));
+    pInfoDict->SetNewFor<CPDF_String>("Title", wsTitle);
 }
 
 void CPDFXFA_DocEnvironment::ExportData(CXFA_FFDoc* hDoc,
diff --git a/fpdfsdk/javascript/Document.cpp b/fpdfsdk/javascript/Document.cpp
index 54761a2..29f9764 100644
--- a/fpdfsdk/javascript/Document.cpp
+++ b/fpdfsdk/javascript/Document.cpp
@@ -13,6 +13,7 @@
 #include "core/fpdfapi/page/cpdf_page.h"
 #include "core/fpdfapi/parser/cpdf_array.h"
 #include "core/fpdfapi/parser/cpdf_document.h"
+#include "core/fpdfapi/parser/cpdf_string.h"
 #include "core/fpdfapi/parser/fpdf_parser_decode.h"
 #include "core/fpdfdoc/cpdf_interform.h"
 #include "core/fpdfdoc/cpdf_nametree.h"
@@ -809,7 +810,7 @@
   // It's to be compatible to non-standard info dictionary.
   for (const auto& it : *pDictionary) {
     const CFX_ByteString& bsKey = it.first;
-    CPDF_Object* pValueObj = it.second;
+    CPDF_Object* pValueObj = it.second.get();
     CFX_WideString wsKey = CFX_WideString::FromUTF8(bsKey.AsStringC());
     if (pValueObj->IsString() || pValueObj->IsName()) {
       pRuntime->PutObjectString(pObj, wsKey, pValueObj->GetUnicodeText());
@@ -844,7 +845,8 @@
     }
     CFX_WideString csProperty;
     vp >> csProperty;
-    pDictionary->SetStringFor(propName, PDF_EncodeText(csProperty));
+    pDictionary->SetNewFor<CPDF_String>(propName, PDF_EncodeText(csProperty),
+                                        false);
     m_pFormFillEnv->SetChangeMark();
   }
   return true;
diff --git a/testing/libfuzzer/pdf_hint_table_fuzzer.cc b/testing/libfuzzer/pdf_hint_table_fuzzer.cc
index 15e04d9..b31d56e 100644
--- a/testing/libfuzzer/pdf_hint_table_fuzzer.cc
+++ b/testing/libfuzzer/pdf_hint_table_fuzzer.cc
@@ -5,6 +5,7 @@
 #include <cstdint>
 
 #include "core/fpdfapi/parser/cpdf_array.h"
+#include "core/fpdfapi/parser/cpdf_boolean.h"
 #include "core/fpdfapi/parser/cpdf_dictionary.h"
 #include "core/fpdfapi/parser/cpdf_hint_tables.h"
 #include "core/fpdfapi/parser/cpdf_linearized_header.h"
@@ -62,15 +63,15 @@
 
   auto linearized_dict = pdfium::MakeUnique<CPDF_Dictionary>();
   // Set initial value.
-  linearized_dict->SetBooleanFor("Linearized", true);
+  linearized_dict->SetNewFor<CPDF_Boolean>("Linearized", true);
   // Set first page end offset
-  linearized_dict->SetIntegerFor("E", GetData(&data32, &data, &size));
+  linearized_dict->SetNewFor<CPDF_Number>("E", GetData(&data32, &data, &size));
   // Set page count
-  linearized_dict->SetIntegerFor("N", GetData(&data32, &data, &size));
+  linearized_dict->SetNewFor<CPDF_Number>("N", GetData(&data32, &data, &size));
   // Set first page obj num
-  linearized_dict->SetIntegerFor("O", GetData(&data32, &data, &size));
+  linearized_dict->SetNewFor<CPDF_Number>("O", GetData(&data32, &data, &size));
   // Set first page no
-  linearized_dict->SetIntegerFor("P", GetData(&data32, &data, &size));
+  linearized_dict->SetNewFor<CPDF_Number>("P", GetData(&data32, &data, &size));
 
   auto hint_info = pdfium::MakeUnique<CPDF_Array>();
   // Add primary hint stream offset
@@ -78,7 +79,7 @@
   // Add primary hint stream size
   hint_info->AddNew<CPDF_Number>(GetData(&data32, &data, &size));
   // Set hint stream info.
-  linearized_dict->SetFor("H", hint_info.release());
+  linearized_dict->SetFor("H", std::move(hint_info));
 
   const int shared_hint_table_offset = GetData(&data32, &data, &size);
 
diff --git a/xfa/fxfa/app/xfa_fontmgr.cpp b/xfa/fxfa/app/xfa_fontmgr.cpp
index ddac27d5..857c1d5 100644
--- a/xfa/fxfa/app/xfa_fontmgr.cpp
+++ b/xfa/fxfa/app/xfa_fontmgr.cpp
@@ -1839,7 +1839,7 @@
   CFGAS_FontMgr* pFDEFontMgr = m_pDoc->GetApp()->GetFDEFontMgr();
   for (const auto& it : *pFontSetDict) {
     const CFX_ByteString& key = it.first;
-    CPDF_Object* pObj = it.second;
+    CPDF_Object* pObj = it.second.get();
     if (!PsNameMatchDRFontName(name.AsStringC(), bBold, bItalic, key,
                                bStrictMatch)) {
       continue;