Replace some CPDF_Dictionary::SetFor() calls with SetNewFor<>()

SetNewFor<>() is safer because it can not introduce a direct
cycle of objects into the dictionary since it creates a new object
that can not have references to any old objects [cycles through
indirect objects are always possible, but do not affect memory
management when using RetainPtr<>].

This reduces the number of NewFor() calls that might need auditing
should a cycle be discovered in dictionaries again someday.

Change-Id: I4d9e8b466a2562e39386d028cbee9f7c86a267c3
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/53832
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
index a99f1ed..11b24e6 100644
--- a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
+++ b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
@@ -202,9 +202,9 @@
   if (!m_pObjHolder->m_pResources) {
     m_pObjHolder->m_pResources.Reset(
         m_pDocument->NewIndirect<CPDF_Dictionary>());
-    m_pObjHolder->GetDict()->SetFor(
-        "Resources",
-        m_pObjHolder->m_pResources->MakeReference(m_pDocument.Get()));
+    m_pObjHolder->GetDict()->SetNewFor<CPDF_Reference>(
+        "Resources", m_pDocument.Get(),
+        m_pObjHolder->m_pResources->GetObjNum());
   }
   CPDF_Dictionary* pResList = m_pObjHolder->m_pResources->GetDictFor(bsType);
   if (!pResList)
@@ -219,7 +219,8 @@
 
     idnum++;
   }
-  pResList->SetFor(name, pResource->MakeReference(m_pDocument.Get()));
+  pResList->SetNewFor<CPDF_Reference>(name, m_pDocument.Get(),
+                                      pResource->GetObjNum());
   return name;
 }
 
diff --git a/core/fpdfapi/edit/cpdf_pagecontentgenerator_unittest.cpp b/core/fpdfapi/edit/cpdf_pagecontentgenerator_unittest.cpp
index 20e4374..6238346 100644
--- a/core/fpdfapi/edit/cpdf_pagecontentgenerator_unittest.cpp
+++ b/core/fpdfapi/edit/cpdf_pagecontentgenerator_unittest.cpp
@@ -317,13 +317,13 @@
     CPDF_Dictionary* pDesc = pDoc->NewIndirect<CPDF_Dictionary>();
     pDesc->SetNewFor<CPDF_Name>("Type", "FontDescriptor");
     pDesc->SetNewFor<CPDF_Name>("FontName", pFont->GetBaseFont());
-    pDict->SetFor("FontDescriptor", pDesc->MakeReference(pDoc.get()));
+    pDict->SetNewFor<CPDF_Reference>("FontDescriptor", pDoc.get(),
+                                     pDesc->GetObjNum());
 
     CPDF_Font* loadedFont = pDoc->LoadFont(pDict);
     pTextObj->m_TextState.SetFont(loadedFont);
     pTextObj->m_TextState.SetFontSize(15.5f);
     pTextObj->SetText("I am indirect");
-
     TestProcessText(&generator, &buf, pTextObj.get());
   }
 
diff --git a/core/fpdfapi/edit/cpdf_pagecontentmanager.cpp b/core/fpdfapi/edit/cpdf_pagecontentmanager.cpp
index 95a7a85..0191f47 100644
--- a/core/fpdfapi/edit/cpdf_pagecontentmanager.cpp
+++ b/core/fpdfapi/edit/cpdf_pagecontentmanager.cpp
@@ -70,8 +70,8 @@
     new_contents_array->Add(new_stream->MakeReference(doc_.Get()));
 
     CPDF_Dictionary* page_dict = obj_holder_->GetDict();
-    page_dict->SetFor("Contents",
-                      new_contents_array->MakeReference(doc_.Get()));
+    page_dict->SetNewFor<CPDF_Reference>("Contents", doc_.Get(),
+                                         new_contents_array->GetObjNum());
     contents_array_.Reset(new_contents_array);
     contents_stream_ = nullptr;
     return 1;
@@ -86,7 +86,8 @@
   // There were no Contents, so add the new stream as the single Content stream.
   // Its index is 0.
   CPDF_Dictionary* page_dict = obj_holder_->GetDict();
