Add CPDF_Array::GetBooleanAt().

Compared to CPDF_Dictionary, CPDF_Array is missing a GetBooleanAt()
method. Add it to mirror the CPDF_Dictionary version, with unit tests.
Use it in a couple places that expect to be reading booleans.

Change-Id: I71612ac00a5c7e87126a21d2424e6ad98a68264a
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/60652
Commit-Queue: dsinclair <dsinclair@chromium.org>
Reviewed-by: dsinclair <dsinclair@chromium.org>
diff --git a/core/fpdfapi/parser/cpdf_array.cpp b/core/fpdfapi/parser/cpdf_array.cpp
index 1c51341..a7ce4e6 100644
--- a/core/fpdfapi/parser/cpdf_array.cpp
+++ b/core/fpdfapi/parser/cpdf_array.cpp
@@ -9,6 +9,7 @@
 #include <set>
 #include <utility>
 
+#include "core/fpdfapi/parser/cpdf_boolean.h"
 #include "core/fpdfapi/parser/cpdf_name.h"
 #include "core/fpdfapi/parser/cpdf_number.h"
 #include "core/fpdfapi/parser/cpdf_reference.h"
@@ -123,6 +124,13 @@
   return m_Objects[index]->GetUnicodeText();
 }
 
+bool CPDF_Array::GetBooleanAt(size_t index, bool bDefault) const {
+  if (index >= m_Objects.size())
+    return bDefault;
+  const CPDF_Object* p = m_Objects[index].Get();
+  return ToBoolean(p) ? p->GetInteger() != 0 : bDefault;
+}
+
 int CPDF_Array::GetIntegerAt(size_t index) const {
   if (index >= m_Objects.size())
     return 0;
diff --git a/core/fpdfapi/parser/cpdf_array.h b/core/fpdfapi/parser/cpdf_array.h
index 34b7c9a..2a12d99 100644
--- a/core/fpdfapi/parser/cpdf_array.h
+++ b/core/fpdfapi/parser/cpdf_array.h
@@ -43,6 +43,7 @@
   const CPDF_Object* GetDirectObjectAt(size_t index) const;
   ByteString GetStringAt(size_t index) const;
   WideString GetUnicodeTextAt(size_t index) const;
+  bool GetBooleanAt(size_t index, bool bDefault) const;
   int GetIntegerAt(size_t index) const;
   float GetNumberAt(size_t index) const;
   CPDF_Dictionary* GetDictAt(size_t index);
diff --git a/core/fpdfapi/parser/cpdf_array_unittest.cpp b/core/fpdfapi/parser/cpdf_array_unittest.cpp
index a941160..457961f 100644
--- a/core/fpdfapi/parser/cpdf_array_unittest.cpp
+++ b/core/fpdfapi/parser/cpdf_array_unittest.cpp
@@ -7,11 +7,32 @@
 #include <memory>
 #include <utility>
 
+#include "core/fpdfapi/parser/cpdf_boolean.h"
 #include "core/fpdfapi/parser/cpdf_number.h"
 #include "core/fpdfapi/parser/cpdf_reference.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/base/ptr_util.h"
 
+TEST(cpdf_array, GetBooleanAt) {
+  auto arr = pdfium::MakeRetain<CPDF_Array>();
+  arr->AddNew<CPDF_Boolean>(true);
+  arr->AddNew<CPDF_Boolean>(false);
+  arr->AddNew<CPDF_Number>(100);
+  arr->AddNew<CPDF_Number>(0);
+
+  ASSERT_EQ(4u, arr->size());
+  EXPECT_TRUE(arr->GetBooleanAt(0, true));
+  EXPECT_TRUE(arr->GetBooleanAt(0, false));
+  EXPECT_FALSE(arr->GetBooleanAt(1, true));
+  EXPECT_FALSE(arr->GetBooleanAt(1, false));
+  EXPECT_TRUE(arr->GetBooleanAt(2, true));
+  EXPECT_FALSE(arr->GetBooleanAt(2, false));
+  EXPECT_TRUE(arr->GetBooleanAt(3, true));
+  EXPECT_FALSE(arr->GetBooleanAt(3, false));
+  EXPECT_TRUE(arr->GetBooleanAt(99, true));
+  EXPECT_FALSE(arr->GetBooleanAt(99, false));
+}
+
 TEST(cpdf_array, RemoveAt) {
   {
     const int elems[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
diff --git a/core/fpdfapi/render/cpdf_renderstatus.cpp b/core/fpdfapi/render/cpdf_renderstatus.cpp
index 484eff1..d412b52 100644
--- a/core/fpdfapi/render/cpdf_renderstatus.cpp
+++ b/core/fpdfapi/render/cpdf_renderstatus.cpp
@@ -158,13 +158,10 @@
     t_min = pArray->GetNumberAt(0);
     t_max = pArray->GetNumberAt(1);
   }
-  bool bStartExtend = false;
-  bool bEndExtend = false;
   pArray = pDict->GetArrayFor("Extend");
-  if (pArray) {
-    bStartExtend = !!pArray->GetIntegerAt(0);
-    bEndExtend = !!pArray->GetIntegerAt(1);
-  }
+  const bool bStartExtend = pArray && pArray->GetBooleanAt(0, false);
+  const bool bEndExtend = pArray && pArray->GetBooleanAt(1, false);
+
   int width = pBitmap->GetWidth();
   int height = pBitmap->GetHeight();
   float x_span = end_x - start_x;
@@ -231,13 +228,9 @@
     t_min = pArray->GetNumberAt(0);
     t_max = pArray->GetNumberAt(1);
   }
-  bool bStartExtend = false;
-  bool bEndExtend = false;
   pArray = pDict->GetArrayFor("Extend");
-  if (pArray) {
-    bStartExtend = !!pArray->GetIntegerAt(0);
-    bEndExtend = !!pArray->GetIntegerAt(1);
-  }
+  const bool bStartExtend = pArray && pArray->GetBooleanAt(0, false);
+  const bool bEndExtend = pArray && pArray->GetBooleanAt(1, false);
 
   std::array<FX_ARGB, kShadingSteps> shading_steps =
       GetShadingSteps(t_min, t_max, funcs, pCS, alpha, total_results);