Make CPDF_Array take unique_ptrs

BUG=

Review-Url: https://codereview.chromium.org/2498223005
diff --git a/core/fpdfapi/edit/fpdf_edit_create.cpp b/core/fpdfapi/edit/fpdf_edit_create.cpp
index c823ab0..ff12606 100644
--- a/core/fpdfapi/edit/fpdf_edit_create.cpp
+++ b/core/fpdfapi/edit/fpdf_edit_create.cpp
@@ -1931,12 +1931,12 @@
     m_pIDArray.reset(new CPDF_Array);
     CPDF_Object* pID1 = pOldIDArray ? pOldIDArray->GetObjectAt(0) : nullptr;
     if (pID1) {
-      m_pIDArray->Add(pID1->Clone().release());
+      m_pIDArray->Add(pID1->Clone());
     } else {
       std::vector<uint8_t> buffer =
           PDF_GenerateFileID((uint32_t)(uintptr_t) this, m_dwLastObjNum);
       CFX_ByteString bsBuffer(buffer.data(), buffer.size());
-      m_pIDArray->Add(new CPDF_String(bsBuffer, true));
+      m_pIDArray->AddNew<CPDF_String>(bsBuffer, true);
     }
   }
   if (!bDefault) {
@@ -1945,21 +1945,20 @@
   if (pOldIDArray) {
     CPDF_Object* pID2 = pOldIDArray->GetObjectAt(1);
     if ((m_dwFlags & FPDFCREATE_INCREMENTAL) && m_pEncryptDict && pID2) {
-      m_pIDArray->Add(pID2->Clone().release());
+      m_pIDArray->Add(pID2->Clone());
       return;
     }
     std::vector<uint8_t> buffer =
         PDF_GenerateFileID((uint32_t)(uintptr_t) this, m_dwLastObjNum);
     CFX_ByteString bsBuffer(buffer.data(), buffer.size());
-    m_pIDArray->Add(new CPDF_String(bsBuffer, true));
+    m_pIDArray->AddNew<CPDF_String>(bsBuffer, true);
     return;
   }
-  m_pIDArray->Add(m_pIDArray->GetObjectAt(0)->Clone().release());
+  m_pIDArray->Add(m_pIDArray->GetObjectAt(0)->Clone());
   if (m_pEncryptDict && !pOldIDArray && m_pParser && bNewId) {
     if (m_pEncryptDict->GetStringFor("Filter") == "Standard") {
       CFX_ByteString user_pass = m_pParser->GetPassword();
       uint32_t flag = PDF_ENCRYPT_CONTENT;
-
       CPDF_SecurityHandler handler;
       handler.OnCreate(m_pEncryptDict, m_pIDArray.get(), user_pass.raw_str(),
                        user_pass.GetLength(), flag);
diff --git a/core/fpdfapi/font/cpdf_fontencoding.cpp b/core/fpdfapi/font/cpdf_fontencoding.cpp
index fba35a1..3537330 100644
--- a/core/fpdfapi/font/cpdf_fontencoding.cpp
+++ b/core/fpdfapi/font/cpdf_fontencoding.cpp
@@ -1703,11 +1703,11 @@
       PDF_UnicodesForPredefinedCharSet(PDFFONT_ENCODING_WINANSI);
   CPDF_Array* pDiff = new CPDF_Array;
   for (int i = 0; i < 256; i++) {
-    if (pStandard[i] == m_Unicodes[i]) {
+    if (pStandard[i] == m_Unicodes[i])
       continue;
-    }
-    pDiff->Add(new CPDF_Number(i));
-    pDiff->Add(new CPDF_Name(PDF_AdobeNameFromUnicode(m_Unicodes[i])));
+
+    pDiff->AddNew<CPDF_Number>(i);
+    pDiff->AddNew<CPDF_Name>(PDF_AdobeNameFromUnicode(m_Unicodes[i]));
   }
 
   CPDF_Dictionary* pDict = new CPDF_Dictionary(pPool);
diff --git a/core/fpdfapi/page/cpdf_image.cpp b/core/fpdfapi/page/cpdf_image.cpp
index e21d38a..1c3aa89 100644
--- a/core/fpdfapi/page/cpdf_image.cpp
+++ b/core/fpdfapi/page/cpdf_image.cpp
@@ -17,6 +17,9 @@
 #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_string.h"
 #include "core/fpdfapi/render/cpdf_pagerendercache.h"
 #include "core/fpdfapi/render/render_int.h"
@@ -107,8 +110,8 @@
     csname = "DeviceCMYK";
     CPDF_Array* pDecode = new CPDF_Array;
     for (int n = 0; n < 4; n++) {
-      pDecode->AddInteger(1);
-      pDecode->AddInteger(0);
+      pDecode->AddNew<CPDF_Number>(1);
+      pDecode->AddNew<CPDF_Number>(0);
     }
     pDict->SetFor("Decode", pDecode);
   }
@@ -181,15 +184,15 @@
       pDict->SetFor("ImageMask", new CPDF_Boolean(true));
       if (reset_a == 0) {
         CPDF_Array* pArray = new CPDF_Array;
-        pArray->AddInteger(1);
-        pArray->AddInteger(0);
+        pArray->AddNew<CPDF_Number>(1);
+        pArray->AddNew<CPDF_Number>(0);
         pDict->SetFor("Decode", pArray);
       }
     } else {
       CPDF_Array* pCS = new CPDF_Array;
-      pCS->AddName("Indexed");
-      pCS->AddName("DeviceRGB");
-      pCS->AddInteger(1);
+      pCS->AddNew<CPDF_Name>("Indexed");
+      pCS->AddNew<CPDF_Name>("DeviceRGB");
+      pCS->AddNew<CPDF_Number>(1);
       CFX_ByteString ct;
       FX_CHAR* pBuf = ct.GetBuffer(6);
       pBuf[0] = (FX_CHAR)reset_r;
@@ -199,7 +202,7 @@
       pBuf[4] = (FX_CHAR)set_g;
       pBuf[5] = (FX_CHAR)set_b;
       ct.ReleaseBuffer(6);
-      pCS->Add(new CPDF_String(ct, true));
+      pCS->AddNew<CPDF_String>(ct, true);
       pDict->SetFor("ColorSpace", pCS);
     }
     pDict->SetIntegerFor("BitsPerComponent", 1);
@@ -213,9 +216,9 @@
     int32_t iPalette = pBitmap->GetPaletteSize();
     if (iPalette > 0) {
       CPDF_Array* pCS = m_pDocument->NewIndirect<CPDF_Array>();
-      pCS->AddName("Indexed");
-      pCS->AddName("DeviceRGB");
-      pCS->AddInteger(iPalette - 1);
+      pCS->AddNew<CPDF_Name>("Indexed");
+      pCS->AddNew<CPDF_Name>("DeviceRGB");
+      pCS->AddNew<CPDF_Number>(iPalette - 1);
       uint8_t* pColorTable = FX_Alloc2D(uint8_t, iPalette, 3);
       uint8_t* ptr = pColorTable;
       for (int32_t i = 0; i < iPalette; i++) {
@@ -228,7 +231,7 @@
       CPDF_Stream* pCTS = m_pDocument->NewIndirect<CPDF_Stream>(
           pColorTable, iPalette * 3,
           new CPDF_Dictionary(m_pDocument->GetByteStringPool()));
-      pCS->AddReference(m_pDocument, pCTS);
+      pCS->AddNew<CPDF_Reference>(m_pDocument, pCTS->GetObjNum());
       pDict->SetReferenceFor("ColorSpace", m_pDocument, pCS);
     } else {
       pDict->SetNameFor("ColorSpace", "DeviceGray");
diff --git a/core/fpdfapi/page/cpdf_streamcontentparser.cpp b/core/fpdfapi/page/cpdf_streamcontentparser.cpp
index 69b2b7e..5ef47bc 100644
--- a/core/fpdfapi/page/cpdf_streamcontentparser.cpp
+++ b/core/fpdfapi/page/cpdf_streamcontentparser.cpp
@@ -216,7 +216,7 @@
           CFX_ByteStringC fullname = FindFullName(
               InlineValueAbbr, FX_ArraySize(InlineValueAbbr), name.AsStringC());
           if (!fullname.IsEmpty())
-            pArray->SetAt(i, new CPDF_Name(CFX_ByteString(fullname)));
+            pArray->SetNewAt<CPDF_Name>(i, CFX_ByteString(fullname));
         } else {
           ReplaceAbbr(pElement);
         }
diff --git a/core/fpdfapi/page/cpdf_streamparser.cpp b/core/fpdfapi/page/cpdf_streamparser.cpp
index 9d36d0a..b149f1f 100644
--- a/core/fpdfapi/page/cpdf_streamparser.cpp
+++ b/core/fpdfapi/page/cpdf_streamparser.cpp
@@ -385,10 +385,9 @@
     while (1) {
       CPDF_Object* pObj = ReadNextObject(bAllowNestedArray, dwInArrayLevel + 1);
       if (pObj) {
-        pArray->Add(pObj);
+        pArray->Add(pdfium::WrapUnique(pObj));
         continue;
       }
-
       if (!m_WordSize || m_WordBuffer[0] == ']')
         break;
     }
diff --git a/core/fpdfapi/parser/cpdf_array.cpp b/core/fpdfapi/parser/cpdf_array.cpp
index f8ec46a..3edb3bb 100644
--- a/core/fpdfapi/parser/cpdf_array.cpp
+++ b/core/fpdfapi/parser/cpdf_array.cpp
@@ -19,12 +19,11 @@
 CPDF_Array::CPDF_Array() {}
 
 CPDF_Array::~CPDF_Array() {
-  // Mark the object as deleted so that it will not be deleted again
-  // in case of cyclic references.
+  // Break cycles for cyclic references.
   m_ObjNum = kInvalidObjNum;
   for (auto& it : m_Objects) {
-    if (it && it->GetObjNum() != kInvalidObjNum)
-      delete it;
+    if (it && it->GetObjNum() == kInvalidObjNum)
+      it.release();
   }
 }
 
@@ -53,11 +52,9 @@
     std::set<const CPDF_Object*>* pVisited) const {
   pVisited->insert(this);
   auto pCopy = pdfium::MakeUnique<CPDF_Array>();
-  for (CPDF_Object* value : m_Objects) {
-    if (!pdfium::ContainsKey(*pVisited, value)) {
-      pCopy->m_Objects.push_back(
-          value->CloneNonCyclic(bDirect, pVisited).release());
-    }
+  for (const auto& pValue : m_Objects) {
+    if (!pdfium::ContainsKey(*pVisited, pValue.get()))
+      pCopy->m_Objects.push_back(pValue->CloneNonCyclic(bDirect, pVisited));
   }
   return std::move(pCopy);
 }
@@ -87,7 +84,7 @@
 CPDF_Object* CPDF_Array::GetObjectAt(size_t i) const {
   if (i >= m_Objects.size())
     return nullptr;
-  return m_Objects[i];
+  return m_Objects[i].get();
 }
 
 CPDF_Object* CPDF_Array::GetDirectObjectAt(size_t i) const {
@@ -140,9 +137,6 @@
   if (nCount <= 0 || nCount > m_Objects.size() - i)
     return;
 
-  for (size_t j = 0; j < nCount; ++j)
-    delete m_Objects[i + j];
-
   m_Objects.erase(m_Objects.begin() + i, m_Objects.begin() + i + nCount);
 }
 
@@ -151,67 +145,45 @@
   if (i >= m_Objects.size())
     return;
 
-  CPDF_Object* pObj = m_Objects[i];
-  if (!pObj || pObj->IsReference())
+  if (!m_Objects[i] || m_Objects[i]->IsReference())
     return;
 
-  CPDF_Object* pNew = pHolder->AddIndirectObject(pdfium::WrapUnique(pObj));
-  m_Objects[i] = new CPDF_Reference(pHolder, pNew->GetObjNum());
+  CPDF_Object* pNew = pHolder->AddIndirectObject(std::move(m_Objects[i]));
+  m_Objects[i] = pdfium::MakeUnique<CPDF_Reference>(pHolder, pNew->GetObjNum());
 }
 
-void CPDF_Array::SetAt(size_t i, CPDF_Object* pObj) {
+CPDF_Object* CPDF_Array::SetAt(size_t i, std::unique_ptr<CPDF_Object> pObj) {
   ASSERT(IsArray());
-  CHECK(!pObj || pObj->IsInline());
+  ASSERT(!pObj || pObj->IsInline());
   if (i >= m_Objects.size()) {
     ASSERT(false);
-    return;
+    return nullptr;
   }
-  delete m_Objects[i];
-  m_Objects[i] = pObj;
+  CPDF_Object* pRet = pObj.get();
+  m_Objects[i] = std::move(pObj);
+  return pRet;
 }
 
-void CPDF_Array::InsertAt(size_t index, CPDF_Object* pObj) {
+CPDF_Object* CPDF_Array::InsertAt(size_t index,
+                                  std::unique_ptr<CPDF_Object> pObj) {
   ASSERT(IsArray());
   CHECK(!pObj || pObj->IsInline());
+  CPDF_Object* pRet = pObj.get();
   if (index >= m_Objects.size()) {
     // Allocate space first.
-    m_Objects.resize(index + 1, nullptr);
-    m_Objects[index] = pObj;
+    m_Objects.resize(index + 1);
+    m_Objects[index] = std::move(pObj);
   } else {
     // Directly insert.
-    m_Objects.insert(m_Objects.begin() + index, pObj);
+    m_Objects.insert(m_Objects.begin() + index, std::move(pObj));
   }
+  return pRet;
 }
 
-void CPDF_Array::Add(CPDF_Object* pObj) {
+CPDF_Object* CPDF_Array::Add(std::unique_ptr<CPDF_Object> pObj) {
   ASSERT(IsArray());
   CHECK(!pObj || pObj->IsInline());
-  m_Objects.push_back(pObj);
-}
-
-void CPDF_Array::AddName(const CFX_ByteString& str) {
-  Add(new CPDF_Name(str));
-}
-
-void CPDF_Array::AddString(const CFX_ByteString& str) {
-  Add(new CPDF_String(str, false));
-}
-
-void CPDF_Array::AddInteger(int i) {
-  Add(new CPDF_Number(i));
-}
-
-void CPDF_Array::AddNumber(FX_FLOAT f) {
-  Add(new CPDF_Number(f));
-}
-
-void CPDF_Array::AddReference(CPDF_IndirectObjectHolder* pDoc,
-                              uint32_t objnum) {
-  Add(new CPDF_Reference(pDoc, objnum));
-}
-
-void CPDF_Array::AddReference(CPDF_IndirectObjectHolder* pDoc,
-                              CPDF_Object* pObj) {
-  ASSERT(!pObj->IsInline());
-  Add(new CPDF_Reference(pDoc, pObj->GetObjNum()));
+  CPDF_Object* pRet = pObj.get();
+  m_Objects.push_back(std::move(pObj));
+  return pRet;
 }
diff --git a/core/fpdfapi/parser/cpdf_array.h b/core/fpdfapi/parser/cpdf_array.h
index bf4b8a6..b7aec7e 100644
--- a/core/fpdfapi/parser/cpdf_array.h
+++ b/core/fpdfapi/parser/cpdf_array.h
@@ -7,6 +7,7 @@
 #ifndef CORE_FPDFAPI_PARSER_CPDF_ARRAY_H_
 #define CORE_FPDFAPI_PARSER_CPDF_ARRAY_H_
 
+#include <memory>
 #include <set>
 #include <vector>
 
@@ -14,11 +15,12 @@
 #include "core/fpdfapi/parser/cpdf_object.h"
 #include "core/fxcrt/fx_basic.h"
 #include "core/fxcrt/fx_coordinates.h"
+#include "third_party/base/ptr_util.h"
 
 class CPDF_Array : public CPDF_Object {
  public:
-  using iterator = std::vector<CPDF_Object*>::iterator;
-  using const_iterator = std::vector<CPDF_Object*>::const_iterator;
+  using const_iterator =
+      std::vector<std::unique_ptr<CPDF_Object>>::const_iterator;
 
   CPDF_Array();
   ~CPDF_Array() override;
@@ -44,21 +46,28 @@
   CFX_Matrix GetMatrix();
   CFX_FloatRect GetRect();
 
-  void SetAt(size_t index, CPDF_Object* pObj);
-  void InsertAt(size_t index, CPDF_Object* pObj);
+  // Takes ownership of |pObj|, returns unowned pointer to it.
+  CPDF_Object* Add(std::unique_ptr<CPDF_Object> pObj);
+  CPDF_Object* SetAt(size_t index, std::unique_ptr<CPDF_Object> pObj);
+  CPDF_Object* InsertAt(size_t index, std::unique_ptr<CPDF_Object> pObj);
+
+  // Creates object owned by the array, returns unowned pointer to it.
+  template <typename T, typename... Args>
+  T* AddNew(Args... args) {
+    return static_cast<T*>(Add(pdfium::MakeUnique<T>(args...)));
+  }
+  template <typename T, typename... Args>
+  T* SetNewAt(size_t index, Args... args) {
+    return static_cast<T*>(SetAt(index, pdfium::MakeUnique<T>(args...)));
+  }
+  template <typename T, typename... Args>
+  T* InsertNewAt(size_t index, Args... args) {
+    return static_cast<T*>(InsertAt(index, pdfium::MakeUnique<T>(args...)));
+  }
+
   void RemoveAt(size_t index, size_t nCount = 1);
   void ConvertToIndirectObjectAt(size_t index, CPDF_IndirectObjectHolder* pDoc);
 
-  void Add(CPDF_Object* pObj);
-  void AddNumber(FX_FLOAT f);
-  void AddInteger(int i);
-  void AddString(const CFX_ByteString& str);
-  void AddName(const CFX_ByteString& str);
-  void AddReference(CPDF_IndirectObjectHolder* pDoc, uint32_t objnum);
-  void AddReference(CPDF_IndirectObjectHolder* pDoc, CPDF_Object* pObj);
-
-  iterator begin() { return m_Objects.begin(); }
-  iterator end() { return m_Objects.end(); }
   const_iterator begin() const { return m_Objects.begin(); }
   const_iterator end() const { return m_Objects.end(); }
 
@@ -67,7 +76,7 @@
       bool bDirect,
       std::set<const CPDF_Object*>* pVisited) const override;
 
-  std::vector<CPDF_Object*> m_Objects;
+  std::vector<std::unique_ptr<CPDF_Object>> m_Objects;
 };
 
 inline CPDF_Array* ToArray(CPDF_Object* obj) {
diff --git a/core/fpdfapi/parser/cpdf_array_unittest.cpp b/core/fpdfapi/parser/cpdf_array_unittest.cpp
index acb1bd8..866e961 100644
--- a/core/fpdfapi/parser/cpdf_array_unittest.cpp
+++ b/core/fpdfapi/parser/cpdf_array_unittest.cpp
@@ -16,7 +16,7 @@
     int elems[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
     std::unique_ptr<CPDF_Array> arr(new CPDF_Array);
     for (size_t i = 0; i < FX_ArraySize(elems); ++i)
-      arr->AddInteger(elems[i]);
+      arr->AddNew<CPDF_Number>(elems[i]);
     arr->RemoveAt(3, 3);
     int expected[] = {1, 2, 3, 7, 8, 9, 10};
     EXPECT_EQ(FX_ArraySize(expected), arr->GetCount());
@@ -33,7 +33,7 @@
     int elems[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
     std::unique_ptr<CPDF_Array> arr(new CPDF_Array);
     for (size_t i = 0; i < FX_ArraySize(elems); ++i)
-      arr->AddInteger(elems[i]);
+      arr->AddNew<CPDF_Number>(elems[i]);
     arr->RemoveAt(8, 5);
     EXPECT_EQ(FX_ArraySize(elems), arr->GetCount());
     for (size_t i = 0; i < FX_ArraySize(elems); ++i)
@@ -48,15 +48,15 @@
 TEST(cpdf_array, InsertAt) {
   {
     int elems[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
-    std::unique_ptr<CPDF_Array> arr(new CPDF_Array);
+    auto arr = pdfium::MakeUnique<CPDF_Array>();
     for (size_t i = 0; i < FX_ArraySize(elems); ++i)
-      arr->InsertAt(i, new CPDF_Number(elems[i]));
+      arr->InsertNewAt<CPDF_Number>(i, elems[i]);
     EXPECT_EQ(FX_ArraySize(elems), arr->GetCount());
     for (size_t i = 0; i < FX_ArraySize(elems); ++i)
       EXPECT_EQ(elems[i], arr->GetIntegerAt(i));
-    arr->InsertAt(3, new CPDF_Number(33));
-    arr->InsertAt(6, new CPDF_Number(55));
-    arr->InsertAt(12, new CPDF_Number(12));
+    arr->InsertNewAt<CPDF_Number>(3, 33);
+    arr->InsertNewAt<CPDF_Number>(6, 55);
+    arr->InsertNewAt<CPDF_Number>(12, 12);
     int expected[] = {1, 2, 3, 33, 4, 5, 55, 6, 7, 8, 9, 10, 12};
     EXPECT_EQ(FX_ArraySize(expected), arr->GetCount());
     for (size_t i = 0; i < FX_ArraySize(expected); ++i)
@@ -67,10 +67,10 @@
     // an element is inserted at that position while other unfilled
     // positions have nullptr.
     int elems[] = {1, 2};
-    std::unique_ptr<CPDF_Array> arr(new CPDF_Array);
+    auto arr = pdfium::MakeUnique<CPDF_Array>();
     for (size_t i = 0; i < FX_ArraySize(elems); ++i)
-      arr->InsertAt(i, new CPDF_Number(elems[i]));
-    arr->InsertAt(10, new CPDF_Number(10));
+      arr->InsertNewAt<CPDF_Number>(i, elems[i]);
+    arr->InsertNewAt<CPDF_Number>(10, 10);
     EXPECT_EQ(11u, arr->GetCount());
     for (size_t i = 0; i < FX_ArraySize(elems); ++i)
       EXPECT_EQ(elems[i], arr->GetIntegerAt(i));
@@ -84,9 +84,9 @@
   {
     // Basic case.
     int elems[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
-    std::unique_ptr<CPDF_Array> arr(new CPDF_Array);
+    auto arr = pdfium::MakeUnique<CPDF_Array>();
     for (size_t i = 0; i < FX_ArraySize(elems); ++i)
-      arr->InsertAt(i, new CPDF_Number(elems[i]));
+      arr->InsertNewAt<CPDF_Number>(i, elems[i]);
     std::unique_ptr<CPDF_Array> arr2 = ToArray(arr->Clone());
     EXPECT_EQ(arr->GetCount(), arr2->GetCount());
     for (size_t i = 0; i < FX_ArraySize(elems); ++i) {
@@ -106,16 +106,16 @@
     std::unique_ptr<CPDF_IndirectObjectHolder> obj_holder(
         new CPDF_IndirectObjectHolder());
     for (size_t i = 0; i < kNumOfRows; ++i) {
-      CPDF_Array* arr_elem = new CPDF_Array;
+      auto arr_elem = pdfium::MakeUnique<CPDF_Array>();
       for (size_t j = 0; j < kNumOfRowElems; ++j) {
         std::unique_ptr<CPDF_Number> obj(new CPDF_Number(elems[i][j]));
         // Starts object number from 1.
         int obj_num = i * kNumOfRowElems + j + 1;
         obj_holder->ReplaceIndirectObjectIfHigherGeneration(obj_num,
                                                             std::move(obj));
-        arr_elem->InsertAt(j, new CPDF_Reference(obj_holder.get(), obj_num));
+        arr_elem->InsertNewAt<CPDF_Reference>(j, obj_holder.get(), obj_num);
       }
-      arr->InsertAt(i, arr_elem);
+      arr->InsertAt(i, std::move(arr_elem));
     }
     ASSERT_EQ(kNumOfRows, arr->GetCount());
     // Not dereferencing reference objects means just creating new references
@@ -169,7 +169,7 @@
                  0,   7895330, -12564334, 10000, -100000};
   std::unique_ptr<CPDF_Array> arr(new CPDF_Array);
   for (size_t i = 0; i < FX_ArraySize(elems); ++i)
-    arr->InsertAt(i, new CPDF_Number(elems[i]));
+    arr->InsertNewAt<CPDF_Number>(i, elems[i]);
   size_t index = 0;
   for (const auto& it : *arr)
     EXPECT_EQ(elems[index++], it->AsNumber()->GetInteger());
diff --git a/core/fpdfapi/parser/cpdf_data_avail.cpp b/core/fpdfapi/parser/cpdf_data_avail.cpp
index c1d17a9..6af2da6 100644
--- a/core/fpdfapi/parser/cpdf_data_avail.cpp
+++ b/core/fpdfapi/parser/cpdf_data_avail.cpp
@@ -470,15 +470,13 @@
 
     CPDF_Array* pArray = ToArray(pObj.get());
     if (pArray) {
-      for (CPDF_Object* pArrayObj : *pArray) {
-        if (CPDF_Reference* pRef = ToReference(pArrayObj))
+      for (const auto& pArrayObj : *pArray) {
+        if (CPDF_Reference* pRef = ToReference(pArrayObj.get()))
           UnavailObjList.Add(pRef->GetRefObjNum());
       }
     }
-
-    if (!pObj->IsDictionary()) {
+    if (!pObj->IsDictionary())
       continue;
-    }
 
     CFX_ByteString type = pObj->GetDict()->GetStringFor("Type");
     if (type == "Pages") {
diff --git a/core/fpdfapi/parser/cpdf_dictionary.cpp b/core/fpdfapi/parser/cpdf_dictionary.cpp
index 02cdfa3..f28507e 100644
--- a/core/fpdfapi/parser/cpdf_dictionary.cpp
+++ b/core/fpdfapi/parser/cpdf_dictionary.cpp
@@ -270,22 +270,22 @@
 void CPDF_Dictionary::SetRectFor(const CFX_ByteString& key,
                                  const CFX_FloatRect& rect) {
   CPDF_Array* pArray = new CPDF_Array;
-  pArray->AddNumber(rect.left);
-  pArray->AddNumber(rect.bottom);
-  pArray->AddNumber(rect.right);
-  pArray->AddNumber(rect.top);
+  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;
-  pArray->AddNumber(matrix.a);
-  pArray->AddNumber(matrix.b);
-  pArray->AddNumber(matrix.c);
-  pArray->AddNumber(matrix.d);
-  pArray->AddNumber(matrix.e);
-  pArray->AddNumber(matrix.f);
+  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);
 }
 
diff --git a/core/fpdfapi/parser/cpdf_document.cpp b/core/fpdfapi/parser/cpdf_document.cpp
index 35c1899..83123b2 100644
--- a/core/fpdfapi/parser/cpdf_document.cpp
+++ b/core/fpdfapi/parser/cpdf_document.cpp
@@ -18,6 +18,7 @@
 #include "core/fpdfapi/parser/cpdf_array.h"
 #include "core/fpdfapi/parser/cpdf_dictionary.h"
 #include "core/fpdfapi/parser/cpdf_linearized_header.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"
@@ -194,13 +195,12 @@
   }
   if (i == size) {
     int first = pWidthArray->GetIntegerAt(pWidthArray->GetCount() - 1);
-    pWidthArray->AddInteger(first + size - 1);
-    pWidthArray->AddInteger(*widths);
+    pWidthArray->AddNew<CPDF_Number>(first + size - 1);
+    pWidthArray->AddNew<CPDF_Number>(*widths);
   } else {
-    CPDF_Array* pWidthArray1 = new CPDF_Array;
-    pWidthArray->Add(pWidthArray1);
+    CPDF_Array* pWidthArray1 = pWidthArray->AddNew<CPDF_Array>();
     for (i = 0; i < size; i++)
-      pWidthArray1->AddInteger(widths[i]);
+      pWidthArray1->AddNew<CPDF_Number>(widths[i]);
   }
   FX_Free(widths);
 }
@@ -688,7 +688,7 @@
         continue;
       }
       if (bInsert) {
-        pKidList->InsertAt(i, new CPDF_Reference(this, pPageDict->GetObjNum()));
+        pKidList->InsertNewAt<CPDF_Reference>(i, this, pPageDict->GetObjNum());
         pPageDict->SetReferenceFor("Parent", this, pPages->GetObjNum());
       } else {
         pKidList->RemoveAt(i);
@@ -733,7 +733,7 @@
       pPagesList = new CPDF_Array;
       pPages->SetFor("Kids", pPagesList);
     }
-    pPagesList->Add(new CPDF_Reference(this, pPageDict->GetObjNum()));
+    pPagesList->AddNew<CPDF_Reference>(this, pPageDict->GetObjNum());
     pPages->SetIntegerFor("Count", nPages + 1);
     pPageDict->SetReferenceFor("Parent", this, pPages->GetObjNum());
     ResetTraversal();
@@ -785,12 +785,12 @@
   pEncodingDict->SetNameFor("BaseEncoding", "WinAnsiEncoding");
 
   CPDF_Array* pArray = new CPDF_Array;
-  pArray->AddInteger(128);
+  pArray->AddNew<CPDF_Number>(128);
 
   const uint16_t* pUnicodes = g_FX_CharsetUnicodes[i].m_pUnicodes;
   for (int j = 0; j < 128; j++) {
     CFX_ByteString name = PDF_AdobeNameFromUnicode(pUnicodes[j]);
-    pArray->AddName(name.IsEmpty() ? ".notdef" : name);
+    pArray->AddNew<CPDF_Name>(name.IsEmpty() ? ".notdef" : name);
   }
   pEncodingDict->SetFor("Differences", pArray);
   pBaseDict->SetReferenceFor("Encoding", this, pEncodingDict);
@@ -813,36 +813,36 @@
       cmap = bVert ? "ETenms-B5-V" : "ETenms-B5-H";
       ordering = "CNS1";
       supplement = 4;
-      pWidthArray->AddInteger(1);
+      pWidthArray->AddNew<CPDF_Number>(1);
       Insert(0x20, 0x7e, pWidthArray);
       break;
     case FXFONT_GB2312_CHARSET:
       cmap = bVert ? "GBK-EUC-V" : "GBK-EUC-H";
       ordering = "GB1";
       supplement = 2;
-      pWidthArray->AddInteger(7716);
+      pWidthArray->AddNew<CPDF_Number>(7716);
       Insert(0x20, 0x20, pWidthArray);
-      pWidthArray->AddInteger(814);
+      pWidthArray->AddNew<CPDF_Number>(814);
       Insert(0x21, 0x7e, pWidthArray);
       break;
     case FXFONT_HANGUL_CHARSET:
       cmap = bVert ? "KSCms-UHC-V" : "KSCms-UHC-H";
       ordering = "Korea1";
       supplement = 2;
-      pWidthArray->AddInteger(1);
+      pWidthArray->AddNew<CPDF_Number>(1);
       Insert(0x20, 0x7e, pWidthArray);
       break;
     case FXFONT_SHIFTJIS_CHARSET:
       cmap = bVert ? "90ms-RKSJ-V" : "90ms-RKSJ-H";
       ordering = "Japan1";
       supplement = 5;
-      pWidthArray->AddInteger(231);
+      pWidthArray->AddNew<CPDF_Number>(231);
       Insert(0x20, 0x7d, pWidthArray);
-      pWidthArray->AddInteger(326);
+      pWidthArray->AddNew<CPDF_Number>(326);
       Insert(0xa0, 0xa0, pWidthArray);
-      pWidthArray->AddInteger(327);
+      pWidthArray->AddNew<CPDF_Number>(327);
       Insert(0xa1, 0xdf, pWidthArray);
-      pWidthArray->AddInteger(631);
+      pWidthArray->AddNew<CPDF_Number>(631);
       Insert(0x7e, 0x7e, pWidthArray);
       break;
   }
@@ -860,7 +860,7 @@
   pFontDict->SetFor("CIDSystemInfo", pCIDSysInfo);
   CPDF_Array* pArray = new CPDF_Array;
   pBaseDict->SetFor("DescendantFonts", pArray);
-  pArray->AddReference(this, pFontDict->GetObjNum());
+  pArray->AddNew<CPDF_Reference>(this, pFontDict->GetObjNum());
   return pFontDict;
 }
 
@@ -888,7 +888,7 @@
     for (int charcode = 32; charcode < 128; charcode++) {
       int glyph_index = pEncoding->GlyphFromCharCode(charcode);
       int char_width = pFont->GetGlyphWidth(glyph_index);
-      pWidths->AddInteger(char_width);
+      pWidths->AddNew<CPDF_Number>(char_width);
     }
     if (charset == FXFONT_ANSI_CHARSET || charset == FXFONT_DEFAULT_CHARSET ||
         charset == FXFONT_SYMBOL_CHARSET) {
@@ -896,7 +896,7 @@
       for (int charcode = 128; charcode <= 255; charcode++) {
         int glyph_index = pEncoding->GlyphFromCharCode(charcode);
         int char_width = pFont->GetGlyphWidth(glyph_index);
-        pWidths->AddInteger(char_width);
+        pWidths->AddNew<CPDF_Number>(char_width);
       }
     } else {
       size_t i = CalculateEncodingDict(charset, pBaseDict);
@@ -905,7 +905,7 @@
         for (int j = 0; j < 128; j++) {
           int glyph_index = pEncoding->GlyphFromCharCode(pUnicodes[j]);
           int char_width = pFont->GetGlyphWidth(glyph_index);
-          pWidths->AddInteger(char_width);
+          pWidths->AddNew<CPDF_Number>(char_width);
         }
       }
     }
@@ -924,10 +924,10 @@
   FX_RECT bbox;
   pFont->GetBBox(bbox);
   CPDF_Array* pBBox = new CPDF_Array;
-  pBBox->AddInteger(bbox.left);
-  pBBox->AddInteger(bbox.bottom);
-  pBBox->AddInteger(bbox.right);
-  pBBox->AddInteger(bbox.top);
+  pBBox->AddNew<CPDF_Number>(bbox.left);
+  pBBox->AddNew<CPDF_Number>(bbox.bottom);
+  pBBox->AddNew<CPDF_Number>(bbox.right);
+  pBBox->AddNew<CPDF_Number>(bbox.top);
   int32_t nStemV = 0;
   if (pFont->GetSubstFont()) {
     nStemV = pFont->GetSubstFont()->m_Weight / 5;
@@ -1023,7 +1023,7 @@
     GetCharWidth(hDC, 32, 255, char_widths);
     CPDF_Array* pWidths = new CPDF_Array;
     for (size_t i = 0; i < 224; i++)
-      pWidths->AddInteger(char_widths[i]);
+      pWidths->AddNew<CPDF_Number>(char_widths[i]);
     ProcessNonbCJK(pBaseDict, pLogFont->lfWeight > FW_MEDIUM,
                    pLogFont->lfItalic != 0, basefont, pWidths);
   } else {
@@ -1035,7 +1035,7 @@
   }
   CPDF_Array* pBBox = new CPDF_Array;
   for (int i = 0; i < 4; i++)
-    pBBox->AddInteger(bbox[i]);
+    pBBox->AddNew<CPDF_Number>(bbox[i]);
   std::unique_ptr<CPDF_Dictionary> pFontDesc =
       CalculateFontDesc(this, basefont, flags, italicangle, ascend, descend,
                         pBBox, pLogFont->lfWeight / 5);
diff --git a/core/fpdfapi/parser/cpdf_document_unittest.cpp b/core/fpdfapi/parser/cpdf_document_unittest.cpp
index 048a9fe..df90875 100644
--- a/core/fpdfapi/parser/cpdf_document_unittest.cpp
+++ b/core/fpdfapi/parser/cpdf_document_unittest.cpp
@@ -11,6 +11,7 @@
 #include "core/fpdfapi/parser/cpdf_dictionary.h"
 #include "core/fpdfapi/parser/cpdf_linearized_header.h"
 #include "core/fpdfapi/parser/cpdf_parser.h"
+#include "core/fpdfapi/parser/cpdf_reference.h"
 #include "core/fxcrt/fx_memory.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/base/ptr_util.h"
@@ -42,31 +43,38 @@
   CPDF_TestDocumentForPages() : CPDF_Document(nullptr) {
     // Set up test
     auto zeroToTwo = pdfium::MakeUnique<CPDF_Array>();
-    zeroToTwo->AddReference(this, AddIndirectObject(CreateNumberedPage(0)));
-    zeroToTwo->AddReference(this, AddIndirectObject(CreateNumberedPage(1)));
-    zeroToTwo->AddReference(this, AddIndirectObject(CreateNumberedPage(2)));
+    zeroToTwo->AddNew<CPDF_Reference>(
+        this, AddIndirectObject(CreateNumberedPage(0))->GetObjNum());
+    zeroToTwo->AddNew<CPDF_Reference>(
+        this, AddIndirectObject(CreateNumberedPage(1))->GetObjNum());
+    zeroToTwo->AddNew<CPDF_Reference>(
+        this, AddIndirectObject(CreateNumberedPage(2))->GetObjNum());
     CPDF_Dictionary* branch1 =
         CreatePageTreeNode(std::move(zeroToTwo), this, 3);
 
     auto zeroToThree = pdfium::MakeUnique<CPDF_Array>();
-    zeroToThree->AddReference(this, branch1->GetObjNum());
-    zeroToThree->AddReference(this, AddIndirectObject(CreateNumberedPage(3)));
+    zeroToThree->AddNew<CPDF_Reference>(this, branch1->GetObjNum());
+    zeroToThree->AddNew<CPDF_Reference>(
+        this, AddIndirectObject(CreateNumberedPage(3))->GetObjNum());
     CPDF_Dictionary* branch2 =
         CreatePageTreeNode(std::move(zeroToThree), this, 4);
 
     auto fourFive = pdfium::MakeUnique<CPDF_Array>();
-    fourFive->AddReference(this, AddIndirectObject(CreateNumberedPage(4)));
-    fourFive->AddReference(this, AddIndirectObject(CreateNumberedPage(5)));
+    fourFive->AddNew<CPDF_Reference>(
+        this, AddIndirectObject(CreateNumberedPage(4))->GetObjNum());
+    fourFive->AddNew<CPDF_Reference>(
+        this, AddIndirectObject(CreateNumberedPage(5))->GetObjNum());
     CPDF_Dictionary* branch3 = CreatePageTreeNode(std::move(fourFive), this, 2);
 
     auto justSix = pdfium::MakeUnique<CPDF_Array>();
-    justSix->AddReference(this, AddIndirectObject(CreateNumberedPage(6)));
+    justSix->AddNew<CPDF_Reference>(
+        this, AddIndirectObject(CreateNumberedPage(6))->GetObjNum());
     CPDF_Dictionary* branch4 = CreatePageTreeNode(std::move(justSix), this, 1);
 
     auto allPages = pdfium::MakeUnique<CPDF_Array>();
-    allPages->AddReference(this, branch2);
-    allPages->AddReference(this, branch3);
-    allPages->AddReference(this, branch4);
+    allPages->AddNew<CPDF_Reference>(this, branch2->GetObjNum());
+    allPages->AddNew<CPDF_Reference>(this, branch3->GetObjNum());
+    allPages->AddNew<CPDF_Reference>(this, branch4->GetObjNum());
     CPDF_Dictionary* pagesDict =
         CreatePageTreeNode(std::move(allPages), this, 7);
 
@@ -85,10 +93,12 @@
   CPDF_TestDocumentWithPageWithoutPageNum() : CPDF_Document(nullptr) {
     // Set up test
     auto allPages = pdfium::MakeUnique<CPDF_Array>();
-    allPages->AddReference(this, AddIndirectObject(CreateNumberedPage(0)));
-    allPages->AddReference(this, AddIndirectObject(CreateNumberedPage(1)));
+    allPages->AddNew<CPDF_Reference>(
+        this, AddIndirectObject(CreateNumberedPage(0))->GetObjNum());
+    allPages->AddNew<CPDF_Reference>(
+        this, AddIndirectObject(CreateNumberedPage(1))->GetObjNum());
     // Page without pageNum.
-    allPages->Add(CreateNumberedPage(2).release());
+    allPages->Add(CreateNumberedPage(2));
     CPDF_Dictionary* pagesDict =
         CreatePageTreeNode(std::move(allPages), this, 3);
     m_pOwnedRootDict.reset(new CPDF_Dictionary());
diff --git a/core/fpdfapi/parser/cpdf_object_unittest.cpp b/core/fpdfapi/parser/cpdf_object_unittest.cpp
index 4145f24..c341284 100644
--- a/core/fpdfapi/parser/cpdf_object_unittest.cpp
+++ b/core/fpdfapi/parser/cpdf_object_unittest.cpp
@@ -59,8 +59,8 @@
     CPDF_Name* name_obj = new CPDF_Name("space");
     // Array object.
     m_ArrayObj = new CPDF_Array;
-    m_ArrayObj->InsertAt(0, new CPDF_Number(8902));
-    m_ArrayObj->InsertAt(1, new CPDF_Name("address"));
+    m_ArrayObj->InsertNewAt<CPDF_Number>(0, 8902);
+    m_ArrayObj->InsertNewAt<CPDF_Name>(1, "address");
     // Dictionary object.
     m_DictObj = new CPDF_Dictionary();
     m_DictObj->SetFor("bool", new CPDF_Boolean(false));
@@ -388,11 +388,11 @@
                       {2.3f, 4.05f, 3, -2, -3, 0.0f},
                       {0.05f, 0.1f, 0.56f, 0.67f, 1.34f, 99.9f}};
   for (size_t i = 0; i < FX_ArraySize(elems); ++i) {
-    std::unique_ptr<CPDF_Array> arr(new CPDF_Array);
+    auto arr = pdfium::MakeUnique<CPDF_Array>();
     CFX_Matrix matrix(elems[i][0], elems[i][1], elems[i][2], elems[i][3],
                       elems[i][4], elems[i][5]);
     for (size_t j = 0; j < 6; ++j)
-      arr->AddNumber(elems[i][j]);
+      arr->AddNew<CPDF_Number>(elems[i][j]);
     CFX_Matrix arr_matrix = arr->GetMatrix();
     EXPECT_EQ(matrix.GetA(), arr_matrix.GetA());
     EXPECT_EQ(matrix.GetB(), arr_matrix.GetB());
@@ -409,10 +409,10 @@
                       {2.3f, 4.05f, -3, 0.0f},
                       {0.05f, 0.1f, 1.34f, 99.9f}};
   for (size_t i = 0; i < FX_ArraySize(elems); ++i) {
-    std::unique_ptr<CPDF_Array> arr(new CPDF_Array);
+    auto arr = pdfium::MakeUnique<CPDF_Array>();
     CFX_FloatRect rect(elems[i]);
     for (size_t j = 0; j < 4; ++j)
-      arr->AddNumber(elems[i][j]);
+      arr->AddNew<CPDF_Number>(elems[i][j]);
     CFX_FloatRect arr_rect = arr->GetRect();
     EXPECT_EQ(rect.left, arr_rect.left);
     EXPECT_EQ(rect.right, arr_rect.right);
@@ -425,9 +425,9 @@
   {
     // Boolean array.
     const bool vals[] = {true, false, false, true, true};
-    std::unique_ptr<CPDF_Array> arr(new CPDF_Array);
+    auto arr = pdfium::MakeUnique<CPDF_Array>();
     for (size_t i = 0; i < FX_ArraySize(vals); ++i)
-      arr->InsertAt(i, new CPDF_Boolean(vals[i]));
+      arr->InsertNewAt<CPDF_Boolean>(i, vals[i]);
     for (size_t i = 0; i < FX_ArraySize(vals); ++i) {
       TestArrayAccessors(arr.get(), i,                // Array and index.
                          vals[i] ? "true" : "false",  // String value.
@@ -442,9 +442,9 @@
   {
     // Integer array.
     const int vals[] = {10, 0, -345, 2089345456, -1000000000, 567, 93658767};
-    std::unique_ptr<CPDF_Array> arr(new CPDF_Array);
+    auto arr = pdfium::MakeUnique<CPDF_Array>();
     for (size_t i = 0; i < FX_ArraySize(vals); ++i)
-      arr->InsertAt(i, new CPDF_Number(vals[i]));
+      arr->InsertNewAt<CPDF_Number>(i, vals[i]);
     for (size_t i = 0; i < FX_ArraySize(vals); ++i) {
       char buf[33];
       TestArrayAccessors(arr.get(), i,                  // Array and index.
@@ -463,10 +463,9 @@
                           897.34f, -2.5f, -1.0f, -345.0f, -0.0f};
     const char* const expected_str[] = {
         "0", "0", "10", "10", "0.0345", "897.34", "-2.5", "-1", "-345", "0"};
-    std::unique_ptr<CPDF_Array> arr(new CPDF_Array);
-    for (size_t i = 0; i < FX_ArraySize(vals); ++i) {
-      arr->InsertAt(i, new CPDF_Number(vals[i]));
-    }
+    auto arr = pdfium::MakeUnique<CPDF_Array>();
+    for (size_t i = 0; i < FX_ArraySize(vals); ++i)
+      arr->InsertNewAt<CPDF_Number>(i, vals[i]);
     for (size_t i = 0; i < FX_ArraySize(vals); ++i) {
       TestArrayAccessors(arr.get(), i,     // Array and index.
                          expected_str[i],  // String value.
@@ -485,8 +484,8 @@
     std::unique_ptr<CPDF_Array> string_array(new CPDF_Array);
     std::unique_ptr<CPDF_Array> name_array(new CPDF_Array);
     for (size_t i = 0; i < FX_ArraySize(vals); ++i) {
-      string_array->InsertAt(i, new CPDF_String(vals[i], false));
-      name_array->InsertAt(i, new CPDF_Name(vals[i]));
+      string_array->InsertNewAt<CPDF_String>(i, vals[i], false);
+      name_array->InsertNewAt<CPDF_Name>(i, vals[i]);
     }
     for (size_t i = 0; i < FX_ArraySize(vals); ++i) {
       TestArrayAccessors(string_array.get(), i,  // Array and index.
@@ -509,9 +508,9 @@
   }
   {
     // Null element array.
-    std::unique_ptr<CPDF_Array> arr(new CPDF_Array);
+    auto arr = pdfium::MakeUnique<CPDF_Array>();
     for (size_t i = 0; i < 3; ++i)
-      arr->InsertAt(i, new CPDF_Null);
+      arr->InsertNewAt<CPDF_Null>(i);
     for (size_t i = 0; i < 3; ++i) {
       TestArrayAccessors(arr.get(), i,  // Array and index.
                          "",            // String value.
@@ -526,14 +525,13 @@
   {
     // Array of array.
     CPDF_Array* vals[3];
-    std::unique_ptr<CPDF_Array> arr(new CPDF_Array);
+    auto arr = pdfium::MakeUnique<CPDF_Array>();
     for (size_t i = 0; i < 3; ++i) {
-      vals[i] = new CPDF_Array;
+      vals[i] = arr->AddNew<CPDF_Array>();
       for (size_t j = 0; j < 3; ++j) {
         int value = j + 100;
-        vals[i]->InsertAt(i, new CPDF_Number(value));
+        vals[i]->InsertNewAt<CPDF_Number>(i, value);
       }
-      arr->InsertAt(i, vals[i]);
     }
     for (size_t i = 0; i < 3; ++i) {
       TestArrayAccessors(arr.get(), i,  // Array and index.
@@ -549,9 +547,9 @@
   {
     // Dictionary array.
     CPDF_Dictionary* vals[3];
-    std::unique_ptr<CPDF_Array> arr(new CPDF_Array);
+    auto arr = pdfium::MakeUnique<CPDF_Array>();
     for (size_t i = 0; i < 3; ++i) {
-      vals[i] = new CPDF_Dictionary();
+      vals[i] = arr->AddNew<CPDF_Dictionary>();
       for (size_t j = 0; j < 3; ++j) {
         std::string key("key");
         char buf[33];
@@ -559,7 +557,6 @@
         int value = j + 200;
         vals[i]->SetFor(key.c_str(), new CPDF_Number(value));
       }
-      arr->InsertAt(i, vals[i]);
     }
     for (size_t i = 0; i < 3; ++i) {
       TestArrayAccessors(arr.get(), i,  // Array and index.
@@ -576,7 +573,7 @@
     // Stream array.
     CPDF_Dictionary* vals[3];
     CPDF_Stream* stream_vals[3];
-    std::unique_ptr<CPDF_Array> arr(new CPDF_Array);
+    auto arr = pdfium::MakeUnique<CPDF_Array>();
     for (size_t i = 0; i < 3; ++i) {
       vals[i] = new CPDF_Dictionary();
       for (size_t j = 0; j < 3; ++j) {
@@ -590,8 +587,7 @@
       size_t data_size = FX_ArraySize(content);
       uint8_t* data = reinterpret_cast<uint8_t*>(malloc(data_size));
       memcpy(data, content, data_size);
-      stream_vals[i] = new CPDF_Stream(data, data_size, vals[i]);
-      arr->InsertAt(i, stream_vals[i]);
+      stream_vals[i] = arr->AddNew<CPDF_Stream>(data, data_size, vals[i]);
     }
     for (size_t i = 0; i < 3; ++i) {
       TestArrayAccessors(arr.get(), i,     // Array and index.
@@ -606,27 +602,27 @@
   }
   {
     // Mixed array.
-    std::unique_ptr<CPDF_Array> arr(new CPDF_Array);
-    // Array arr will take ownership of all the objects inserted.
-    arr->InsertAt(0, new CPDF_Boolean(true));
-    arr->InsertAt(1, new CPDF_Boolean(false));
-    arr->InsertAt(2, new CPDF_Number(0));
-    arr->InsertAt(3, new CPDF_Number(-1234));
-    arr->InsertAt(4, new CPDF_Number(2345.0f));
-    arr->InsertAt(5, new CPDF_Number(0.05f));
-    arr->InsertAt(6, new CPDF_String("", false));
-    arr->InsertAt(7, new CPDF_String("It is a test!", false));
-    arr->InsertAt(8, new CPDF_Name("NAME"));
-    arr->InsertAt(9, new CPDF_Name("test"));
-    arr->InsertAt(10, new CPDF_Null());
-    CPDF_Array* arr_val = new CPDF_Array;
-    arr_val->AddNumber(1);
-    arr_val->AddNumber(2);
-    arr->InsertAt(11, arr_val);
-    CPDF_Dictionary* dict_val = new CPDF_Dictionary();
+    auto arr = pdfium::MakeUnique<CPDF_Array>();
+    arr->InsertNewAt<CPDF_Boolean>(0, true);
+    arr->InsertNewAt<CPDF_Boolean>(1, false);
+    arr->InsertNewAt<CPDF_Number>(2, 0);
+    arr->InsertNewAt<CPDF_Number>(3, -1234);
+    arr->InsertNewAt<CPDF_Number>(4, 2345.0f);
+    arr->InsertNewAt<CPDF_Number>(5, 0.05f);
+    arr->InsertNewAt<CPDF_String>(6, "", false);
+    arr->InsertNewAt<CPDF_String>(7, "It is a test!", false);
+    arr->InsertNewAt<CPDF_Name>(8, "NAME");
+    arr->InsertNewAt<CPDF_Name>(9, "test");
+    arr->InsertNewAt<CPDF_Null>(10);
+
+    CPDF_Array* arr_val = arr->InsertNewAt<CPDF_Array>(11);
+    arr_val->AddNew<CPDF_Number>(1);
+    arr_val->AddNew<CPDF_Number>(2);
+
+    CPDF_Dictionary* dict_val = arr->InsertNewAt<CPDF_Dictionary>(12);
     dict_val->SetFor("key1", new CPDF_String("Linda", false));
     dict_val->SetFor("key2", new CPDF_String("Zoe", false));
-    arr->InsertAt(12, dict_val);
+
     CPDF_Dictionary* stream_dict = new CPDF_Dictionary();
     stream_dict->SetFor("key1", new CPDF_String("John", false));
     stream_dict->SetFor("key2", new CPDF_String("King", false));
@@ -636,8 +632,8 @@
     size_t buf_size = sizeof(data);
     uint8_t* buf = reinterpret_cast<uint8_t*>(malloc(buf_size));
     memcpy(buf, data, buf_size);
-    CPDF_Stream* stream_val = new CPDF_Stream(buf, buf_size, stream_dict);
-    arr->InsertAt(13, stream_val);
+    CPDF_Stream* stream_val =
+        arr->InsertNewAt<CPDF_Stream>(13, buf, buf_size, stream_dict);
     const char* const expected_str[] = {
         "true",          "false", "0",    "-1234", "2345", "0.05", "",
         "It is a test!", "NAME",  "test", "",      "",     "",     ""};
@@ -671,9 +667,9 @@
 TEST(PDFArrayTest, AddNumber) {
   float vals[] = {1.0f,         -1.0f, 0,    0.456734f,
                   12345.54321f, 0.5f,  1000, 0.000045f};
-  std::unique_ptr<CPDF_Array> arr(new CPDF_Array);
+  auto arr = pdfium::MakeUnique<CPDF_Array>();
   for (size_t i = 0; i < FX_ArraySize(vals); ++i)
-    arr->AddNumber(vals[i]);
+    arr->AddNew<CPDF_Number>(vals[i]);
   for (size_t i = 0; i < FX_ArraySize(vals); ++i) {
     EXPECT_EQ(CPDF_Object::NUMBER, arr->GetObjectAt(i)->GetType());
     EXPECT_EQ(vals[i], arr->GetObjectAt(i)->GetNumber());
@@ -682,9 +678,9 @@
 
 TEST(PDFArrayTest, AddInteger) {
   int vals[] = {0, 1, 934435456, 876, 10000, -1, -24354656, -100};
-  std::unique_ptr<CPDF_Array> arr(new CPDF_Array);
+  auto arr = pdfium::MakeUnique<CPDF_Array>();
   for (size_t i = 0; i < FX_ArraySize(vals); ++i)
-    arr->AddInteger(vals[i]);
+    arr->AddNew<CPDF_Number>(vals[i]);
   for (size_t i = 0; i < FX_ArraySize(vals); ++i) {
     EXPECT_EQ(CPDF_Object::NUMBER, arr->GetObjectAt(i)->GetType());
     EXPECT_EQ(vals[i], arr->GetObjectAt(i)->GetNumber());
@@ -697,8 +693,8 @@
   std::unique_ptr<CPDF_Array> string_array(new CPDF_Array);
   std::unique_ptr<CPDF_Array> name_array(new CPDF_Array);
   for (size_t i = 0; i < FX_ArraySize(vals); ++i) {
-    string_array->AddString(vals[i]);
-    name_array->AddName(vals[i]);
+    string_array->AddNew<CPDF_String>(vals[i], false);
+    name_array->AddNew<CPDF_Name>(vals[i]);
   }
   for (size_t i = 0; i < FX_ArraySize(vals); ++i) {
     EXPECT_EQ(CPDF_Object::STRING, string_array->GetObjectAt(i)->GetType());
@@ -720,14 +716,14 @@
   CPDF_Object* indirect_objs[] = {boolean_obj, int_obj,  float_obj,
                                   str_obj,     name_obj, null_obj};
   unsigned int obj_nums[] = {2, 4, 7, 2345, 799887, 1};
-  std::unique_ptr<CPDF_Array> arr(new CPDF_Array);
+  auto arr = pdfium::MakeUnique<CPDF_Array>();
   std::unique_ptr<CPDF_Array> arr1(new CPDF_Array);
   // Create two arrays of references by different AddReference() APIs.
   for (size_t i = 0; i < FX_ArraySize(indirect_objs); ++i) {
     holder->ReplaceIndirectObjectIfHigherGeneration(
         obj_nums[i], pdfium::WrapUnique<CPDF_Object>(indirect_objs[i]));
-    arr->AddReference(holder.get(), obj_nums[i]);
-    arr1->AddReference(holder.get(), indirect_objs[i]->GetObjNum());
+    arr->AddNew<CPDF_Reference>(holder.get(), obj_nums[i]);
+    arr1->AddNew<CPDF_Reference>(holder.get(), indirect_objs[i]->GetObjNum());
   }
   // Check indirect objects.
   for (size_t i = 0; i < FX_ArraySize(obj_nums); ++i)
@@ -747,7 +743,7 @@
 TEST(PDFArrayTest, CloneDirectObject) {
   CPDF_IndirectObjectHolder objects_holder;
   std::unique_ptr<CPDF_Array> array(new CPDF_Array);
-  array->AddReference(&objects_holder, 1234);
+  array->AddNew<CPDF_Reference>(&objects_holder, 1234);
   ASSERT_EQ(1U, array->GetCount());
   CPDF_Object* obj = array->GetObjectAt(0);
   ASSERT_TRUE(obj);
@@ -766,9 +762,8 @@
 
 TEST(PDFArrayTest, ConvertIndirect) {
   CPDF_IndirectObjectHolder objects_holder;
-  std::unique_ptr<CPDF_Array> array(new CPDF_Array);
-  CPDF_Object* pObj = new CPDF_Number(42);
-  array->Add(pObj);
+  auto array = pdfium::MakeUnique<CPDF_Array>();
+  CPDF_Object* pObj = array->AddNew<CPDF_Number>(42);
   array->ConvertToIndirectObjectAt(0, &objects_holder);
   CPDF_Object* pRef = array->GetObjectAt(0);
   CPDF_Object* pNum = array->GetDirectObjectAt(0);
@@ -802,11 +797,9 @@
 TEST(PDFObjectTest, CloneCheckLoop) {
   {
     // Create a dictionary/array pair with a reference loop.
-    CPDF_Dictionary* dict_obj = new CPDF_Dictionary();
-    std::unique_ptr<CPDF_Array> arr_obj(new CPDF_Array);
+    auto arr_obj = pdfium::MakeUnique<CPDF_Array>();
+    CPDF_Dictionary* dict_obj = arr_obj->InsertNewAt<CPDF_Dictionary>(0);
     dict_obj->SetFor("arr", arr_obj.get());
-    arr_obj->InsertAt(0, dict_obj);
-
     // 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.
@@ -840,8 +833,8 @@
     // Create an object with a reference loop.
     CPDF_Dictionary* dict_obj = objects_holder.NewIndirect<CPDF_Dictionary>();
     std::unique_ptr<CPDF_Array> arr_obj = pdfium::MakeUnique<CPDF_Array>();
-    arr_obj->InsertAt(
-        0, new CPDF_Reference(&objects_holder, dict_obj->GetObjNum()));
+    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());
     EXPECT_EQ(1u, dict_obj->GetObjNum());
diff --git a/core/fpdfapi/parser/cpdf_syntax_parser.cpp b/core/fpdfapi/parser/cpdf_syntax_parser.cpp
index 842ef2b..6a3db60 100644
--- a/core/fpdfapi/parser/cpdf_syntax_parser.cpp
+++ b/core/fpdfapi/parser/cpdf_syntax_parser.cpp
@@ -414,7 +414,7 @@
     std::unique_ptr<CPDF_Array> pArray = pdfium::MakeUnique<CPDF_Array>();
     while (std::unique_ptr<CPDF_Object> pObj =
                GetObject(pObjList, objnum, gennum, true)) {
-      pArray->Add(pObj.release());
+      pArray->Add(std::move(pObj));
     }
     return std::move(pArray);
   }
@@ -534,7 +534,7 @@
     std::unique_ptr<CPDF_Array> pArray = pdfium::MakeUnique<CPDF_Array>();
     while (std::unique_ptr<CPDF_Object> pObj =
                GetObject(pObjList, objnum, gennum, true)) {
-      pArray->Add(pObj.release());
+      pArray->Add(std::move(pObj));
     }
     return m_WordBuffer[0] == ']' ? std::move(pArray) : nullptr;
   }
diff --git a/core/fpdfdoc/cpdf_dest_unittest.cpp b/core/fpdfdoc/cpdf_dest_unittest.cpp
index d427ab6..bc83eca 100644
--- a/core/fpdfdoc/cpdf_dest_unittest.cpp
+++ b/core/fpdfdoc/cpdf_dest_unittest.cpp
@@ -4,6 +4,7 @@
 
 #include "core/fpdfapi/parser/cpdf_array.h"
 #include "core/fpdfapi/parser/cpdf_null.h"
+#include "core/fpdfapi/parser/cpdf_name.h"
 #include "core/fpdfapi/parser/cpdf_number.h"
 #include "core/fpdfdoc/cpdf_dest.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -22,16 +23,16 @@
   EXPECT_FALSE(dest->GetXYZ(&hasX, &hasY, &hasZoom, &x, &y, &zoom));
 
   auto array = pdfium::MakeUnique<CPDF_Array>();
-  array->AddInteger(0);  // Page Index.
-  array->AddName("XYZ");
-  array->AddNumber(4);  // X
+  array->AddNew<CPDF_Number>(0);  // Page Index.
+  array->AddNew<CPDF_Name>("XYZ");
+  array->AddNew<CPDF_Number>(4);  // X
 
   // Not enough entries.
   dest = pdfium::MakeUnique<CPDF_Dest>(array.get());
   EXPECT_FALSE(dest->GetXYZ(&hasX, &hasY, &hasZoom, &x, &y, &zoom));
 
-  array->AddNumber(5);  // Y
-  array->AddNumber(6);  // Zoom.
+  array->AddNew<CPDF_Number>(5);  // Y
+  array->AddNew<CPDF_Number>(6);  // Zoom.
 
   dest = pdfium::MakeUnique<CPDF_Dest>(array.get());
   EXPECT_TRUE(dest->GetXYZ(&hasX, &hasY, &hasZoom, &x, &y, &zoom));
@@ -43,15 +44,15 @@
   EXPECT_EQ(6, zoom);
 
   // Set zoom to 0.
-  array->SetAt(4, new CPDF_Number(0));
+  array->SetNewAt<CPDF_Number>(4, 0);
   dest = pdfium::MakeUnique<CPDF_Dest>(array.get());
   EXPECT_TRUE(dest->GetXYZ(&hasX, &hasY, &hasZoom, &x, &y, &zoom));
   EXPECT_FALSE(hasZoom);
 
   // Set values to null.
-  array->SetAt(2, new CPDF_Null);
-  array->SetAt(3, new CPDF_Null);
-  array->SetAt(4, new CPDF_Null);
+  array->SetNewAt<CPDF_Null>(2);
+  array->SetNewAt<CPDF_Null>(3);
+  array->SetNewAt<CPDF_Null>(4);
   dest = pdfium::MakeUnique<CPDF_Dest>(array.get());
   EXPECT_TRUE(dest->GetXYZ(&hasX, &hasY, &hasZoom, &x, &y, &zoom));
   EXPECT_FALSE(hasX);
diff --git a/core/fpdfdoc/cpdf_formfield.cpp b/core/fpdfdoc/cpdf_formfield.cpp
index 4999f2d..3a2213f 100644
--- a/core/fpdfdoc/cpdf_formfield.cpp
+++ b/core/fpdfdoc/cpdf_formfield.cpp
@@ -555,7 +555,7 @@
         for (int i = 0; i < CountOptions(); i++) {
           if (i == index || IsItemSelected(i)) {
             opt_value = GetOptionValue(i);
-            pArray->AddString(PDF_EncodeText(opt_value));
+            pArray->AddNew<CPDF_String>(PDF_EncodeText(opt_value), false);
           }
         }
         m_pDict->SetFor("V", pArray);
@@ -563,7 +563,7 @@
     } else {
       m_pDict->SetStringFor("V", PDF_EncodeText(opt_value));
       CPDF_Array* pI = new CPDF_Array;
-      pI->AddInteger(index);
+      pI->AddNew<CPDF_Number>(index);
       m_pDict->SetFor("I", pI);
     }
   } else {
@@ -579,7 +579,7 @@
           for (int i = 0; i < CountOptions(); i++) {
             if (i != index && IsItemSelected(i)) {
               opt_value = GetOptionValue(i);
-              pArray->AddString(PDF_EncodeText(opt_value));
+              pArray->AddNew<CPDF_String>(PDF_EncodeText(opt_value), false);
             }
           }
           if (pArray->GetCount() > 0)
@@ -684,11 +684,10 @@
 
   int iCount = pdfium::base::checked_cast<int>(pOpt->GetCount());
   if (index >= iCount) {
-    pOpt->AddString(csStr);
+    pOpt->AddNew<CPDF_String>(csStr, false);
     index = iCount;
   } else {
-    CPDF_String* pString = new CPDF_String(csStr, false);
-    pOpt->InsertAt(index, pString);
+    pOpt->InsertNewAt<CPDF_String>(index, csStr, false);
   }
 
   if (bNotify)
@@ -836,7 +835,7 @@
   if (!pArray)
     return false;
 
-  for (CPDF_Object* pObj : *pArray) {
+  for (const auto& pObj : *pArray) {
     if (pObj->GetInteger() == iOptIndex)
       return true;
   }
@@ -879,14 +878,14 @@
         if (!NotifyListOrComboBoxBeforeChange(csValue))
           return false;
       }
-      pArray->InsertAt(i, new CPDF_Number(iOptIndex));
+      pArray->InsertNewAt<CPDF_Number>(i, iOptIndex);
       bReturn = true;
       break;
     }
   }
   if (!bReturn) {
     if (bSelected)
-      pArray->AddInteger(iOptIndex);
+      pArray->AddNew<CPDF_Number>(iOptIndex);
 
     if (pArray->IsEmpty())
       m_pDict->RemoveFor("I");
diff --git a/core/fpdfdoc/cpdf_interform.cpp b/core/fpdfdoc/cpdf_interform.cpp
index 64d15a0..c991598 100644
--- a/core/fpdfdoc/cpdf_interform.cpp
+++ b/core/fpdfdoc/cpdf_interform.cpp
@@ -1237,8 +1237,8 @@
         continue;
 
       CFX_WideString fullname = FPDF_GetFullName(pField->GetFieldDict());
-      CPDF_Dictionary* pFieldDict =
-          new CPDF_Dictionary(pDoc->GetByteStringPool());
+      auto pFieldDict =
+          pdfium::MakeUnique<CPDF_Dictionary>(pDoc->GetByteStringPool());
       pFieldDict->SetFor("T", new CPDF_String(fullname));
       if (pField->GetType() == CPDF_FormField::CheckBox ||
           pField->GetType() == CPDF_FormField::RadioButton) {
@@ -1254,7 +1254,7 @@
         if (pV)
           pFieldDict->SetFor("V", pV->CloneDirectObject().release());
       }
-      pFields->Add(pFieldDict);
+      pFields->Add(std::move(pFieldDict));
     }
   }
   return pDoc;
diff --git a/fpdfsdk/cpdfsdk_baannot.cpp b/fpdfsdk/cpdfsdk_baannot.cpp
index 9436b3b..ee4b55d 100644
--- a/fpdfsdk/cpdfsdk_baannot.cpp
+++ b/fpdfsdk/cpdfsdk_baannot.cpp
@@ -162,7 +162,7 @@
 void CPDFSDK_BAAnnot::SetBorderWidth(int nWidth) {
   CPDF_Array* pBorder = m_pAnnot->GetAnnotDict()->GetArrayFor("Border");
   if (pBorder) {
-    pBorder->SetAt(2, new CPDF_Number(nWidth));
+    pBorder->SetNewAt<CPDF_Number>(2, nWidth);
   } else {
     CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDictFor("BS");
     if (!pBSDict) {
@@ -242,9 +242,12 @@
 
 void CPDFSDK_BAAnnot::SetColor(FX_COLORREF color) {
   CPDF_Array* pArray = new CPDF_Array;
-  pArray->AddNumber((FX_FLOAT)FXSYS_GetRValue(color) / 255.0f);
-  pArray->AddNumber((FX_FLOAT)FXSYS_GetGValue(color) / 255.0f);
-  pArray->AddNumber((FX_FLOAT)FXSYS_GetBValue(color) / 255.0f);
+  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);
 }
 
diff --git a/fpdfsdk/fpdf_flatten.cpp b/fpdfsdk/fpdf_flatten.cpp
index b11e4a6..cb0a625 100644
--- a/fpdfsdk/fpdf_flatten.cpp
+++ b/fpdfsdk/fpdf_flatten.cpp
@@ -13,6 +13,7 @@
 #include "core/fpdfapi/parser/cpdf_array.h"
 #include "core/fpdfapi/parser/cpdf_document.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_stream_acc.h"
 #include "core/fpdfdoc/cpdf_annot.h"
@@ -205,12 +206,13 @@
         CFX_ByteString((const FX_CHAR*)acc.GetData(), acc.GetSize());
     sStream = sStream + sBody + "\nQ";
     pContentsStream->SetData(sStream.raw_str(), sStream.GetLength());
-    pContentsArray->AddReference(pDocument, pContentsStream->GetObjNum());
+    pContentsArray->AddNew<CPDF_Reference>(pDocument,
+                                           pContentsStream->GetObjNum());
     pPage->SetReferenceFor("Contents", pDocument, pContentsArray);
   }
   if (!key.IsEmpty()) {
-    pContentsArray->AddReference(pDocument,
-                                 NewIndirectContentsStream(key, pDocument));
+    pContentsArray->AddNew<CPDF_Reference>(
+        pDocument, NewIndirectContentsStream(key, pDocument));
   }
 }
 
@@ -270,19 +272,19 @@
 
   if (!rcOriginalMB.IsEmpty()) {
     CPDF_Array* pMediaBox = new CPDF_Array();
-    pMediaBox->Add(new CPDF_Number(rcOriginalMB.left));
-    pMediaBox->Add(new CPDF_Number(rcOriginalMB.bottom));
-    pMediaBox->Add(new CPDF_Number(rcOriginalMB.right));
-    pMediaBox->Add(new CPDF_Number(rcOriginalMB.top));
+    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();
-    pCropBox->Add(new CPDF_Number(rcOriginalCB.left));
-    pCropBox->Add(new CPDF_Number(rcOriginalCB.bottom));
-    pCropBox->Add(new CPDF_Number(rcOriginalCB.right));
-    pCropBox->Add(new CPDF_Number(rcOriginalCB.top));
+    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);
   }
 
diff --git a/fpdfsdk/fpdf_transformpage.cpp b/fpdfsdk/fpdf_transformpage.cpp
index 76be4de..beaa6c4 100644
--- a/fpdfsdk/fpdf_transformpage.cpp
+++ b/fpdfsdk/fpdf_transformpage.cpp
@@ -27,10 +27,10 @@
                     float right,
                     float top) {
   CPDF_Array* pBoundingBoxArray = new CPDF_Array;
-  pBoundingBoxArray->Add(new CPDF_Number(left));
-  pBoundingBoxArray->Add(new CPDF_Number(bottom));
-  pBoundingBoxArray->Add(new CPDF_Number(right));
-  pBoundingBoxArray->Add(new CPDF_Number(top));
+  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);
 }
 
@@ -142,23 +142,22 @@
   CPDF_Array* pArray = ToArray(pContentObj);
   if (pArray) {
     pContentArray = pArray;
-    CPDF_Reference* pRef = new CPDF_Reference(pDoc, pStream->GetObjNum());
-    pContentArray->InsertAt(0, pRef);
-    pContentArray->AddReference(pDoc, pEndStream->GetObjNum());
+    pContentArray->InsertNewAt<CPDF_Reference>(0, pDoc, pStream->GetObjNum());
+    pContentArray->AddNew<CPDF_Reference>(pDoc, pEndStream->GetObjNum());
   } else if (CPDF_Reference* pReference = ToReference(pContentObj)) {
     CPDF_Object* pDirectObj = pReference->GetDirect();
     if (pDirectObj) {
       CPDF_Array* pObjArray = pDirectObj->AsArray();
       if (pObjArray) {
         pContentArray = pObjArray;
-        CPDF_Reference* pRef = new CPDF_Reference(pDoc, pStream->GetObjNum());
-        pContentArray->InsertAt(0, pRef);
-        pContentArray->AddReference(pDoc, pEndStream->GetObjNum());
+        pContentArray->InsertNewAt<CPDF_Reference>(0, pDoc,
+                                                   pStream->GetObjNum());
+        pContentArray->AddNew<CPDF_Reference>(pDoc, pEndStream->GetObjNum());
       } else if (pDirectObj->IsStream()) {
         pContentArray = pDoc->NewIndirect<CPDF_Array>();
-        pContentArray->AddReference(pDoc, pStream->GetObjNum());
-        pContentArray->AddReference(pDoc, pDirectObj->GetObjNum());
-        pContentArray->AddReference(pDoc, pEndStream->GetObjNum());
+        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);
       }
     }
@@ -307,26 +306,28 @@
   CPDF_Stream* pStream = pDoc->NewIndirect<CPDF_Stream>(nullptr, 0, pDic);
   pStream->SetData(strClip.GetBuffer(), strClip.GetSize());
 
-  CPDF_Array* pContentArray = nullptr;
   CPDF_Array* pArray = ToArray(pContentObj);
   if (pArray) {
-    pContentArray = pArray;
-    CPDF_Reference* pRef = new CPDF_Reference(pDoc, pStream->GetObjNum());
-    pContentArray->InsertAt(0, pRef);
-  } else if (CPDF_Reference* pReference = ToReference(pContentObj)) {
-    CPDF_Object* pDirectObj = pReference->GetDirect();
-    if (pDirectObj) {
-      CPDF_Array* pObjArray = pDirectObj->AsArray();
-      if (pObjArray) {
-        pContentArray = pObjArray;
-        CPDF_Reference* pRef = new CPDF_Reference(pDoc, pStream->GetObjNum());
-        pContentArray->InsertAt(0, pRef);
-      } else if (pDirectObj->IsStream()) {
-        pContentArray = pDoc->NewIndirect<CPDF_Array>();
-        pContentArray->AddReference(pDoc, pStream->GetObjNum());
-        pContentArray->AddReference(pDoc, pDirectObj->GetObjNum());
-        pPageDic->SetReferenceFor("Contents", pDoc, pContentArray);
-      }
-    }
+    pArray->InsertNewAt<CPDF_Reference>(0, pDoc, pStream->GetObjNum());
+    return;
+  }
+  CPDF_Reference* pReference = ToReference(pContentObj);
+  if (!pReference)
+    return;
+
+  CPDF_Object* pDirectObj = pReference->GetDirect();
+  if (!pDirectObj)
+    return;
+
+  CPDF_Array* pObjArray = pDirectObj->AsArray();
+  if (pObjArray) {
+    pObjArray->InsertNewAt<CPDF_Reference>(0, pDoc, pStream->GetObjNum());
+    return;
+  }
+  if (pDirectObj->IsStream()) {
+    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);
   }
 }
diff --git a/fpdfsdk/fpdfdoc_unittest.cpp b/fpdfsdk/fpdfdoc_unittest.cpp
index 7d1d6b4..50837d5 100644
--- a/fpdfsdk/fpdfdoc_unittest.cpp
+++ b/fpdfsdk/fpdfdoc_unittest.cpp
@@ -236,11 +236,11 @@
 
 TEST_F(PDFDocTest, GetLocationInPage) {
   auto array = pdfium::MakeUnique<CPDF_Array>();
-  array->AddInteger(0);  // Page Index.
-  array->AddName("XYZ");
-  array->AddNumber(4);  // X
-  array->AddNumber(5);  // Y
-  array->AddNumber(6);  // Zoom.
+  array->AddNew<CPDF_Number>(0);  // Page Index.
+  array->AddNew<CPDF_Name>("XYZ");
+  array->AddNew<CPDF_Number>(4);  // X
+  array->AddNew<CPDF_Number>(5);  // Y
+  array->AddNew<CPDF_Number>(6);  // Zoom.
 
   FPDF_BOOL hasX;
   FPDF_BOOL hasY;
@@ -258,9 +258,9 @@
   EXPECT_EQ(5, y);
   EXPECT_EQ(6, zoom);
 
-  array->SetAt(2, new CPDF_Null);
-  array->SetAt(3, new CPDF_Null);
-  array->SetAt(4, new CPDF_Null);
+  array->SetNewAt<CPDF_Null>(2);
+  array->SetNewAt<CPDF_Null>(3);
+  array->SetNewAt<CPDF_Null>(4);
   EXPECT_TRUE(FPDFDest_GetLocationInPage(array.get(), &hasX, &hasY, &hasZoom,
                                          &x, &y, &zoom));
   EXPECT_FALSE(hasX);
diff --git a/fpdfsdk/fpdfeditpage.cpp b/fpdfsdk/fpdfeditpage.cpp
index 92fd39e..9dc8ae9 100644
--- a/fpdfsdk/fpdfeditpage.cpp
+++ b/fpdfsdk/fpdfeditpage.cpp
@@ -110,10 +110,10 @@
     return nullptr;
 
   CPDF_Array* pMediaBoxArray = new CPDF_Array;
-  pMediaBoxArray->Add(new CPDF_Number(0));
-  pMediaBoxArray->Add(new CPDF_Number(0));
-  pMediaBoxArray->Add(new CPDF_Number(FX_FLOAT(width)));
-  pMediaBoxArray->Add(new CPDF_Number(FX_FLOAT(height)));
+  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",
@@ -298,10 +298,10 @@
       pRectArray = new CPDF_Array;
       pAnnot->GetAnnotDict()->SetFor("Rect", pRectArray);
     }
-    pRectArray->SetAt(0, new CPDF_Number(rect.left));
-    pRectArray->SetAt(1, new CPDF_Number(rect.bottom));
-    pRectArray->SetAt(2, new CPDF_Number(rect.right));
-    pRectArray->SetAt(3, new CPDF_Number(rect.top));
+    pRectArray->SetNewAt<CPDF_Number>(0, rect.left);
+    pRectArray->SetNewAt<CPDF_Number>(1, rect.bottom);
+    pRectArray->SetNewAt<CPDF_Number>(2, rect.right);
+    pRectArray->SetNewAt<CPDF_Number>(3, rect.top);
 
     // TODO: Transform AP's rectangle
   }
diff --git a/fpdfsdk/fpdfppo.cpp b/fpdfsdk/fpdfppo.cpp
index 610aae7..ec3312b 100644
--- a/fpdfsdk/fpdfppo.cpp
+++ b/fpdfsdk/fpdfppo.cpp
@@ -221,10 +221,10 @@
       } else {
         // Make the default size to be letter size (8.5'x11')
         CPDF_Array* pArray = new CPDF_Array;
-        pArray->AddNumber(0);
-        pArray->AddNumber(0);
-        pArray->AddNumber(612);
-        pArray->AddNumber(792);
+        pArray->AddNew<CPDF_Number>(0);
+        pArray->AddNew<CPDF_Number>(0);
+        pArray->AddNew<CPDF_Number>(612);
+        pArray->AddNew<CPDF_Number>(792);
         pCurPageDict->SetFor("MediaBox", pArray);
       }
     }
diff --git a/fpdfsdk/fpdfsave.cpp b/fpdfsdk/fpdfsave.cpp
index e5d7a40..c904324 100644
--- a/fpdfsdk/fpdfsave.cpp
+++ b/fpdfsdk/fpdfsave.cpp
@@ -183,9 +183,9 @@
         CPDF_Stream* pData = pPDFDocument->NewIndirect<CPDF_Stream>();
         pData->InitStreamFromFile(pDsfileWrite.get(), pDataDict);
         iLast = pArray->GetCount() - 2;
-        pArray->InsertAt(iLast, new CPDF_String("datasets", false));
-        pArray->InsertAt(iLast + 1,
-                         new CPDF_Reference(pPDFDocument, pData->GetObjNum()));
+        pArray->InsertNewAt<CPDF_String>(iLast, "datasets", false);
+        pArray->InsertNewAt<CPDF_Reference>(iLast + 1, pPDFDocument,
+                                            pData->GetObjNum());
       }
       fileList->push_back(std::move(pDsfileWrite));
     }
@@ -205,9 +205,9 @@
         CPDF_Stream* pData = pPDFDocument->NewIndirect<CPDF_Stream>();
         pData->InitStreamFromFile(pfileWrite.get(), pDataDict);
         iLast = pArray->GetCount() - 2;
-        pArray->InsertAt(iLast, new CPDF_String("form", false));
-        pArray->InsertAt(iLast + 1,
-                         new CPDF_Reference(pPDFDocument, pData->GetObjNum()));
+        pArray->InsertNewAt<CPDF_String>(iLast, "form", false);
+        pArray->InsertNewAt<CPDF_Reference>(iLast + 1, pPDFDocument,
+                                            pData->GetObjNum());
       }
       fileList->push_back(std::move(pfileWrite));
     }
diff --git a/testing/libfuzzer/pdf_hint_table_fuzzer.cc b/testing/libfuzzer/pdf_hint_table_fuzzer.cc
index 16d0401..15e04d9 100644
--- a/testing/libfuzzer/pdf_hint_table_fuzzer.cc
+++ b/testing/libfuzzer/pdf_hint_table_fuzzer.cc
@@ -8,6 +8,7 @@
 #include "core/fpdfapi/parser/cpdf_dictionary.h"
 #include "core/fpdfapi/parser/cpdf_hint_tables.h"
 #include "core/fpdfapi/parser/cpdf_linearized_header.h"
+#include "core/fpdfapi/parser/cpdf_number.h"
 #include "third_party/base/ptr_util.h"
 
 int32_t GetData(const int32_t** data32, const uint8_t** data, size_t* size) {
@@ -73,9 +74,9 @@
 
   auto hint_info = pdfium::MakeUnique<CPDF_Array>();
   // Add primary hint stream offset
-  hint_info->AddInteger(GetData(&data32, &data, &size));
+  hint_info->AddNew<CPDF_Number>(GetData(&data32, &data, &size));
   // Add primary hint stream size
-  hint_info->AddInteger(GetData(&data32, &data, &size));
+  hint_info->AddNew<CPDF_Number>(GetData(&data32, &data, &size));
   // Set hint stream info.
   linearized_dict->SetFor("H", hint_info.release());