-  page_dict->SetFor("Contents", new_stream->MakeReference(doc_.Get()));
+  page_dict->SetNewFor<CPDF_Reference>("Contents", doc_.Get(),
+                                       new_stream->GetObjNum());
   contents_stream_.Reset(new_stream);
   return 0;
 }
diff --git a/core/fpdfapi/page/cpdf_image.cpp b/core/fpdfapi/page/cpdf_image.cpp
index 63ec6ce..2a44215 100644
--- a/core/fpdfapi/page/cpdf_image.cpp
+++ b/core/fpdfapi/page/cpdf_image.cpp
@@ -247,7 +247,8 @@
       CPDF_Stream* pCTS = m_pDocument->NewIndirect<CPDF_Stream>(
           std::move(pColorTable), iPalette * 3, std::move(pNewDict));
       pCS->Add(pCTS->MakeReference(m_pDocument.Get()));
-      pDict->SetFor("ColorSpace", pCS->MakeReference(m_pDocument.Get()));
+      pDict->SetNewFor<CPDF_Reference>("ColorSpace", m_pDocument.Get(),
+                                       pCS->GetObjNum());
     } else {
       pDict->SetNewFor<CPDF_Name>("ColorSpace", "DeviceGray");
     }
@@ -287,7 +288,8 @@
     pMaskDict->SetNewFor<CPDF_Number>("Length", mask_size);
     CPDF_Stream* pNewStream = m_pDocument->NewIndirect<CPDF_Stream>(
         std::move(mask_buf), mask_size, std::move(pMaskDict));
-    pDict->SetFor("SMask", pNewStream->MakeReference(m_pDocument.Get()));
+    pDict->SetNewFor<CPDF_Reference>("SMask", m_pDocument.Get(),
+                                     pNewStream->GetObjNum());
   }
 
   uint8_t* src_buf = pBitmap->GetBuffer();
diff --git a/core/fpdfapi/page/cpdf_streamcontentparser.cpp b/core/fpdfapi/page/cpdf_streamcontentparser.cpp
index 3da7f5f..9527ac3 100644
--- a/core/fpdfapi/page/cpdf_streamcontentparser.cpp
+++ b/core/fpdfapi/page/cpdf_streamcontentparser.cpp
@@ -627,10 +627,12 @@
     ByteString key(word.Right(word.GetLength() - 1));
     auto pObj = m_pSyntax->ReadNextObject(false, false, 0);
     if (!key.IsEmpty()) {
-      if (pObj && !pObj->IsInline())
-        pDict->SetFor(key, pObj->MakeReference(m_pDocument.Get()));
-      else
+      if (pObj && !pObj->IsInline()) {
+        pDict->SetNewFor<CPDF_Reference>(key, m_pDocument.Get(),
+                                         pObj->GetObjNum());
+      } else {
         pDict->SetFor(key, std::move(pObj));
+      }
     }
   }
   ReplaceAbbr(pDict.Get());
diff --git a/core/fpdfapi/parser/cpdf_dictionary.h b/core/fpdfapi/parser/cpdf_dictionary.h
index af14f5c..1087632 100644
--- a/core/fpdfapi/parser/cpdf_dictionary.h
+++ b/core/fpdfapi/parser/cpdf_dictionary.h
@@ -70,12 +70,10 @@
   bool KeyExist(const ByteString& key) const;
   std::vector<ByteString> GetKeys() const;
 
-  // Set* functions invalidate iterators for the element with the key |key|.
-  // Takes ownership of |pObj|, returns an unowned pointer to it.
-  CPDF_Object* SetFor(const ByteString& key, RetainPtr<CPDF_Object> pObj);
-
   // Creates a new object owned by the dictionary and returns an unowned
