Do not let CPDF_Array::SetAt() and friends take a CPDF_Stream

Use `= delete` to disallow SetAt() from taking a CPDF_Stream directly.
Then update the unit test that does pass in a CPDF_Stream to properly
use CPDF_Reference instead. Do the same for InsertAt() and Append().

Along the way, rename a few variables to follow the style guide.

Bug: pdfium:2119
Change-Id: Idc24223bf2433dbe87167ec0ad21e2cf3b7af5b1
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/115711
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/parser/cpdf_array.cpp b/core/fpdfapi/parser/cpdf_array.cpp
index 55b82e7..3d51a9f 100644
--- a/core/fpdfapi/parser/cpdf_array.cpp
+++ b/core/fpdfapi/parser/cpdf_array.cpp
@@ -214,16 +214,16 @@
   m_Objects[index] = m_Objects[index]->MakeReference(pHolder);
 }
 
-void CPDF_Array::SetAt(size_t index, RetainPtr<CPDF_Object> pObj) {
-  (void)SetAtInternal(index, std::move(pObj));
+void CPDF_Array::SetAt(size_t index, RetainPtr<CPDF_Object> object) {
+  (void)SetAtInternal(index, std::move(object));
 }
 
-void CPDF_Array::InsertAt(size_t index, RetainPtr<CPDF_Object> pObj) {
-  (void)InsertAtInternal(index, std::move(pObj));
+void CPDF_Array::InsertAt(size_t index, RetainPtr<CPDF_Object> object) {
+  (void)InsertAtInternal(index, std::move(object));
 }
 
-void CPDF_Array::Append(RetainPtr<CPDF_Object> pObj) {
-  (void)AppendInternal(std::move(pObj));
+void CPDF_Array::Append(RetainPtr<CPDF_Object> object) {
+  (void)AppendInternal(std::move(object));
 }
 
 CPDF_Object* CPDF_Array::SetAtInternal(size_t index,
diff --git a/core/fpdfapi/parser/cpdf_array.h b/core/fpdfapi/parser/cpdf_array.h
index ea9a815..2554809 100644
--- a/core/fpdfapi/parser/cpdf_array.h
+++ b/core/fpdfapi/parser/cpdf_array.h
@@ -117,19 +117,22 @@
         index, pdfium::MakeRetain<T>(m_pPool, std::forward<Args>(args)...))));
   }
 
-  // Adds non-null `pObj` to the end of the array, growing as appropriate.
-  void Append(RetainPtr<CPDF_Object> pObj);
+  // Adds non-null `object` to the end of the array, growing as appropriate.
+  void Append(RetainPtr<CPDF_Object> object);
+  void Append(RetainPtr<CPDF_Stream> stream) = delete;
 
-  // Overwrites the object at `index` with non-null `pObj`, if it is
-  // in bounds. Otherwise, `index` is out of bounds, and `pObj` is
+  // Overwrites the object at `index` with non-null `object`, if it is
+  // in bounds. Otherwise, `index` is out of bounds, and `object` is
   // not stored.
-  void SetAt(size_t index, RetainPtr<CPDF_Object> pObj);
+  void SetAt(size_t index, RetainPtr<CPDF_Object> object);
+  void SetAt(size_t index, RetainPtr<CPDF_Stream> stream) = delete;
 
-  // Inserts non-null `pObj` at `index` and shifts by one position all of the
+  // Inserts non-null `object` at `index` and shifts by one position all of the
   // objects beyond it like std::vector::insert(), if `index` is less than or
   // equal to the current array size. Otherwise, `index` is out of bounds,
-  // and `pObj` is not stored.
-  void InsertAt(size_t index, RetainPtr<CPDF_Object> pObj);
+  // and `object` is not stored.
+  void InsertAt(size_t index, RetainPtr<CPDF_Object> object);
+  void InsertAt(size_t index, RetainPtr<CPDF_Stream> stream) = delete;
 
   void Clear();
   void RemoveAt(size_t index);
