Introduce CPDF_Array::Find().
Then implement Contains() in terms of Find(). Then use it in one place,
and avoid some casting.
Change-Id: I28225ca94c4544914aaac6a43c7661a7e30ab60f
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/87390
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/parser/cpdf_array.cpp b/core/fpdfapi/parser/cpdf_array.cpp
index 10d8538..708e677 100644
--- a/core/fpdfapi/parser/cpdf_array.cpp
+++ b/core/fpdfapi/parser/cpdf_array.cpp
@@ -88,12 +88,16 @@
GetNumberAt(3), GetNumberAt(4), GetNumberAt(5));
}
-bool CPDF_Array::Contains(const CPDF_Object* pThat) const {
- for (size_t i = 0; i < m_Objects.size(); ++i) {
+absl::optional<size_t> CPDF_Array::Find(const CPDF_Object* pThat) const {
+ for (size_t i = 0; i < size(); ++i) {
if (GetDirectObjectAt(i) == pThat)
- return true;
+ return i;
}
- return false;
+ return absl::nullopt;
+}
+
+bool CPDF_Array::Contains(const CPDF_Object* pThat) const {
+ return Find(pThat).has_value();
}
CPDF_Object* CPDF_Array::GetObjectAt(size_t index) {
diff --git a/core/fpdfapi/parser/cpdf_array.h b/core/fpdfapi/parser/cpdf_array.h
index 5c0c255..6761a97 100644
--- a/core/fpdfapi/parser/cpdf_array.h
+++ b/core/fpdfapi/parser/cpdf_array.h
@@ -7,6 +7,8 @@
#ifndef CORE_FPDFAPI_PARSER_CPDF_ARRAY_H_
#define CORE_FPDFAPI_PARSER_CPDF_ARRAY_H_
+#include <stddef.h>
+
#include <set>
#include <type_traits>
#include <utility>
@@ -16,6 +18,7 @@
#include "core/fpdfapi/parser/cpdf_object.h"
#include "core/fxcrt/fx_coordinates.h"
#include "core/fxcrt/retain_ptr.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "third_party/base/check.h"
// Arrays never contain nullptrs for objects within bounds, but some of the
@@ -69,6 +72,7 @@
CFX_FloatRect GetRect() const;
CFX_Matrix GetMatrix() const;
+ absl::optional<size_t> Find(const CPDF_Object* pThat) const;
bool Contains(const CPDF_Object* pThat) const;
// Creates object owned by the array, returns unowned pointer to it.
diff --git a/core/fpdfapi/parser/cpdf_array_unittest.cpp b/core/fpdfapi/parser/cpdf_array_unittest.cpp
index a70599d..72621e2 100644
--- a/core/fpdfapi/parser/cpdf_array_unittest.cpp
+++ b/core/fpdfapi/parser/cpdf_array_unittest.cpp
@@ -189,6 +189,29 @@
}
}
+TEST(cpdf_array, Find) {
+ auto arr = pdfium::MakeRetain<CPDF_Array>();
+ auto dict0 = pdfium::MakeRetain<CPDF_Dictionary>();
+ auto dict1 = pdfium::MakeRetain<CPDF_Dictionary>();
+ auto dict2 = pdfium::MakeRetain<CPDF_Dictionary>();
+ arr->Append(dict0);
+ arr->Append(dict1);
+
+ absl::optional<size_t> maybe_found = arr->Find(nullptr);
+ EXPECT_FALSE(maybe_found.has_value());
+
+ maybe_found = arr->Find(dict0.Get());
+ ASSERT_TRUE(maybe_found.has_value());
+ EXPECT_EQ(0u, maybe_found.value());
+
+ maybe_found = arr->Find(dict1.Get());
+ ASSERT_TRUE(maybe_found.has_value());
+ EXPECT_EQ(1u, maybe_found.value());
+
+ maybe_found = arr->Find(dict2.Get());
+ EXPECT_FALSE(maybe_found.has_value());
+}
+
TEST(cpdf_array, Contains) {
auto arr = pdfium::MakeRetain<CPDF_Array>();
auto dict0 = pdfium::MakeRetain<CPDF_Dictionary>();
diff --git a/core/fpdfdoc/cpdf_interactiveform.cpp b/core/fpdfdoc/cpdf_interactiveform.cpp
index 16cc1dd..e50f7e1 100644
--- a/core/fpdfdoc/cpdf_interactiveform.cpp
+++ b/core/fpdfdoc/cpdf_interactiveform.cpp
@@ -30,8 +30,10 @@
#include "core/fxcrt/fx_codepage.h"
#include "core/fxge/cfx_substfont.h"
#include "core/fxge/fx_font.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "third_party/base/check.h"
#include "third_party/base/containers/contains.h"
+#include "third_party/base/numerics/safe_conversions.h"
namespace {
@@ -698,19 +700,18 @@
int CPDF_InteractiveForm::FindFieldInCalculationOrder(
const CPDF_FormField* pField) {
- if (!m_pFormDict || !pField)
+ if (!m_pFormDict)
return -1;
CPDF_Array* pArray = m_pFormDict->GetArrayFor("CO");
if (!pArray)
return -1;
- for (size_t i = 0; i < pArray->size(); i++) {
- CPDF_Object* pElement = pArray->GetDirectObjectAt(i);
- if (pElement == pField->GetDict())
- return i;
- }
- return -1;
+ absl::optional<size_t> maybe_found = pArray->Find(pField->GetDict());
+ if (!maybe_found.has_value())
+ return -1;
+
+ return pdfium::base::checked_cast<int>(maybe_found.value());
}
RetainPtr<CPDF_Font> CPDF_InteractiveForm::GetFormFont(
diff --git a/fxjs/cjs_field.cpp b/fxjs/cjs_field.cpp
index bf23543..aef9db0 100644
--- a/fxjs/cjs_field.cpp
+++ b/fxjs/cjs_field.cpp
@@ -950,8 +950,8 @@
CPDFSDK_InteractiveForm* pRDForm = m_pFormFillEnv->GetInteractiveForm();
CPDF_InteractiveForm* pForm = pRDForm->GetInteractiveForm();
- return CJS_Result::Success(pRuntime->NewNumber(
- static_cast<int32_t>(pForm->FindFieldInCalculationOrder(pFormField))));
+ return CJS_Result::Success(
+ pRuntime->NewNumber(pForm->FindFieldInCalculationOrder(pFormField)));
}
CJS_Result CJS_Field::set_calc_order_index(CJS_Runtime* pRuntime,