-  // pointer to it.
+  // pointer to it. Prefer using these templates over calls to SetFor(),
+  // since by creating a new object with no previous references, they ensure
+  // cycles can not be introduced.
   template <typename T, typename... Args>
   typename std::enable_if<!CanInternStrings<T>::value, T*>::type SetNewFor(
       const ByteString& key,
@@ -97,6 +95,10 @@
   void SetRectFor(const ByteString& key, const CFX_FloatRect& rect);
   void SetMatrixFor(const ByteString& key, const CFX_Matrix& matrix);
 
+  // Set* functions invalidate iterators for the element with the key |key|.
+  // Takes ownership of |pObj|, returns an unowned pointer to it.
+  CPDF_Object* SetFor(const ByteString& key, RetainPtr<CPDF_Object> pObj);
+
   void ConvertToIndirectObjectFor(const ByteString& key,
                                   CPDF_IndirectObjectHolder* pHolder);
 
diff --git a/core/fpdfapi/parser/cpdf_document.cpp b/core/fpdfapi/parser/cpdf_document.cpp
index 5b2c416..835b086 100644
--- a/core/fpdfapi/parser/cpdf_document.cpp
+++ b/core/fpdfapi/parser/cpdf_document.cpp
@@ -508,7 +508,7 @@
   pPages->SetNewFor<CPDF_Name>("Type", "Pages");
   pPages->SetNewFor<CPDF_Number>("Count", 0);
   pPages->SetNewFor<CPDF_Array>("Kids");
-  m_pRootDict->SetFor("Pages", pPages->MakeReference(this));
+  m_pRootDict->SetNewFor<CPDF_Reference>("Pages", this, pPages->GetObjNum());
   m_pInfoDict.Reset(NewIndirect<CPDF_Dictionary>());
 }
 
@@ -541,7 +541,8 @@
       }
       if (bInsert) {
         pKidList->InsertAt(i, pPageDict->MakeReference(this));
-        pPageDict->SetFor("Parent", pPages->MakeReference(this));
+        pPageDict->SetNewFor<CPDF_Reference>("Parent", this,
+                                             pPages->GetObjNum());
       } else {
         pKidList->RemoveAt(i);
       }
@@ -585,7 +586,7 @@
       pPagesList = pPages->SetNewFor<CPDF_Array>("Kids");
     pPagesList->Add(pPageDict->MakeReference(this));
     pPages->SetNewFor<CPDF_Number>("Count", nPages + 1);
-    pPageDict->SetFor("Parent", pPages->MakeReference(this));
+    pPageDict->SetNewFor<CPDF_Reference>("Parent", this, pPages->GetObjNum());
     ResetTraversal();
   } else {
     std::set<CPDF_Dictionary*> stack = {pPages};
@@ -654,7 +655,8 @@
     ByteString name = PDF_AdobeNameFromUnicode(pUnicodes[j]);
     pArray->AddNew<CPDF_Name>(name.IsEmpty() ? ".notdef" : name);
   }
-  pBaseDict->SetFor("Encoding", pEncodingDict->MakeReference(this));
+  pBaseDict->SetNewFor<CPDF_Reference>("Encoding", this,
+                                       pEncodingDict->GetObjNum());
   return i;
 }
 
@@ -801,7 +803,8 @@
   CPDF_Dictionary* pFontDesc = ToDictionary(AddIndirectObject(
       CalculateFontDesc(this, basefont, flags, italicangle, pFont->GetAscent(),
                         pFont->GetDescent(), std::move(pBBox), nStemV)));
-  pFontDict->SetFor("FontDescriptor", pFontDesc->MakeReference(this));
+  pFontDict->SetNewFor<CPDF_Reference>("FontDescriptor", this,
+                                       pFontDesc->GetObjNum());
   return LoadFont(pBaseDict);
 }
 
diff --git a/core/fpdfdoc/cpdf_interactiveform.cpp b/core/fpdfdoc/cpdf_interactiveform.cpp
index 6a05b63..3649bc0 100644
--- a/core/fpdfdoc/cpdf_interactiveform.cpp
+++ b/core/fpdfdoc/cpdf_interactiveform.cpp
@@ -82,8 +82,8 @@
 
   if (!pFormDict) {
     pFormDict = pDocument->NewIndirect<CPDF_Dictionary>();
-    pDocument->GetRoot()->SetFor("AcroForm",
-                                 pFormDict->MakeReference(pDocument));
+    pDocument->GetRoot()->SetNewFor<CPDF_Reference>("AcroForm", pDocument,
+                                                    pFormDict->GetObjNum());
   }
 
   ByteString csDA;