diff --git a/core/fpdfapi/parser/cpdf_object_walker_unittest.cpp b/core/fpdfapi/parser/cpdf_object_walker_unittest.cpp
index ab0c2c3..a45c111 100644
--- a/core/fpdfapi/parser/cpdf_object_walker_unittest.cpp
+++ b/core/fpdfapi/parser/cpdf_object_walker_unittest.cpp
@@ -64,26 +64,36 @@
 }
 
 TEST(ObjectWalkerTest, CombinedObject) {
+  CPDF_IndirectObjectHolder holder;
   auto dict = pdfium::MakeRetain<CPDF_Dictionary>();
   dict->SetFor("1", pdfium::MakeRetain<CPDF_String>());
   dict->SetFor("2", pdfium::MakeRetain<CPDF_Boolean>());
   auto array = pdfium::MakeRetain<CPDF_Array>();
   array->Append(pdfium::MakeRetain<CPDF_Reference>(nullptr, 0));
   array->Append(pdfium::MakeRetain<CPDF_Null>());
+  auto stream =
+      holder.NewIndirect<CPDF_Stream>(pdfium::MakeRetain<CPDF_Dictionary>());
+  ASSERT_TRUE(stream);
+  const uint32_t stream_object_number = stream->GetObjNum();
+  ASSERT_GT(stream_object_number, 0u);
   array->Append(
-      pdfium::MakeRetain<CPDF_Stream>(pdfium::MakeRetain<CPDF_Dictionary>()));
+      pdfium::MakeRetain<CPDF_Reference>(&holder, stream_object_number));
   dict->SetFor("3", std::move(array));
-  // The last number for stream length.
-  EXPECT_EQ(Walk(dict), "Dict Str Bool Arr Ref Null Stream Dict Num");
+  EXPECT_EQ(Walk(dict), "Dict Str Bool Arr Ref Null Ref");
 }
 
 TEST(ObjectWalkerTest, GetParent) {
+  CPDF_IndirectObjectHolder holder;
   auto level_4 = pdfium::MakeRetain<CPDF_Number>(0);
   auto level_3 = pdfium::MakeRetain<CPDF_Dictionary>();
   level_3->SetFor("Length", std::move(level_4));
-  auto level_2 = pdfium::MakeRetain<CPDF_Stream>(std::move(level_3));
+  auto level_2 = holder.NewIndirect<CPDF_Stream>(std::move(level_3));
+  ASSERT_TRUE(level_2);
+  const uint32_t level_2_object_number = level_2->GetObjNum();
+  ASSERT_GT(level_2_object_number, 0u);
   auto level_1 = pdfium::MakeRetain<CPDF_Array>();
-  level_1->Append(std::move(level_2));
+  level_1->Append(
+      pdfium::MakeRetain<CPDF_Reference>(&holder, level_2_object_number));
   auto level_0 = pdfium::MakeRetain<CPDF_Dictionary>();
   level_0->SetFor("Array", std::move(level_1));
 
diff --git a/core/fpdfapi/render/cpdf_docrenderdata_unittest.cpp b/core/fpdfapi/render/cpdf_docrenderdata_unittest.cpp
index df7bb1c..88296e6 100644
--- a/core/fpdfapi/render/cpdf_docrenderdata_unittest.cpp
+++ b/core/fpdfapi/render/cpdf_docrenderdata_unittest.cpp
@@ -11,7 +11,9 @@
 #include "core/fpdfapi/page/cpdf_transferfunc.h"
 #include "core/fpdfapi/parser/cpdf_array.h"
 #include "core/fpdfapi/parser/cpdf_dictionary.h"
+#include "core/fpdfapi/parser/cpdf_indirect_object_holder.h"
 #include "core/fpdfapi/parser/cpdf_number.h"
+#include "core/fpdfapi/parser/cpdf_reference.h"
 #include "core/fpdfapi/parser/cpdf_stream.h"
 #include "core/fxcrt/data_vector.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -70,7 +72,8 @@
     26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
     26, 26, 26, 26, 26, 26, 26, 26, 26};
 
