Add unit tests for cpdf_function.

CPDF_Function is well-covered by both docrenderdata unittest and
pixel/corpus tests, but add a few error cases.

- make IntegerToFunctionType() an anonymous function

Change-Id: I1cba054e946bde898d1e138dca71c55f327cd1f9
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/67850
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fpdfapi/page/BUILD.gn b/core/fpdfapi/page/BUILD.gn
index 2ab0b72..c762cdc 100644
--- a/core/fpdfapi/page/BUILD.gn
+++ b/core/fpdfapi/page/BUILD.gn
@@ -118,11 +118,15 @@
 pdfium_unittest_source_set("unittests") {
   sources = [
     "cpdf_devicecs_unittest.cpp",
+    "cpdf_function_unittest.cpp",
     "cpdf_pageobjectholder_unittest.cpp",
     "cpdf_psengine_unittest.cpp",
     "cpdf_streamcontentparser_unittest.cpp",
     "cpdf_streamparser_unittest.cpp",
   ]
-  deps = [ ":page" ]
+  deps = [
+    ":page",
+    "../parser",
+  ]
   pdfium_root_dir = "../../../"
 }
diff --git a/core/fpdfapi/page/cpdf_function.cpp b/core/fpdfapi/page/cpdf_function.cpp
index 688c48e..055a979 100644
--- a/core/fpdfapi/page/cpdf_function.cpp
+++ b/core/fpdfapi/page/cpdf_function.cpp
@@ -20,6 +20,22 @@
 #include "third_party/base/ptr_util.h"
 #include "third_party/base/stl_util.h"
 
+namespace {
+
+CPDF_Function::Type IntegerToFunctionType(int iType) {
+  switch (iType) {
+    case 0:
+    case 2:
+    case 3:
+    case 4:
+      return static_cast<CPDF_Function::Type>(iType);
+    default:
+      return CPDF_Function::Type::kTypeInvalid;
+  }
+}
+
+}  // namespace
+
 // static
 std::unique_ptr<CPDF_Function> CPDF_Function::Load(
     const CPDF_Object* pFuncObj) {
@@ -61,19 +77,6 @@
   return pFunc;
 }
 
-// static
-CPDF_Function::Type CPDF_Function::IntegerToFunctionType(int iType) {
-  switch (iType) {
-    case 0:
-    case 2:
-    case 3:
-    case 4:
-      return static_cast<Type>(iType);
-    default:
-      return Type::kTypeInvalid;
-  }
-}
-
 CPDF_Function::CPDF_Function(Type type) : m_Type(type) {}
 
 CPDF_Function::~CPDF_Function() = default;
diff --git a/core/fpdfapi/page/cpdf_function.h b/core/fpdfapi/page/cpdf_function.h
index 5f4e125..91fa31e 100644
--- a/core/fpdfapi/page/cpdf_function.h
+++ b/core/fpdfapi/page/cpdf_function.h
@@ -27,7 +27,6 @@
   };
 
   static std::unique_ptr<CPDF_Function> Load(const CPDF_Object* pFuncObj);
-  static Type IntegerToFunctionType(int iType);
 
   virtual ~CPDF_Function();
 
diff --git a/core/fpdfapi/page/cpdf_function_unittest.cpp b/core/fpdfapi/page/cpdf_function_unittest.cpp
new file mode 100644
index 0000000..e07ff16
--- /dev/null
+++ b/core/fpdfapi/page/cpdf_function_unittest.cpp
@@ -0,0 +1,43 @@
+// Copyright 2020 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "core/fpdfapi/page/cpdf_function.h"
+
+#include "core/fpdfapi/parser/cpdf_array.h"
+#include "core/fpdfapi/parser/cpdf_dictionary.h"
+#include "core/fpdfapi/parser/cpdf_number.h"
+#include "core/fxcrt/retain_ptr.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+TEST(CPDFFunction, BadFunctionType) {
+  auto pDict = pdfium::MakeRetain<CPDF_Dictionary>();
+  pDict->SetNewFor<CPDF_Number>("FunctionType", -2);
+  EXPECT_EQ(nullptr, CPDF_Function::Load(pDict.Get()));
+
+  pDict->SetNewFor<CPDF_Number>("FunctionType", 5);
+  EXPECT_EQ(nullptr, CPDF_Function::Load(pDict.Get()));
+}
+
+TEST(CPDFFunction, NoDomain) {
+  auto pDict = pdfium::MakeRetain<CPDF_Dictionary>();
+  pDict->SetNewFor<CPDF_Number>("FunctionType", 0);
+  EXPECT_EQ(nullptr, CPDF_Function::Load(pDict.Get()));
+}
+
+TEST(CPDFFunction, EmptyDomain) {
+  auto pDict = pdfium::MakeRetain<CPDF_Dictionary>();
+  pDict->SetNewFor<CPDF_Number>("FunctionType", 0);
+  pDict->SetNewFor<CPDF_Array>("Domain");
+  EXPECT_EQ(nullptr, CPDF_Function::Load(pDict.Get()));
+}
+
+TEST(CPDFFunction, NoRange) {
+  auto pDict = pdfium::MakeRetain<CPDF_Dictionary>();
+  pDict->SetNewFor<CPDF_Number>("FunctionType", 0);
+
+  CPDF_Array* pArray = pDict->SetNewFor<CPDF_Array>("Domain");
+  pArray->AddNew<CPDF_Number>(0);
+  pArray->AddNew<CPDF_Number>(10);
+  EXPECT_EQ(nullptr, CPDF_Function::Load(pDict.Get()));
+}