@@ -289,7 +289,8 @@
 
   csNameTag->Remove(' ');
   *csNameTag = GenerateNewFontResourceName(pDR, *csNameTag);
-  pFonts->SetFor(*csNameTag, pFont->GetFontDict()->MakeReference(pDocument));
+  pFonts->SetNewFor<CPDF_Reference>(*csNameTag, pDocument,
+                                    pFont->GetFontDict()->GetObjNum());
 }
 
 CPDF_Font* AddNativeFont(CPDF_Dictionary*& pFormDict,
diff --git a/core/fpdfdoc/cpvt_fontmap.cpp b/core/fpdfdoc/cpvt_fontmap.cpp
index c235505..635869a 100644
--- a/core/fpdfdoc/cpvt_fontmap.cpp
+++ b/core/fpdfdoc/cpvt_fontmap.cpp
@@ -40,8 +40,8 @@
 
   CPDF_Dictionary* pFontList = pResDict->GetDictFor("Font");
   if (pFontList && !pFontList->KeyExist(*sSysFontAlias)) {
-    pFontList->SetFor(*sSysFontAlias,
-                      pPDFFont->GetFontDict()->MakeReference(pDoc));
+    pFontList->SetNewFor<CPDF_Reference>(*sSysFontAlias, pDoc,
+                                         pPDFFont->GetFontDict()->GetObjNum());
   }
   return pPDFFont;
 }
diff --git a/core/fpdfdoc/cpvt_generateap.cpp b/core/fpdfdoc/cpvt_generateap.cpp
index fdf2b26..adaff5d 100644
--- a/core/fpdfdoc/cpvt_generateap.cpp
+++ b/core/fpdfdoc/cpvt_generateap.cpp
@@ -408,7 +408,8 @@
   pFontDict->SetNewFor<CPDF_Name>("Encoding", "WinAnsiEncoding");
 
   auto pResourceFontDict = pDoc->New<CPDF_Dictionary>();
-  pResourceFontDict->SetFor(sFontDictName, pFontDict->MakeReference(pDoc));
+  pResourceFontDict->SetNewFor<CPDF_Reference>(sFontDictName, pDoc,
+                                               pFontDict->GetObjNum());
   return pResourceFontDict;
 }
 
@@ -513,7 +514,7 @@
   if (!pAPDict)
     pAPDict = pAnnotDict->SetNewFor<CPDF_Dictionary>(pdfium::annotation::kAP);
 
-  pAPDict->SetFor("N", pNormalStream->MakeReference(pDoc));
+  pAPDict->SetNewFor<CPDF_Reference>("N", pDoc, pNormalStream->GetObjNum());
 
   CPDF_Dictionary* pStreamDict = pNormalStream->GetDict();
   pStreamDict->SetNewFor<CPDF_Number>("FormType", 1);
@@ -949,7 +950,8 @@
     pFontDict->SetNewFor<CPDF_Name>("Subtype", "Type1");
     pFontDict->SetNewFor<CPDF_Name>("BaseFont", CFX_Font::kDefaultAnsiFontName);
     pFontDict->SetNewFor<CPDF_Name>("Encoding", "WinAnsiEncoding");
-    pDRFontDict->SetFor(font_name, pFontDict->MakeReference(pDoc));
+    pDRFontDict->SetNewFor<CPDF_Reference>(font_name, pDoc,
+                                           pFontDict->GetObjNum());
   }
   CPDF_Font* pDefFont = pDoc->LoadFont(pFontDict);
   if (!pDefFont)
