Introduce CPDF_Array::Contains() Use Contains() in CPDF_OCContext in place of FindGroup(). Note that FindGroup() should have probably returned a bool in the first place, since we only test for a found/not-found result. -- add unit test. -- slightly re-order header to match cpp. -- de-dup some code with calls to GetObjectAt(). Change-Id: I4ce31652f212e83014555e6b282c27cba5e90455 Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/87370 Commit-Queue: Tom Sepez <tsepez@chromium.org> Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/page/cpdf_occontext.cpp b/core/fpdfapi/page/cpdf_occontext.cpp index 21b8ec6..1318ad8 100644 --- a/core/fpdfapi/page/cpdf_occontext.cpp +++ b/core/fpdfapi/page/cpdf_occontext.cpp
@@ -14,17 +14,6 @@ namespace { -int32_t FindGroup(const CPDF_Array* pArray, const CPDF_Dictionary* pGroupDict) { - if (!pArray || !pGroupDict) - return -1; - - for (size_t i = 0; i < pArray->size(); i++) { - if (pArray->GetDictAt(i) == pGroupDict) - return i; - } - return -1; -} - bool HasIntent(const CPDF_Dictionary* pDict, ByteStringView csElement, ByteStringView csDef) { @@ -56,7 +45,7 @@ if (!pOCGs) return nullptr; - if (FindGroup(pOCGs, pOCGDict) < 0) + if (!pOCGs->Contains(pOCGDict)) return nullptr; CPDF_Dictionary* pConfig = pOCProperties->GetDictFor("D"); @@ -109,15 +98,13 @@ bool bState = pConfig->GetStringFor("BaseState", "ON") != "OFF"; CPDF_Array* pArray = pConfig->GetArrayFor("ON"); - if (pArray) { - if (FindGroup(pArray, pOCGDict) >= 0) - bState = true; - } + if (pArray && pArray->Contains(pOCGDict)) + bState = true; + pArray = pConfig->GetArrayFor("OFF"); - if (pArray) { - if (FindGroup(pArray, pOCGDict) >= 0) - bState = false; - } + if (pArray && pArray->Contains(pOCGDict)) + bState = false; + pArray = pConfig->GetArrayFor("AS"); if (!pArray) return bState; @@ -135,7 +122,7 @@ if (!pOCGs) continue; - if (FindGroup(pOCGs, pOCGDict) < 0) + if (!pOCGs->Contains(pOCGDict)) continue; CPDF_Dictionary* pState = pUsage->GetDictFor(csConfig);
diff --git a/core/fpdfapi/parser/cpdf_array.cpp b/core/fpdfapi/parser/cpdf_array.cpp index 719d918..10d8538 100644 --- a/core/fpdfapi/parser/cpdf_array.cpp +++ b/core/fpdfapi/parser/cpdf_array.cpp
@@ -88,6 +88,14 @@ 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) { + if (GetDirectObjectAt(i) == pThat) + return true; + } + return false; +} + CPDF_Object* CPDF_Array::GetObjectAt(size_t index) { if (index >= m_Objects.size()) return nullptr; @@ -101,15 +109,13 @@ } CPDF_Object* CPDF_Array::GetDirectObjectAt(size_t index) { - if (index >= m_Objects.size()) - return nullptr; - return m_Objects[index]->GetDirect(); + CPDF_Object* pObj = GetObjectAt(index); + return pObj ? pObj->GetDirect() : nullptr; } const CPDF_Object* CPDF_Array::GetDirectObjectAt(size_t index) const { - if (index >= m_Objects.size()) - return nullptr; - return m_Objects[index]->GetDirect(); + const CPDF_Object* pObj = GetObjectAt(index); + return pObj ? pObj->GetDirect() : nullptr; } ByteString CPDF_Array::GetStringAt(size_t index) const {
diff --git a/core/fpdfapi/parser/cpdf_array.h b/core/fpdfapi/parser/cpdf_array.h index d3288bd..5c0c255 100644 --- a/core/fpdfapi/parser/cpdf_array.h +++ b/core/fpdfapi/parser/cpdf_array.h
@@ -66,8 +66,10 @@ CPDF_Array* GetArrayAt(size_t index); const CPDF_Array* GetArrayAt(size_t index) const; - CFX_Matrix GetMatrix() const; CFX_FloatRect GetRect() const; + CFX_Matrix GetMatrix() const; + + bool Contains(const CPDF_Object* pThat) const; // Creates object owned by the array, returns unowned pointer to it. // We have special cases for objects that can intern strings from
diff --git a/core/fpdfapi/parser/cpdf_array_unittest.cpp b/core/fpdfapi/parser/cpdf_array_unittest.cpp index e8c143b..a70599d 100644 --- a/core/fpdfapi/parser/cpdf_array_unittest.cpp +++ b/core/fpdfapi/parser/cpdf_array_unittest.cpp
@@ -8,6 +8,7 @@ #include <utility> #include "core/fpdfapi/parser/cpdf_boolean.h" +#include "core/fpdfapi/parser/cpdf_dictionary.h" #include "core/fpdfapi/parser/cpdf_number.h" #include "core/fpdfapi/parser/cpdf_reference.h" #include "testing/gtest/include/gtest/gtest.h" @@ -188,6 +189,18 @@ } } +TEST(cpdf_array, Contains) { + 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); + EXPECT_TRUE(arr->Contains(dict0.Get())); + EXPECT_TRUE(arr->Contains(dict1.Get())); + EXPECT_FALSE(arr->Contains(dict2.Get())); +} + TEST(cpdf_array, Iterator) { const int elems[] = {-23, -11, 3, 455, 2345877, 0, 7895330, -12564334, 10000, -100000};