-RetainPtr<CPDF_Stream> CreateType0FunctionStream() {
+RetainPtr<CPDF_Reference> CreateType0FunctionStreamReference(
+    CPDF_IndirectObjectHolder& holder) {
   auto func_dict = pdfium::MakeRetain<CPDF_Dictionary>();
   func_dict->SetNewFor<CPDF_Number>("FunctionType", 0);
   func_dict->SetNewFor<CPDF_Number>("BitsPerSample", 8);
@@ -87,9 +90,10 @@
   size_array->AppendNew<CPDF_Number>(4);
 
   static constexpr uint8_t kContents[] = "1234";
-  return pdfium::MakeRetain<CPDF_Stream>(
+  auto stream = holder.NewIndirect<CPDF_Stream>(
       DataVector<uint8_t>(std::begin(kContents), std::end(kContents)),
       std::move(func_dict));
+  return pdfium::MakeRetain<CPDF_Reference>(&holder, stream->GetObjNum());
 }
 
 RetainPtr<CPDF_Dictionary> CreateType2FunctionDict() {
@@ -114,7 +118,8 @@
   return func_dict;
 }
 
-RetainPtr<CPDF_Stream> CreateType4FunctionStream() {
+RetainPtr<CPDF_Reference> CreateType4FunctionStreamReference(
+    CPDF_IndirectObjectHolder& holder) {
   auto func_dict = pdfium::MakeRetain<CPDF_Dictionary>();
   func_dict->SetNewFor<CPDF_Number>("FunctionType", 4);
 
@@ -127,9 +132,10 @@
   range_array->AppendNew<CPDF_Number>(1);
 
   static constexpr uint8_t kContents[] = "{ 360 mul sin 2 div }";
-  return pdfium::MakeRetain<CPDF_Stream>(
+  auto stream = holder.NewIndirect<CPDF_Stream>(
       DataVector<uint8_t>(std::begin(kContents), std::end(kContents)),
       std::move(func_dict));
+  return pdfium::MakeRetain<CPDF_Reference>(&holder, stream->GetObjNum());
 }
 
 RetainPtr<CPDF_Stream> CreateBadType4FunctionStream() {
@@ -194,10 +200,11 @@
 }
 
 TEST(CPDF_DocRenderDataTest, TransferFunctionArray) {
+  CPDF_IndirectObjectHolder holder;
   auto func_array = pdfium::MakeRetain<CPDF_Array>();
-  func_array->Append(CreateType0FunctionStream());
+  func_array->Append(CreateType0FunctionStreamReference(holder));
   func_array->Append(CreateType2FunctionDict());
-  func_array->Append(CreateType4FunctionStream());
+  func_array->Append(CreateType4FunctionStreamReference(holder));
 
   TestDocRenderData render_data;
   auto func = render_data.CreateTransferFuncForTesting(func_array);
@@ -247,10 +254,15 @@
   }
 
   {
+    CPDF_IndirectObjectHolder holder;
     auto func_array = pdfium::MakeRetain<CPDF_Array>();
-    func_array->Append(CreateType0FunctionStream());
+    func_array->Append(CreateType0FunctionStreamReference(holder));
     func_array->Append(CreateType2FunctionDict());
-    func_array->Append(CreateBadType4FunctionStream());
+    auto func_stream = CreateBadType4FunctionStream();
+    const int func_stream_object_number =
+        holder.AddIndirectObject(std::move(func_stream));
+    func_array->Append(
+        pdfium::MakeRetain<CPDF_Reference>(&holder, func_stream_object_number));
 
     TestDocRenderData render_data;
     auto func = render_data.CreateTransferFuncForTesting(func_array);