@@ -1058,7 +1060,7 @@
   CPDF_Stream* pNormalStream = pAPDict->GetStreamFor("N");
   if (!pNormalStream) {
     pNormalStream = pDoc->NewIndirect<CPDF_Stream>();
-    pAPDict->SetFor("N", pNormalStream->MakeReference(pDoc));
+    pAPDict->SetNewFor<CPDF_Reference>("N", pDoc, pNormalStream->GetObjNum());
   }
   CPDF_Dictionary* pStreamDict = pNormalStream->GetDict();
   if (pStreamDict) {
@@ -1070,7 +1072,8 @@
       if (!pStreamResFontList)
         pStreamResFontList = pStreamResList->SetNewFor<CPDF_Dictionary>("Font");
       if (!pStreamResFontList->KeyExist(font_name)) {
-        pStreamResFontList->SetFor(font_name, pFontDict->MakeReference(pDoc));
+        pStreamResFontList->SetNewFor<CPDF_Reference>(font_name, pDoc,
+                                                      pFontDict->GetObjNum());
       }
     } else {
       pStreamDict->SetFor("Resources", pFormDict->GetDictFor("DR")->Clone());
@@ -1313,7 +1316,8 @@
               pStreamResList->SetNewFor<CPDF_Dictionary>("Font");
         }
         if (!pStreamResFontList->KeyExist(font_name)) {
-          pStreamResFontList->SetFor(font_name, pFontDict->MakeReference(pDoc));
+          pStreamResFontList->SetNewFor<CPDF_Reference>(font_name, pDoc,
+                                                        pFontDict->GetObjNum());
         }
       } else {
         pStreamDict->SetFor("Resources", pFormDict->GetDictFor("DR")->Clone());
diff --git a/fpdfsdk/formfiller/cba_fontmap.cpp b/fpdfsdk/formfiller/cba_fontmap.cpp
index 66678a4..a1f8fe1 100644
--- a/fpdfsdk/formfiller/cba_fontmap.cpp
+++ b/fpdfsdk/formfiller/cba_fontmap.cpp
@@ -293,7 +293,8 @@
   CPDF_Stream* pStream = pAPDict->GetStreamFor(m_sAPType);
   if (!pStream) {
     pStream = m_pDocument->NewIndirect<CPDF_Stream>();
-    pAPDict->SetFor(m_sAPType, pStream->MakeReference(m_pDocument.Get()));
+    pAPDict->SetNewFor<CPDF_Reference>(m_sAPType, m_pDocument.Get(),
+                                       pStream->GetObjNum());
   }
 
   CPDF_Dictionary* pStreamDict = pStream->GetDict();
@@ -309,8 +310,8 @@
   CPDF_Dictionary* pStreamResFontList = pStreamResList->GetDictFor("Font");
   if (!pStreamResFontList) {
     pStreamResFontList = m_pDocument->NewIndirect<CPDF_Dictionary>();
-    pStreamResList->SetFor(
-        "Font", pStreamResFontList->MakeReference(m_pDocument.Get()));
+    pStreamResList->SetNewFor<CPDF_Reference>("Font", m_pDocument.Get(),
+                                              pStreamResFontList->GetObjNum());
   }
   if (!pStreamResFontList->KeyExist(sAlias)) {
     CPDF_Dictionary* pFontDict = pFont->GetFontDict();
diff --git a/fpdfsdk/fpdf_annot.cpp b/fpdfsdk/fpdf_annot.cpp
index 32e49df..a7a7cd8 100644
--- a/fpdfsdk/fpdf_annot.cpp
+++ b/fpdfsdk/fpdf_annot.cpp
@@ -773,9 +773,8 @@
       pApDict = pAnnotDict->SetNewFor<CPDF_Dictionary>(pdfium::annotation::kAP);
 
     ByteString newValue = PDF_EncodeText(WideStringFromFPDFWideString(value));
-    auto pNewApStream = pdfium::MakeRetain<CPDF_Stream>();
+    auto* pNewApStream = pApDict->SetNewFor<CPDF_Stream>(modeKey);
     pNewApStream->SetData(newValue.AsRawSpan());
-    pApDict->SetFor(modeKey, std::move(pNewApStream));
   } else {
     if (pApDict) {
       if (appearanceMode == FPDF_ANNOT_APPEARANCEMODE_NORMAL)
diff --git a/fpdfsdk/fpdf_attachment.cpp b/fpdfsdk/fpdf_attachment.cpp
index 0ba0b1a..259ed65 100644
--- a/fpdfsdk/fpdf_attachment.cpp
+++ b/fpdfsdk/fpdf_attachment.cpp
@@ -75,14 +75,15 @@
   CPDF_Dictionary* pNames = pRoot->GetDictFor("Names");
   if (!pNames) {
     pNames = pDoc->NewIndirect<CPDF_Dictionary>();
-    pRoot->SetFor("Names", pNames->MakeReference(pDoc));
+    pRoot->SetNewFor<CPDF_Reference>("Names", pDoc, pNames->GetObjNum());
   }
 
   // Create the EmbeddedFiles dictionary if missing.
   if (!pNames->GetDictFor("EmbeddedFiles")) {
     CPDF_Dictionary* pFiles = pDoc->NewIndirect<CPDF_Dictionary>();
     pFiles->SetNewFor<CPDF_Array>("Names");
-    pNames->SetFor("EmbeddedFiles", pFiles->MakeReference(pDoc));
+    pNames->SetNewFor<CPDF_Reference>("EmbeddedFiles", pDoc,
+                                      pFiles->GetObjNum());
   }
 
   // Set up the basic entries in the filespec dictionary.
@@ -255,7 +256,7 @@
       std::move(stream), len, std::move(pFileStreamDict));
   CPDF_Dictionary* pEFDict =
       pFile->AsDictionary()->SetNewFor<CPDF_Dictionary>("EF");
-  pEFDict->SetFor("F", pFileStream->MakeReference(pDoc));
+  pEFDict->SetNewFor<CPDF_Reference>("F", pDoc, pFileStream->GetObjNum());
   return true;
 }
 
diff --git a/fpdfsdk/fpdf_edittext.cpp b/fpdfsdk/fpdf_edittext.cpp
index 388f6bb..e39da48 100644
--- a/fpdfsdk/fpdf_edittext.cpp
+++ b/fpdfsdk/fpdf_edittext.cpp
@@ -102,7 +102,7 @@
                                                static_cast<int>(span.size()));
   }
   ByteString fontFile = font_type == FPDF_FONT_TYPE1 ? "FontFile" : "FontFile2";
