1// Copyright 2017 PDFium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "core/fpdfapi/parser/cpdf_indirect_object_holder.h" 6 7#include <memory> 8#include <utility> 9 10#include "core/fpdfapi/parser/cpdf_null.h" 11#include "testing/gmock/include/gmock/gmock.h" 12#include "testing/gtest/include/gtest/gtest.h" 13#include "third_party/base/ptr_util.h" 14 15namespace { 16 17class MockIndirectObjectHolder : public CPDF_IndirectObjectHolder { 18 public: 19 MockIndirectObjectHolder() {} 20 ~MockIndirectObjectHolder() override {} 21 22 MOCK_METHOD1(ParseIndirectObject, 23 std::unique_ptr<CPDF_Object>(uint32_t objnum)); 24}; 25 26} // namespace 27 28TEST(CPDF_IndirectObjectHolderTest, RecursiveParseOfSameObject) { 29 MockIndirectObjectHolder mock_holder; 30 // ParseIndirectObject should not be called again on recursively same object 31 // parse request. 32 EXPECT_CALL(mock_holder, ParseIndirectObject(::testing::_)) 33 .WillOnce(::testing::WithArg<0>(::testing::Invoke( 34 [&mock_holder](uint32_t objnum) -> std::unique_ptr<CPDF_Object> { 35 const CPDF_Object* same_parse = 36 mock_holder.GetOrParseIndirectObject(objnum); 37 CHECK(!same_parse); 38 return pdfium::MakeUnique<CPDF_Null>(); 39 }))); 40 41 EXPECT_TRUE(mock_holder.GetOrParseIndirectObject(1000)); 42} 43 44TEST(CPDF_IndirectObjectHolderTest, GetObjectMethods) { 45 static constexpr uint32_t kObjNum = 1000; 46 MockIndirectObjectHolder mock_holder; 47 48 EXPECT_CALL(mock_holder, ParseIndirectObject(::testing::_)).Times(0); 49 EXPECT_FALSE(mock_holder.GetIndirectObject(kObjNum)); 50 ::testing::Mock::VerifyAndClearExpectations(&mock_holder); 51 52 EXPECT_CALL(mock_holder, ParseIndirectObject(::testing::_)) 53 .WillOnce(::testing::WithArg<0>(::testing::Invoke( 54 [](uint32_t objnum) -> std::unique_ptr<CPDF_Object> { 55 return pdfium::MakeUnique<CPDF_Null>(); 56 }))); 57 EXPECT_TRUE(mock_holder.GetOrParseIndirectObject(kObjNum)); 58 ::testing::Mock::VerifyAndClearExpectations(&mock_holder); 59 60 EXPECT_CALL(mock_holder, ParseIndirectObject(::testing::_)).Times(0); 61 ASSERT_TRUE(mock_holder.GetIndirectObject(kObjNum)); 62 ::testing::Mock::VerifyAndClearExpectations(&mock_holder); 63 64 EXPECT_EQ(kObjNum, mock_holder.GetIndirectObject(kObjNum)->GetObjNum()); 65} 66 67TEST(CPDF_IndirectObjectHolderTest, ParseInvalidObjNum) { 68 MockIndirectObjectHolder mock_holder; 69 70 EXPECT_CALL(mock_holder, ParseIndirectObject(::testing::_)).Times(0); 71 EXPECT_FALSE( 72 mock_holder.GetOrParseIndirectObject(CPDF_Object::kInvalidObjNum)); 73} 74 75TEST(CPDF_IndirectObjectHolderTest, ReplaceObjectWithInvalidObjNum) { 76 MockIndirectObjectHolder mock_holder; 77 78 EXPECT_CALL(mock_holder, ParseIndirectObject(::testing::_)).Times(0); 79 EXPECT_FALSE(mock_holder.ReplaceIndirectObjectIfHigherGeneration( 80 CPDF_Object::kInvalidObjNum, pdfium::MakeUnique<CPDF_Null>())); 81} 82