xref: /aosp_15_r20/external/pdfium/core/fpdfapi/parser/cpdf_indirect_object_holder_unittest.cpp (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
1 // Copyright 2017 The PDFium Authors
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 "core/fpdfapi/parser/cpdf_array.h"
8 #include "core/fpdfapi/parser/cpdf_dictionary.h"
9 #include "core/fpdfapi/parser/cpdf_null.h"
10 #include "testing/gmock/include/gmock/gmock.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12 #include "third_party/base/check.h"
13 
14 namespace {
15 
16 class MockIndirectObjectHolder final : public CPDF_IndirectObjectHolder {
17  public:
18   MockIndirectObjectHolder() = default;
19   ~MockIndirectObjectHolder() override = default;
20 
21   MOCK_METHOD1(ParseIndirectObject, RetainPtr<CPDF_Object>(uint32_t objnum));
22 };
23 
24 }  // namespace
25 
TEST(IndirectObjectHolderTest,RecursiveParseOfSameObject)26 TEST(IndirectObjectHolderTest, RecursiveParseOfSameObject) {
27   MockIndirectObjectHolder mock_holder;
28   // ParseIndirectObject should not be called again on recursively same object
29   // parse request.
30   EXPECT_CALL(mock_holder, ParseIndirectObject(::testing::_))
31       .WillOnce(::testing::WithArg<0>(::testing::Invoke(
32           [&mock_holder](uint32_t objnum) -> RetainPtr<CPDF_Object> {
33             RetainPtr<const CPDF_Object> same_parse =
34                 mock_holder.GetOrParseIndirectObject(objnum);
35             CHECK(!same_parse);
36             return pdfium::MakeRetain<CPDF_Null>();
37           })));
38 
39   EXPECT_TRUE(mock_holder.GetOrParseIndirectObject(1000));
40 }
41 
TEST(IndirectObjectHolderTest,GetObjectMethods)42 TEST(IndirectObjectHolderTest, GetObjectMethods) {
43   static constexpr uint32_t kObjNum = 1000;
44   MockIndirectObjectHolder mock_holder;
45 
46   EXPECT_CALL(mock_holder, ParseIndirectObject(::testing::_)).Times(0);
47   EXPECT_FALSE(mock_holder.GetIndirectObject(kObjNum));
48   ::testing::Mock::VerifyAndClearExpectations(&mock_holder);
49 
50   EXPECT_CALL(mock_holder, ParseIndirectObject(::testing::_))
51       .WillOnce(::testing::WithArg<0>(
52           ::testing::Invoke([](uint32_t objnum) -> RetainPtr<CPDF_Object> {
53             return pdfium::MakeRetain<CPDF_Null>();
54           })));
55   EXPECT_TRUE(mock_holder.GetOrParseIndirectObject(kObjNum));
56   ::testing::Mock::VerifyAndClearExpectations(&mock_holder);
57 
58   EXPECT_CALL(mock_holder, ParseIndirectObject(::testing::_)).Times(0);
59   ASSERT_TRUE(mock_holder.GetIndirectObject(kObjNum));
60   ::testing::Mock::VerifyAndClearExpectations(&mock_holder);
61 
62   EXPECT_EQ(kObjNum, mock_holder.GetIndirectObject(kObjNum)->GetObjNum());
63 }
64 
TEST(IndirectObjectHolderTest,ParseInvalidObjNum)65 TEST(IndirectObjectHolderTest, ParseInvalidObjNum) {
66   MockIndirectObjectHolder mock_holder;
67 
68   EXPECT_CALL(mock_holder, ParseIndirectObject(::testing::_)).Times(0);
69   EXPECT_FALSE(
70       mock_holder.GetOrParseIndirectObject(CPDF_Object::kInvalidObjNum));
71 }
72 
TEST(IndirectObjectHolderTest,ReplaceObjectWithInvalidObjNum)73 TEST(IndirectObjectHolderTest, ReplaceObjectWithInvalidObjNum) {
74   MockIndirectObjectHolder mock_holder;
75 
76   EXPECT_CALL(mock_holder, ParseIndirectObject(::testing::_)).Times(0);
77   EXPECT_FALSE(mock_holder.ReplaceIndirectObjectIfHigherGeneration(
78       CPDF_Object::kInvalidObjNum, pdfium::MakeRetain<CPDF_Null>()));
79 }
80 
TEST(IndirectObjectHolderTest,TemplateNewMethods)81 TEST(IndirectObjectHolderTest, TemplateNewMethods) {
82   MockIndirectObjectHolder mock_holder;
83 
84   auto pDict = mock_holder.NewIndirect<CPDF_Dictionary>();
85   auto pArray = mock_holder.NewIndirect<CPDF_Array>();
86   mock_holder.DeleteIndirectObject(pDict->GetObjNum());
87   mock_holder.DeleteIndirectObject(pArray->GetObjNum());
88 
89   // No longer UAF since NewIndirect<> returns retained objects.
90   EXPECT_TRUE(pDict->IsDictionary());
91   EXPECT_TRUE(pArray->IsArray());
92 }
93