-  pFontDesc->SetFor(fontFile, pStream->MakeReference(pDoc));
+  pFontDesc->SetNewFor<CPDF_Reference>(fontFile, pDoc, pStream->GetObjNum());
   return pFontDesc;
 }
 
@@ -298,11 +298,13 @@
   }
   pFontDict->SetNewFor<CPDF_Number>("LastChar",
                                     static_cast<int>(dwCurrentChar));
-  pFontDict->SetFor("Widths", widthsArray->MakeReference(pDoc));
+  pFontDict->SetNewFor<CPDF_Reference>("Widths", pDoc,
+                                       widthsArray->GetObjNum());
   CPDF_Dictionary* pFontDesc =
       LoadFontDesc(pDoc, name, pFont.get(), span, font_type);
 
-  pFontDict->SetFor("FontDescriptor", pFontDesc->MakeReference(pDoc));
+  pFontDict->SetNewFor<CPDF_Reference>("FontDescriptor", pDoc,
+                                       pFontDesc->GetObjNum());
   return pDoc->LoadFont(pFontDict);
 }
 
@@ -335,11 +337,13 @@
   pCIDSystemInfo->SetNewFor<CPDF_String>("Registry", "Adobe", false);
   pCIDSystemInfo->SetNewFor<CPDF_String>("Ordering", "Identity", false);
   pCIDSystemInfo->SetNewFor<CPDF_Number>("Supplement", 0);
-  pCIDFont->SetFor("CIDSystemInfo", pCIDSystemInfo->MakeReference(pDoc));
+  pCIDFont->SetNewFor<CPDF_Reference>("CIDSystemInfo", pDoc,
+                                      pCIDSystemInfo->GetObjNum());
 
   CPDF_Dictionary* pFontDesc =
       LoadFontDesc(pDoc, name, pFont.get(), span, font_type);
-  pCIDFont->SetFor("FontDescriptor", pFontDesc->MakeReference(pDoc));
+  pCIDFont->SetNewFor<CPDF_Reference>("FontDescriptor", pDoc,
+                                      pFontDesc->GetObjNum());
 
   uint32_t dwGlyphIndex;
   uint32_t dwCurrentChar = FXFT_Get_First_Char(pFont->GetFace(), &dwGlyphIndex);
