5#include "core/fpdfapi/parser/cpdf_document.h"
10#include "core/fpdfapi/page/test_with_page_module.h"
11#include "core/fpdfapi/parser/cpdf_array.h"
12#include "core/fpdfapi/parser/cpdf_boolean.h"
13#include "core/fpdfapi/parser/cpdf_dictionary.h"
14#include "core/fpdfapi/parser/cpdf_linearized_header.h"
15#include "core/fpdfapi/parser/cpdf_name.h"
16#include "core/fpdfapi/parser/cpdf_number.h"
17#include "core/fpdfapi/parser/cpdf_parser.h"
18#include "core/fpdfapi/parser/cpdf_reference.h"
19#include "core/fpdfapi/parser/cpdf_string.h"
20#include "core/fpdfapi/parser/cpdf_test_document.h"
21#include "testing/gtest/include/gtest/gtest.h"
22#include "third_party/base/check.h"
26const int kNumTestPages = 7;
32 auto pageNode = pDoc->NewIndirect<CPDF_Dictionary>();
33 pageNode->SetNewFor<CPDF_Name>(
"Type",
"Pages");
34 pageNode->SetNewFor<CPDF_Reference>(
"Kids", pDoc, new_objnum);
35 pageNode->SetNewFor<CPDF_Number>(
"Count", count);
36 for (size_t i = 0; i < kids->size(); i++) {
37 kids->GetMutableDictAt(i)->SetNewFor<CPDF_Reference>(
"Parent", pDoc,
38 pageNode->GetObjNum());
43RetainPtr<CPDF_Dictionary> CreateNumberedPage(size_t number) {
44 auto page = pdfium::MakeRetain<CPDF_Dictionary>();
45 page->SetNewFor<CPDF_Name>(
"Type",
"Page");
46 page->SetNewFor<CPDF_Number>(
"PageNumbering",
static_cast<
int>(number));
52 CPDF_TestDocumentForPages() {
54 auto zeroToTwo = pdfium::MakeRetain<CPDF_Array>();
55 zeroToTwo->AppendNew<CPDF_Reference>(
56 this, AddIndirectObject(CreateNumberedPage(0)));
57 zeroToTwo->AppendNew<CPDF_Reference>(
58 this, AddIndirectObject(CreateNumberedPage(1)));
59 zeroToTwo->AppendNew<CPDF_Reference>(
60 this, AddIndirectObject(CreateNumberedPage(2)));
62 CreatePageTreeNode(std::move(zeroToTwo),
this, 3);
64 auto zeroToThree = pdfium::MakeRetain<CPDF_Array>();
65 zeroToThree->AppendNew<CPDF_Reference>(
this, branch1->GetObjNum());
66 zeroToThree->AppendNew<CPDF_Reference>(
67 this, AddIndirectObject(CreateNumberedPage(3)));
69 CreatePageTreeNode(std::move(zeroToThree),
this, 4);
71 auto fourFive = pdfium::MakeRetain<CPDF_Array>();
72 fourFive->AppendNew<CPDF_Reference>(
73 this, AddIndirectObject(CreateNumberedPage(4)));
74 fourFive->AppendNew<CPDF_Reference>(
75 this, AddIndirectObject(CreateNumberedPage(5)));
77 CreatePageTreeNode(std::move(fourFive),
this, 2);
79 auto justSix = pdfium::MakeRetain<CPDF_Array>();
80 justSix->AppendNew<CPDF_Reference>(
81 this, AddIndirectObject(CreateNumberedPage(6)));
83 CreatePageTreeNode(std::move(justSix),
this, 1);
85 auto allPages = pdfium::MakeRetain<CPDF_Array>();
86 allPages->AppendNew<CPDF_Reference>(
this, branch2->GetObjNum());
87 allPages->AppendNew<CPDF_Reference>(
this, branch3->GetObjNum());
88 allPages->AppendNew<CPDF_Reference>(
this, branch4->GetObjNum());
90 CreatePageTreeNode(std::move(allPages),
this, kNumTestPages);
93 GetMutableRoot()->SetNewFor<CPDF_Reference>(
"Pages",
this,
94 pagesDict->GetObjNum());
95 ResizePageListForTesting(kNumTestPages);
98 void SetTreeSize(
int size) {
99 GetMutableRoot()->SetNewFor<CPDF_Number>(
"Count", size);
100 ResizePageListForTesting(size);
106 CPDF_TestDocumentWithPageWithoutPageNum() {
108 auto allPages = pdfium::MakeRetain<CPDF_Array>();
109 allPages->AppendNew<CPDF_Reference>(
110 this, AddIndirectObject(CreateNumberedPage(0)));
111 allPages->AppendNew<CPDF_Reference>(
112 this, AddIndirectObject(CreateNumberedPage(1)));
114 inlined_page_ = CreateNumberedPage(2);
115 allPages->Append(inlined_page_);
117 CreatePageTreeNode(std::move(allPages),
this, 3);
119 GetMutableRoot()->SetNewFor<CPDF_Reference>(
"Pages",
this,
120 pagesDict->GetObjNum());
121 ResizePageListForTesting(3);
124 const CPDF_Object* inlined_page()
const {
return inlined_page_.Get(); }
132 explicit TestLinearized(CPDF_Dictionary* dict)
138 CPDF_TestDocPagesWithoutKids() {
139 auto pagesDict = NewIndirect<CPDF_Dictionary>();
140 pagesDict->SetNewFor<CPDF_Name>(
"Type",
"Pages");
141 pagesDict->SetNewFor<CPDF_Number>(
"Count", 3);
142 ResizePageListForTesting(10);
144 GetMutableRoot()->SetNewFor<CPDF_Reference>(
"Pages",
this,
145 pagesDict->GetObjNum());
151 CPDF_TestDocumentAllowSetParser() =
default;
161 std::unique_ptr<CPDF_TestDocumentForPages> document =
162 std::make_unique<CPDF_TestDocumentForPages>();
163 for (
int i = 0; i < kNumTestPages; i++) {
164 RetainPtr<
const CPDF_Dictionary> page = document->GetPageDictionary(i);
166 ASSERT_TRUE(page->KeyExist(
"PageNumbering"));
167 EXPECT_EQ(i, page->GetIntegerFor(
"PageNumbering"));
170 document->GetPageDictionary(kNumTestPages);
175 auto document =
std::make_unique<CPDF_TestDocumentWithPageWithoutPageNum>();
176 RetainPtr<
const CPDF_Dictionary> page = document->GetPageDictionary(2);
178 ASSERT_EQ(document->inlined_page(), page);
180 RetainPtr<
const CPDF_Dictionary> second_call_page =
181 document->GetPageDictionary(2);
182 EXPECT_TRUE(second_call_page);
183 EXPECT_EQ(page, second_call_page);
187 std::unique_ptr<CPDF_TestDocumentForPages> document =
188 std::make_unique<CPDF_TestDocumentForPages>();
189 for (
int i = 6; i >= 0; i--) {
190 RetainPtr<
const CPDF_Dictionary> page = document->GetPageDictionary(i);
192 ASSERT_TRUE(page->KeyExist(
"PageNumbering"));
193 EXPECT_EQ(i, page->GetIntegerFor(
"PageNumbering"));
196 document->GetPageDictionary(kNumTestPages);
201 std::unique_ptr<CPDF_TestDocumentForPages> document =
202 std::make_unique<CPDF_TestDocumentForPages>();
204 RetainPtr<
const CPDF_Dictionary> page = document->GetPageDictionary(1);
206 ASSERT_TRUE(page->KeyExist(
"PageNumbering"));
207 EXPECT_EQ(1, page->GetIntegerFor(
"PageNumbering"));
209 page = document->GetPageDictionary(3);
211 ASSERT_TRUE(page->KeyExist(
"PageNumbering"));
212 EXPECT_EQ(3, page->GetIntegerFor(
"PageNumbering"));
214 page = document->GetPageDictionary(kNumTestPages);
217 page = document->GetPageDictionary(6);
219 ASSERT_TRUE(page->KeyExist(
"PageNumbering"));
220 EXPECT_EQ(6, page->GetIntegerFor(
"PageNumbering"));
224 CPDF_TestDocumentForPages document;
226 auto dict_type_name_page = pdfium::MakeRetain<CPDF_Dictionary>();
227 dict_type_name_page->SetNewFor<CPDF_Name>(
"Type",
"Page");
231 auto dict_type_string_page = pdfium::MakeRetain<CPDF_Dictionary>();
232 dict_type_string_page->SetNewFor<CPDF_String>(
"Type",
"Page",
false);
236 auto dict_type_name_font = pdfium::MakeRetain<CPDF_Dictionary>();
237 dict_type_name_font->SetNewFor<CPDF_Name>(
"Type",
"Font");
241 auto obj_no_type = document.NewIndirect<CPDF_Dictionary>();
249 constexpr int kPageCount = 100;
250 constexpr int kTestPageNum = 33;
252 auto linearization_dict = pdfium::MakeRetain<CPDF_Dictionary>();
253 CPDF_TestDocumentAllowSetParser document;
256 auto first_page = CreateNumberedPage(0);
257 ASSERT_TRUE(first_page);
260 ASSERT_NE(kTestPageNum, first_page_obj_num);
262 linearization_dict->SetNewFor<CPDF_Boolean>(
"Linearized",
true);
263 linearization_dict->SetNewFor<CPDF_Number>(
"N", kPageCount);
264 linearization_dict->SetNewFor<CPDF_Number>(
"O", first_page_obj_num);
267 parser->SetLinearizedHeaderForTesting(
268 std::make_unique<TestLinearized>(linearization_dict.Get()));
269 document.SetParser(
std::move(parser));
275 auto page_stub = document.NewIndirect<CPDF_Dictionary>();
276 const uint32_t obj_num = page_stub->GetObjNum();
287 std::unique_ptr<CPDF_TestDocumentForPages> document =
288 std::make_unique<CPDF_TestDocumentForPages>();
289 document->SetTreeSize(kNumTestPages + 3);
290 for (
int i = 0; i < kNumTestPages; i++)
291 EXPECT_TRUE(document->GetPageDictionary(i));
292 for (
int i = kNumTestPages; i < kNumTestPages + 4; i++)
293 EXPECT_FALSE(document->GetPageDictionary(i));
294 EXPECT_TRUE(document->GetPageDictionary(kNumTestPages - 1));
299 auto pDoc =
std::make_unique<CPDF_TestDocPagesWithoutKids>();
300 EXPECT_TRUE(pDoc->GetPageDictionary(0));
302 for (
int i = 1; i < 5; i++)
303 EXPECT_FALSE(pDoc->GetPageDictionary(i));
305 EXPECT_TRUE(pDoc->GetPageDictionary(0));
bool IsPageLoaded(int iPage) const
RetainPtr< const CPDF_Dictionary > GetPageDictionary(int iPage)
void SetRootForTesting(RetainPtr< CPDF_Dictionary > root)
static bool IsValidPageObject(const CPDF_Object *obj)
void SetPageObjNum(int iPage, uint32_t objNum)
uint32_t AddIndirectObject(RetainPtr< CPDF_Object > pObj)
TEST_F(CPDF_CIDFontTest, BUG_920636)