// Copyright 2017 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/parser/cpdf_indirect_object_holder.h" #include #include #include "core/fpdfapi/parser/cpdf_null.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/base/ptr_util.h" namespace { class MockIndirectObjectHolder final : public CPDF_IndirectObjectHolder { public: MockIndirectObjectHolder() {} ~MockIndirectObjectHolder() override {} MOCK_METHOD1(ParseIndirectObject, std::unique_ptr(uint32_t objnum)); }; } // namespace TEST(CPDF_IndirectObjectHolderTest, RecursiveParseOfSameObject) { MockIndirectObjectHolder mock_holder; // ParseIndirectObject should not be called again on recursively same object // parse request. EXPECT_CALL(mock_holder, ParseIndirectObject(::testing::_)) .WillOnce(::testing::WithArg<0>(::testing::Invoke( [&mock_holder](uint32_t objnum) -> std::unique_ptr { const CPDF_Object* same_parse = mock_holder.GetOrParseIndirectObject(objnum); CHECK(!same_parse); return pdfium::MakeUnique(); }))); EXPECT_TRUE(mock_holder.GetOrParseIndirectObject(1000)); } TEST(CPDF_IndirectObjectHolderTest, GetObjectMethods) { static constexpr uint32_t kObjNum = 1000; MockIndirectObjectHolder mock_holder; EXPECT_CALL(mock_holder, ParseIndirectObject(::testing::_)).Times(0); EXPECT_FALSE(mock_holder.GetIndirectObject(kObjNum)); ::testing::Mock::VerifyAndClearExpectations(&mock_holder); EXPECT_CALL(mock_holder, ParseIndirectObject(::testing::_)) .WillOnce(::testing::WithArg<0>(::testing::Invoke( [](uint32_t objnum) -> std::unique_ptr { return pdfium::MakeUnique(); }))); EXPECT_TRUE(mock_holder.GetOrParseIndirectObject(kObjNum)); ::testing::Mock::VerifyAndClearExpectations(&mock_holder); EXPECT_CALL(mock_holder, ParseIndirectObject(::testing::_)).Times(0); ASSERT_TRUE(mock_holder.GetIndirectObject(kObjNum)); ::testing::Mock::VerifyAndClearExpectations(&mock_holder); EXPECT_EQ(kObjNum, mock_holder.GetIndirectObject(kObjNum)->GetObjNum()); } TEST(CPDF_IndirectObjectHolderTest, ParseInvalidObjNum) { MockIndirectObjectHolder mock_holder; EXPECT_CALL(mock_holder, ParseIndirectObject(::testing::_)).Times(0); EXPECT_FALSE( mock_holder.GetOrParseIndirectObject(CPDF_Object::kInvalidObjNum)); } TEST(CPDF_IndirectObjectHolderTest, ReplaceObjectWithInvalidObjNum) { MockIndirectObjectHolder mock_holder; EXPECT_CALL(mock_holder, ParseIndirectObject(::testing::_)).Times(0); EXPECT_FALSE(mock_holder.ReplaceIndirectObjectIfHigherGeneration( CPDF_Object::kInvalidObjNum, pdfium::MakeUnique())); }