@@ -410,14 +414,16 @@
     }
     widthsArray->Add(std::move(curWidthArray));
   }
-  pCIDFont->SetFor("W", widthsArray->MakeReference(pDoc));
+  pCIDFont->SetNewFor<CPDF_Reference>("W", pDoc, widthsArray->GetObjNum());
+
   // TODO(npm): Support vertical writing
 
-  auto pDescendant = pdfium::MakeRetain<CPDF_Array>();
+  auto* pDescendant = pFontDict->SetNewFor<CPDF_Array>("DescendantFonts");
   pDescendant->Add(pCIDFont->MakeReference(pDoc));
-  pFontDict->SetFor("DescendantFonts", std::move(pDescendant));
+
   CPDF_Stream* toUnicodeStream = LoadUnicode(pDoc, to_unicode);
-  pFontDict->SetFor("ToUnicode", toUnicodeStream->MakeReference(pDoc));
+  pFontDict->SetNewFor<CPDF_Reference>("ToUnicode", pDoc,
+                                       toUnicodeStream->GetObjNum());
   return pDoc->LoadFont(pFontDict);
 }
 
diff --git a/fpdfsdk/fpdf_flatten.cpp b/fpdfsdk/fpdf_flatten.cpp
index 5128e22..94cc288 100644
--- a/fpdfsdk/fpdf_flatten.cpp
+++ b/fpdfsdk/fpdf_flatten.cpp
@@ -213,11 +213,10 @@
       sStream += "\nQ";
     }
     pContentsStream->SetDataAndRemoveFilter(sStream.AsRawSpan());
-
     pContentsArray = pDocument->NewIndirect<CPDF_Array>();
     pContentsArray->Add(pContentsStream->MakeReference(pDocument));
-    pPage->SetFor(pdfium::page_object::kContents,
-                  pContentsArray->MakeReference(pDocument));
+    pPage->SetNewFor<CPDF_Reference>(pdfium::page_object::kContents, pDocument,
+                                     pContentsArray->GetObjNum());
   }
   if (!key.IsEmpty()) {
     pContentsArray->Add(
@@ -316,7 +315,9 @@
 
   CPDF_Dictionary* pNewXORes = nullptr;
   if (!key.IsEmpty()) {
-    pPageXObject->SetFor(key, pNewXObject->MakeReference(pDocument));
+    pPageXObject->SetNewFor<CPDF_Reference>(key, pDocument,
+                                            pNewXObject->GetObjNum());
+
     CPDF_Dictionary* pNewOXbjectDic = pNewXObject->GetDict();
     pNewXORes = pNewOXbjectDic->SetNewFor<CPDF_Dictionary>("Resources");
     pNewOXbjectDic->SetNewFor<CPDF_Name>("Type", "XObject");
@@ -392,7 +393,8 @@
       pXObject = pNewXORes->SetNewFor<CPDF_Dictionary>("XObject");
 
     ByteString sFormName = ByteString::Format("F%d", i);
-    pXObject->SetFor(sFormName, pObj->MakeReference(pDocument));
+    pXObject->SetNewFor<CPDF_Reference>(sFormName, pDocument,
+                                        pObj->GetObjNum());
 
     ByteString sStream;
     {
diff --git a/fpdfsdk/fpdf_ppo.cpp b/fpdfsdk/fpdf_ppo.cpp
index 8285e30..5c66f6e 100644
--- a/fpdfsdk/fpdf_ppo.cpp
+++ b/fpdfsdk/fpdf_ppo.cpp
@@ -330,19 +330,19 @@
       pElement ? ToDictionary(pElement->GetDirect()) : nullptr;
   if (!pNewPages) {
     pNewPages = dest()->NewIndirect<CPDF_Dictionary>();
-    pNewRoot->SetFor("Pages", pNewPages->MakeReference(dest()));
+    pNewRoot->SetNewFor<CPDF_Reference>("Pages", dest(),
+                                        pNewPages->GetObjNum());
   }
-
   ByteString cbPageType = pNewPages->GetStringFor("Type", ByteString());
   if (cbPageType.IsEmpty())
     pNewPages->SetNewFor<CPDF_Name>("Type", "Pages");
 
   if (!pNewPages->GetArrayFor("Kids")) {
+    auto* pNewArray = dest()->NewIndirect<CPDF_Array>();
     pNewPages->SetNewFor<CPDF_Number>("Count", 0);
-    pNewPages->SetFor("Kids",
-                      dest()->NewIndirect<CPDF_Array>()->MakeReference(dest()));
+    pNewPages->SetNewFor<CPDF_Reference>("Kids", dest(),
+                                         pNewArray->GetObjNum());
   }
-
   return true;
 }
 
@@ -727,8 +727,8 @@
   CPDF_Stream* pStream =
       dest()->NewIndirect<CPDF_Stream>(nullptr, 0, std::move(pDict));
   pStream->SetData(bsContent.AsRawSpan());
-  pDestPageDict->SetFor(pdfium::page_object::kContents,
-                        pStream->MakeReference(dest()));
+  pDestPageDict->SetNewFor<CPDF_Reference>(pdfium::page_object::kContents,
+                                           dest(), pStream->GetObjNum());
 }
 
 }  // namespace
diff --git a/fpdfsdk/fpdf_transformpage.cpp b/fpdfsdk/fpdf_transformpage.cpp
index ced87f2..3ffbb3b 100644
--- a/fpdfsdk/fpdf_transformpage.cpp
+++ b/fpdfsdk/fpdf_transformpage.cpp
@@ -210,8 +210,8 @@
     pContentArray->Add(pStream->MakeReference(pDoc));
     pContentArray->Add(pContentObj->MakeReference(pDoc));
     pContentArray->Add(pEndStream->MakeReference(pDoc));
-    pPageDict->SetFor(pdfium::page_object::kContents,
-                      pContentArray->MakeReference(pDoc));
+    pPageDict->SetNewFor<CPDF_Reference>(pdfium::page_object::kContents, pDoc,
+                                         pContentArray->GetObjNum());
   }
 
   // Need to transform the patterns as well.
@@ -364,7 +364,7 @@
     CPDF_Array* pContentArray = pDoc->NewIndirect<CPDF_Array>();
     pContentArray->Add(pStream->MakeReference(pDoc));
     pContentArray->Add(pContentObj->MakeReference(pDoc));
-    pPageDict->SetFor(pdfium::page_object::kContents,
-                      pContentArray->MakeReference(pDoc));
+    pPageDict->SetNewFor<CPDF_Reference>(pdfium::page_object::kContents, pDoc,
+                                         pContentArray->GetObjNum());
   }
 }
diff --git a/fpdfsdk/pwl/cpwl_appstream.cpp b/fpdfsdk/pwl/cpwl_appstream.cpp
index ce6d3fb..e2b12da 100644
--- a/fpdfsdk/pwl/cpwl_appstream.cpp
+++ b/fpdfsdk/pwl/cpwl_appstream.cpp
@@ -1901,8 +1901,9 @@
 
   CPDF_Dictionary* pXObject =
       pStreamResList->SetNewFor<CPDF_Dictionary>("XObject");
-  pXObject->SetFor(sImageAlias, pImage->MakeReference(
-                                    widget_->GetPageView()->GetPDFDocument()));
+  pXObject->SetNewFor<CPDF_Reference>(sImageAlias,
+                                      widget_->GetPageView()->GetPDFDocument(),
+                                      pImage->GetObjNum());
 }
 
 void CPWL_AppStream::Write(const ByteString& sAPType,
@@ -1925,7 +1926,7 @@
   if (!pStream) {
     CPDF_Document* doc = widget_->GetPageView()->GetPDFDocument();
     pStream = doc->NewIndirect<CPDF_Stream>();
-    pParentDict->SetFor(sAPType, pStream->MakeReference(doc));
+    pParentDict->SetNewFor<CPDF_Reference>(sAPType, doc, pStream->GetObjNum());
   }
 
   CPDF_Dictionary* pStreamDict = pStream->GetDict();