xref: /aosp_15_r20/external/pdfium/fpdfsdk/fpdf_ppo_embeddertest.cpp (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
1*3ac0a46fSAndroid Build Coastguard Worker // Copyright 2016 The PDFium Authors
2*3ac0a46fSAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*3ac0a46fSAndroid Build Coastguard Worker // found in the LICENSE file.
4*3ac0a46fSAndroid Build Coastguard Worker 
5*3ac0a46fSAndroid Build Coastguard Worker #include <iterator>
6*3ac0a46fSAndroid Build Coastguard Worker 
7*3ac0a46fSAndroid Build Coastguard Worker #include "core/fpdfapi/page/cpdf_form.h"
8*3ac0a46fSAndroid Build Coastguard Worker #include "core/fpdfapi/page/cpdf_formobject.h"
9*3ac0a46fSAndroid Build Coastguard Worker #include "core/fpdfapi/parser/cpdf_array.h"
10*3ac0a46fSAndroid Build Coastguard Worker #include "core/fpdfapi/parser/cpdf_dictionary.h"
11*3ac0a46fSAndroid Build Coastguard Worker #include "core/fpdfapi/parser/cpdf_document.h"
12*3ac0a46fSAndroid Build Coastguard Worker #include "core/fpdfapi/parser/cpdf_name.h"
13*3ac0a46fSAndroid Build Coastguard Worker #include "core/fpdfapi/parser/cpdf_number.h"
14*3ac0a46fSAndroid Build Coastguard Worker #include "core/fpdfapi/parser/cpdf_stream.h"
15*3ac0a46fSAndroid Build Coastguard Worker #include "core/fpdfapi/parser/cpdf_string.h"
16*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxge/cfx_defaultrenderdevice.h"
17*3ac0a46fSAndroid Build Coastguard Worker #include "fpdfsdk/cpdfsdk_helpers.h"
18*3ac0a46fSAndroid Build Coastguard Worker #include "public/cpp/fpdf_scopers.h"
19*3ac0a46fSAndroid Build Coastguard Worker #include "public/fpdf_edit.h"
20*3ac0a46fSAndroid Build Coastguard Worker #include "public/fpdf_ppo.h"
21*3ac0a46fSAndroid Build Coastguard Worker #include "public/fpdf_save.h"
22*3ac0a46fSAndroid Build Coastguard Worker #include "public/fpdfview.h"
23*3ac0a46fSAndroid Build Coastguard Worker #include "testing/embedder_test.h"
24*3ac0a46fSAndroid Build Coastguard Worker #include "testing/embedder_test_constants.h"
25*3ac0a46fSAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
26*3ac0a46fSAndroid Build Coastguard Worker 
27*3ac0a46fSAndroid Build Coastguard Worker namespace {
28*3ac0a46fSAndroid Build Coastguard Worker 
29*3ac0a46fSAndroid Build Coastguard Worker class FPDFPPOEmbedderTest : public EmbedderTest {};
30*3ac0a46fSAndroid Build Coastguard Worker 
FakeBlockWriter(FPDF_FILEWRITE * pThis,const void * pData,unsigned long size)31*3ac0a46fSAndroid Build Coastguard Worker int FakeBlockWriter(FPDF_FILEWRITE* pThis,
32*3ac0a46fSAndroid Build Coastguard Worker                     const void* pData,
33*3ac0a46fSAndroid Build Coastguard Worker                     unsigned long size) {
34*3ac0a46fSAndroid Build Coastguard Worker   return 1;  // Always succeeds.
35*3ac0a46fSAndroid Build Coastguard Worker }
36*3ac0a46fSAndroid Build Coastguard Worker 
37*3ac0a46fSAndroid Build Coastguard Worker constexpr int kRectanglesMultiPagesPageCount = 2;
38*3ac0a46fSAndroid Build Coastguard Worker 
RectanglesMultiPagesExpectedChecksum(int page_index)39*3ac0a46fSAndroid Build Coastguard Worker const char* RectanglesMultiPagesExpectedChecksum(int page_index) {
40*3ac0a46fSAndroid Build Coastguard Worker   if (CFX_DefaultRenderDevice::SkiaIsDefaultRenderer()) {
41*3ac0a46fSAndroid Build Coastguard Worker     static constexpr const char* kChecksums[kRectanglesMultiPagesPageCount] = {
42*3ac0a46fSAndroid Build Coastguard Worker         "07606a12487bd0c28a88f23fa00fc313", "94ea6e1eef220833a3ec14d6a1c612b0"};
43*3ac0a46fSAndroid Build Coastguard Worker     return kChecksums[page_index];
44*3ac0a46fSAndroid Build Coastguard Worker   }
45*3ac0a46fSAndroid Build Coastguard Worker   static constexpr const char* kChecksums[kRectanglesMultiPagesPageCount] = {
46*3ac0a46fSAndroid Build Coastguard Worker       "72d0d7a19a2f40e010ca6a1133b33e1e", "fb18142190d770cfbc329d2b071aee4d"};
47*3ac0a46fSAndroid Build Coastguard Worker   return kChecksums[page_index];
48*3ac0a46fSAndroid Build Coastguard Worker }
49*3ac0a46fSAndroid Build Coastguard Worker 
Bug750568PageHash(int page_index)50*3ac0a46fSAndroid Build Coastguard Worker const char* Bug750568PageHash(int page_index) {
51*3ac0a46fSAndroid Build Coastguard Worker   constexpr int kBug750568PageCount = 4;
52*3ac0a46fSAndroid Build Coastguard Worker   if (CFX_DefaultRenderDevice::SkiaIsDefaultRenderer()) {
53*3ac0a46fSAndroid Build Coastguard Worker     static constexpr const char* kChecksums[kBug750568PageCount] = {
54*3ac0a46fSAndroid Build Coastguard Worker         "eaa139e944eafb43d31e8742a0e158de", "226485e9d4fa6a67dfe0a88723f12060",
55*3ac0a46fSAndroid Build Coastguard Worker         "c5601a3492ae5dcc5dd25140fc463bfe", "1f60055b54de4fac8a59c65e90da156e"};
56*3ac0a46fSAndroid Build Coastguard Worker     return kChecksums[page_index];
57*3ac0a46fSAndroid Build Coastguard Worker   }
58*3ac0a46fSAndroid Build Coastguard Worker   static constexpr const char* kChecksums[kBug750568PageCount] = {
59*3ac0a46fSAndroid Build Coastguard Worker       "64ad08132a1c5a166768298c8a578f57", "83b83e2f6bc80707d0a917c7634140b9",
60*3ac0a46fSAndroid Build Coastguard Worker       "913cd3723a451e4e46fbc2c05702d1ee", "81fb7cfd4860f855eb468f73dfeb6d60"};
61*3ac0a46fSAndroid Build Coastguard Worker   return kChecksums[page_index];
62*3ac0a46fSAndroid Build Coastguard Worker }
63*3ac0a46fSAndroid Build Coastguard Worker 
64*3ac0a46fSAndroid Build Coastguard Worker }  // namespace
65*3ac0a46fSAndroid Build Coastguard Worker 
TEST_F(FPDFPPOEmbedderTest,NoViewerPreferences)66*3ac0a46fSAndroid Build Coastguard Worker TEST_F(FPDFPPOEmbedderTest, NoViewerPreferences) {
67*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_TRUE(OpenDocument("hello_world.pdf"));
68*3ac0a46fSAndroid Build Coastguard Worker 
69*3ac0a46fSAndroid Build Coastguard Worker   FPDF_DOCUMENT output_doc = FPDF_CreateNewDocument();
70*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(output_doc);
71*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(FPDF_CopyViewerPreferences(output_doc, document()));
72*3ac0a46fSAndroid Build Coastguard Worker   FPDF_CloseDocument(output_doc);
73*3ac0a46fSAndroid Build Coastguard Worker }
74*3ac0a46fSAndroid Build Coastguard Worker 
TEST_F(FPDFPPOEmbedderTest,ViewerPreferences)75*3ac0a46fSAndroid Build Coastguard Worker TEST_F(FPDFPPOEmbedderTest, ViewerPreferences) {
76*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_TRUE(OpenDocument("viewer_ref.pdf"));
77*3ac0a46fSAndroid Build Coastguard Worker 
78*3ac0a46fSAndroid Build Coastguard Worker   FPDF_DOCUMENT output_doc = FPDF_CreateNewDocument();
79*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(output_doc);
80*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(FPDF_CopyViewerPreferences(output_doc, document()));
81*3ac0a46fSAndroid Build Coastguard Worker   FPDF_CloseDocument(output_doc);
82*3ac0a46fSAndroid Build Coastguard Worker }
83*3ac0a46fSAndroid Build Coastguard Worker 
TEST_F(FPDFPPOEmbedderTest,ImportPagesByIndex)84*3ac0a46fSAndroid Build Coastguard Worker TEST_F(FPDFPPOEmbedderTest, ImportPagesByIndex) {
85*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_TRUE(OpenDocument("viewer_ref.pdf"));
86*3ac0a46fSAndroid Build Coastguard Worker 
87*3ac0a46fSAndroid Build Coastguard Worker   FPDF_PAGE page = LoadPage(0);
88*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(page);
89*3ac0a46fSAndroid Build Coastguard Worker 
90*3ac0a46fSAndroid Build Coastguard Worker   ScopedFPDFDocument output_doc(FPDF_CreateNewDocument());
91*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_TRUE(output_doc);
92*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(FPDF_CopyViewerPreferences(output_doc.get(), document()));
93*3ac0a46fSAndroid Build Coastguard Worker 
94*3ac0a46fSAndroid Build Coastguard Worker   static constexpr int kPageIndices[] = {1};
95*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(FPDF_ImportPagesByIndex(
96*3ac0a46fSAndroid Build Coastguard Worker       output_doc.get(), document(), kPageIndices, std::size(kPageIndices), 0));
97*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(1, FPDF_GetPageCount(output_doc.get()));
98*3ac0a46fSAndroid Build Coastguard Worker 
99*3ac0a46fSAndroid Build Coastguard Worker   UnloadPage(page);
100*3ac0a46fSAndroid Build Coastguard Worker }
101*3ac0a46fSAndroid Build Coastguard Worker 
TEST_F(FPDFPPOEmbedderTest,ImportPages)102*3ac0a46fSAndroid Build Coastguard Worker TEST_F(FPDFPPOEmbedderTest, ImportPages) {
103*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_TRUE(OpenDocument("viewer_ref.pdf"));
104*3ac0a46fSAndroid Build Coastguard Worker 
105*3ac0a46fSAndroid Build Coastguard Worker   FPDF_PAGE page = LoadPage(0);
106*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(page);
107*3ac0a46fSAndroid Build Coastguard Worker 
108*3ac0a46fSAndroid Build Coastguard Worker   FPDF_DOCUMENT output_doc = FPDF_CreateNewDocument();
109*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_TRUE(output_doc);
110*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(FPDF_CopyViewerPreferences(output_doc, document()));
111*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(FPDF_ImportPages(output_doc, document(), "1", 0));
112*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(1, FPDF_GetPageCount(output_doc));
113*3ac0a46fSAndroid Build Coastguard Worker   FPDF_CloseDocument(output_doc);
114*3ac0a46fSAndroid Build Coastguard Worker 
115*3ac0a46fSAndroid Build Coastguard Worker   UnloadPage(page);
116*3ac0a46fSAndroid Build Coastguard Worker }
117*3ac0a46fSAndroid Build Coastguard Worker 
TEST_F(FPDFPPOEmbedderTest,ImportNPages)118*3ac0a46fSAndroid Build Coastguard Worker TEST_F(FPDFPPOEmbedderTest, ImportNPages) {
119*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_TRUE(OpenDocument("rectangles_multi_pages.pdf"));
120*3ac0a46fSAndroid Build Coastguard Worker 
121*3ac0a46fSAndroid Build Coastguard Worker   ScopedFPDFDocument output_doc_2up(
122*3ac0a46fSAndroid Build Coastguard Worker       FPDF_ImportNPagesToOne(document(), 612, 792, 2, 1));
123*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_TRUE(output_doc_2up);
124*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(3, FPDF_GetPageCount(output_doc_2up.get()));
125*3ac0a46fSAndroid Build Coastguard Worker   ScopedFPDFDocument output_doc_5up(
126*3ac0a46fSAndroid Build Coastguard Worker       FPDF_ImportNPagesToOne(document(), 612, 792, 5, 1));
127*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_TRUE(output_doc_5up);
128*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(1, FPDF_GetPageCount(output_doc_5up.get()));
129*3ac0a46fSAndroid Build Coastguard Worker   ScopedFPDFDocument output_doc_8up(
130*3ac0a46fSAndroid Build Coastguard Worker       FPDF_ImportNPagesToOne(document(), 792, 612, 8, 1));
131*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_TRUE(output_doc_8up);
132*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(1, FPDF_GetPageCount(output_doc_8up.get()));
133*3ac0a46fSAndroid Build Coastguard Worker   ScopedFPDFDocument output_doc_128up(
134*3ac0a46fSAndroid Build Coastguard Worker       FPDF_ImportNPagesToOne(document(), 792, 612, 128, 1));
135*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_TRUE(output_doc_128up);
136*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(1, FPDF_GetPageCount(output_doc_128up.get()));
137*3ac0a46fSAndroid Build Coastguard Worker }
138*3ac0a46fSAndroid Build Coastguard Worker 
TEST_F(FPDFPPOEmbedderTest,BadNupParams)139*3ac0a46fSAndroid Build Coastguard Worker TEST_F(FPDFPPOEmbedderTest, BadNupParams) {
140*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_TRUE(OpenDocument("rectangles_multi_pages.pdf"));
141*3ac0a46fSAndroid Build Coastguard Worker 
142*3ac0a46fSAndroid Build Coastguard Worker   FPDF_DOCUMENT output_doc_zero_row =
143*3ac0a46fSAndroid Build Coastguard Worker       FPDF_ImportNPagesToOne(document(), 612, 792, 0, 3);
144*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_FALSE(output_doc_zero_row);
145*3ac0a46fSAndroid Build Coastguard Worker   FPDF_DOCUMENT output_doc_zero_col =
146*3ac0a46fSAndroid Build Coastguard Worker       FPDF_ImportNPagesToOne(document(), 612, 792, 2, 0);
147*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_FALSE(output_doc_zero_col);
148*3ac0a46fSAndroid Build Coastguard Worker   FPDF_DOCUMENT output_doc_zero_width =
149*3ac0a46fSAndroid Build Coastguard Worker       FPDF_ImportNPagesToOne(document(), 0, 792, 2, 1);
150*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_FALSE(output_doc_zero_width);
151*3ac0a46fSAndroid Build Coastguard Worker   FPDF_DOCUMENT output_doc_zero_height =
152*3ac0a46fSAndroid Build Coastguard Worker       FPDF_ImportNPagesToOne(document(), 612, 0, 7, 1);
153*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_FALSE(output_doc_zero_height);
154*3ac0a46fSAndroid Build Coastguard Worker }
155*3ac0a46fSAndroid Build Coastguard Worker 
156*3ac0a46fSAndroid Build Coastguard Worker // TODO(Xlou): Add more tests to check output doc content of
157*3ac0a46fSAndroid Build Coastguard Worker // FPDF_ImportNPagesToOne()
TEST_F(FPDFPPOEmbedderTest,NupRenderImage)158*3ac0a46fSAndroid Build Coastguard Worker TEST_F(FPDFPPOEmbedderTest, NupRenderImage) {
159*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_TRUE(OpenDocument("rectangles_multi_pages.pdf"));
160*3ac0a46fSAndroid Build Coastguard Worker   ScopedFPDFDocument output_doc_3up(
161*3ac0a46fSAndroid Build Coastguard Worker       FPDF_ImportNPagesToOne(document(), 792, 612, 3, 1));
162*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_TRUE(output_doc_3up);
163*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_EQ(kRectanglesMultiPagesPageCount,
164*3ac0a46fSAndroid Build Coastguard Worker             FPDF_GetPageCount(output_doc_3up.get()));
165*3ac0a46fSAndroid Build Coastguard Worker   for (int i = 0; i < kRectanglesMultiPagesPageCount; ++i) {
166*3ac0a46fSAndroid Build Coastguard Worker     ScopedFPDFPage page(FPDF_LoadPage(output_doc_3up.get(), i));
167*3ac0a46fSAndroid Build Coastguard Worker     ASSERT_TRUE(page);
168*3ac0a46fSAndroid Build Coastguard Worker     ScopedFPDFBitmap bitmap = RenderPage(page.get());
169*3ac0a46fSAndroid Build Coastguard Worker     EXPECT_EQ(792, FPDFBitmap_GetWidth(bitmap.get()));
170*3ac0a46fSAndroid Build Coastguard Worker     EXPECT_EQ(612, FPDFBitmap_GetHeight(bitmap.get()));
171*3ac0a46fSAndroid Build Coastguard Worker     EXPECT_EQ(RectanglesMultiPagesExpectedChecksum(i),
172*3ac0a46fSAndroid Build Coastguard Worker               HashBitmap(bitmap.get()));
173*3ac0a46fSAndroid Build Coastguard Worker   }
174*3ac0a46fSAndroid Build Coastguard Worker }
175*3ac0a46fSAndroid Build Coastguard Worker 
TEST_F(FPDFPPOEmbedderTest,ImportPageToXObject)176*3ac0a46fSAndroid Build Coastguard Worker TEST_F(FPDFPPOEmbedderTest, ImportPageToXObject) {
177*3ac0a46fSAndroid Build Coastguard Worker   const char* checksum = []() {
178*3ac0a46fSAndroid Build Coastguard Worker     if (CFX_DefaultRenderDevice::SkiaIsDefaultRenderer())
179*3ac0a46fSAndroid Build Coastguard Worker       return "d6ebc0a8afc22fe0137f54ce54e1a19c";
180*3ac0a46fSAndroid Build Coastguard Worker     return "2d88d180af7109eb346439f7c855bb29";
181*3ac0a46fSAndroid Build Coastguard Worker   }();
182*3ac0a46fSAndroid Build Coastguard Worker 
183*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_TRUE(OpenDocument("rectangles.pdf"));
184*3ac0a46fSAndroid Build Coastguard Worker 
185*3ac0a46fSAndroid Build Coastguard Worker   {
186*3ac0a46fSAndroid Build Coastguard Worker     ScopedFPDFDocument output_doc(FPDF_CreateNewDocument());
187*3ac0a46fSAndroid Build Coastguard Worker     ASSERT_TRUE(output_doc);
188*3ac0a46fSAndroid Build Coastguard Worker 
189*3ac0a46fSAndroid Build Coastguard Worker     FPDF_XOBJECT xobject =
190*3ac0a46fSAndroid Build Coastguard Worker         FPDF_NewXObjectFromPage(output_doc.get(), document(), 0);
191*3ac0a46fSAndroid Build Coastguard Worker     ASSERT_TRUE(xobject);
192*3ac0a46fSAndroid Build Coastguard Worker 
193*3ac0a46fSAndroid Build Coastguard Worker     for (int i = 0; i < 2; ++i) {
194*3ac0a46fSAndroid Build Coastguard Worker       ScopedFPDFPage page(FPDFPage_New(output_doc.get(), 0, 612, 792));
195*3ac0a46fSAndroid Build Coastguard Worker       ASSERT_TRUE(page);
196*3ac0a46fSAndroid Build Coastguard Worker 
197*3ac0a46fSAndroid Build Coastguard Worker       FPDF_PAGEOBJECT page_object = FPDF_NewFormObjectFromXObject(xobject);
198*3ac0a46fSAndroid Build Coastguard Worker       ASSERT_TRUE(page_object);
199*3ac0a46fSAndroid Build Coastguard Worker       EXPECT_EQ(FPDF_PAGEOBJ_FORM, FPDFPageObj_GetType(page_object));
200*3ac0a46fSAndroid Build Coastguard Worker       FPDFPage_InsertObject(page.get(), page_object);
201*3ac0a46fSAndroid Build Coastguard Worker       EXPECT_TRUE(FPDFPage_GenerateContent(page.get()));
202*3ac0a46fSAndroid Build Coastguard Worker 
203*3ac0a46fSAndroid Build Coastguard Worker       ScopedFPDFBitmap page_bitmap = RenderPage(page.get());
204*3ac0a46fSAndroid Build Coastguard Worker       CompareBitmap(page_bitmap.get(), 612, 792, checksum);
205*3ac0a46fSAndroid Build Coastguard Worker 
206*3ac0a46fSAndroid Build Coastguard Worker       float left;
207*3ac0a46fSAndroid Build Coastguard Worker       float bottom;
208*3ac0a46fSAndroid Build Coastguard Worker       float right;
209*3ac0a46fSAndroid Build Coastguard Worker       float top;
210*3ac0a46fSAndroid Build Coastguard Worker       ASSERT_TRUE(
211*3ac0a46fSAndroid Build Coastguard Worker           FPDFPageObj_GetBounds(page_object, &left, &bottom, &right, &top));
212*3ac0a46fSAndroid Build Coastguard Worker       EXPECT_FLOAT_EQ(-1.0f, left);
213*3ac0a46fSAndroid Build Coastguard Worker       EXPECT_FLOAT_EQ(-1.0f, bottom);
214*3ac0a46fSAndroid Build Coastguard Worker       EXPECT_FLOAT_EQ(201.0f, right);
215*3ac0a46fSAndroid Build Coastguard Worker       EXPECT_FLOAT_EQ(301.0f, top);
216*3ac0a46fSAndroid Build Coastguard Worker     }
217*3ac0a46fSAndroid Build Coastguard Worker 
218*3ac0a46fSAndroid Build Coastguard Worker     EXPECT_TRUE(FPDF_SaveAsCopy(output_doc.get(), this, 0));
219*3ac0a46fSAndroid Build Coastguard Worker 
220*3ac0a46fSAndroid Build Coastguard Worker     FPDF_CloseXObject(xobject);
221*3ac0a46fSAndroid Build Coastguard Worker   }
222*3ac0a46fSAndroid Build Coastguard Worker 
223*3ac0a46fSAndroid Build Coastguard Worker   constexpr int kExpectedPageCount = 2;
224*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_TRUE(OpenSavedDocument());
225*3ac0a46fSAndroid Build Coastguard Worker 
226*3ac0a46fSAndroid Build Coastguard Worker   FPDF_PAGE saved_pages[kExpectedPageCount];
227*3ac0a46fSAndroid Build Coastguard Worker   FPDF_PAGEOBJECT xobjects[kExpectedPageCount];
228*3ac0a46fSAndroid Build Coastguard Worker   for (int i = 0; i < kExpectedPageCount; ++i) {
229*3ac0a46fSAndroid Build Coastguard Worker     saved_pages[i] = LoadSavedPage(i);
230*3ac0a46fSAndroid Build Coastguard Worker     ASSERT_TRUE(saved_pages[i]);
231*3ac0a46fSAndroid Build Coastguard Worker 
232*3ac0a46fSAndroid Build Coastguard Worker     EXPECT_EQ(1, FPDFPage_CountObjects(saved_pages[i]));
233*3ac0a46fSAndroid Build Coastguard Worker     xobjects[i] = FPDFPage_GetObject(saved_pages[i], 0);
234*3ac0a46fSAndroid Build Coastguard Worker     ASSERT_TRUE(xobjects[i]);
235*3ac0a46fSAndroid Build Coastguard Worker     ASSERT_EQ(FPDF_PAGEOBJ_FORM, FPDFPageObj_GetType(xobjects[i]));
236*3ac0a46fSAndroid Build Coastguard Worker     EXPECT_EQ(8, FPDFFormObj_CountObjects(xobjects[i]));
237*3ac0a46fSAndroid Build Coastguard Worker 
238*3ac0a46fSAndroid Build Coastguard Worker     {
239*3ac0a46fSAndroid Build Coastguard Worker       ScopedFPDFBitmap page_bitmap = RenderPage(saved_pages[i]);
240*3ac0a46fSAndroid Build Coastguard Worker       CompareBitmap(page_bitmap.get(), 612, 792, checksum);
241*3ac0a46fSAndroid Build Coastguard Worker     }
242*3ac0a46fSAndroid Build Coastguard Worker   }
243*3ac0a46fSAndroid Build Coastguard Worker 
244*3ac0a46fSAndroid Build Coastguard Worker   for (int i = 0; i < kExpectedPageCount; ++i) {
245*3ac0a46fSAndroid Build Coastguard Worker     float left;
246*3ac0a46fSAndroid Build Coastguard Worker     float bottom;
247*3ac0a46fSAndroid Build Coastguard Worker     float right;
248*3ac0a46fSAndroid Build Coastguard Worker     float top;
249*3ac0a46fSAndroid Build Coastguard Worker     ASSERT_TRUE(
250*3ac0a46fSAndroid Build Coastguard Worker         FPDFPageObj_GetBounds(xobjects[i], &left, &bottom, &right, &top));
251*3ac0a46fSAndroid Build Coastguard Worker     EXPECT_FLOAT_EQ(-1.0f, left);
252*3ac0a46fSAndroid Build Coastguard Worker     EXPECT_FLOAT_EQ(-1.0f, bottom);
253*3ac0a46fSAndroid Build Coastguard Worker     EXPECT_FLOAT_EQ(201.0f, right);
254*3ac0a46fSAndroid Build Coastguard Worker     EXPECT_FLOAT_EQ(301.0f, top);
255*3ac0a46fSAndroid Build Coastguard Worker   }
256*3ac0a46fSAndroid Build Coastguard Worker 
257*3ac0a46fSAndroid Build Coastguard Worker   // Peek at object internals to make sure the two XObjects use the same stream.
258*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_NE(xobjects[0], xobjects[1]);
259*3ac0a46fSAndroid Build Coastguard Worker   CPDF_PageObject* obj1 = CPDFPageObjectFromFPDFPageObject(xobjects[0]);
260*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_TRUE(obj1->AsForm());
261*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_TRUE(obj1->AsForm()->form());
262*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_TRUE(obj1->AsForm()->form()->GetStream());
263*3ac0a46fSAndroid Build Coastguard Worker   CPDF_PageObject* obj2 = CPDFPageObjectFromFPDFPageObject(xobjects[1]);
264*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_TRUE(obj2->AsForm());
265*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_TRUE(obj2->AsForm()->form());
266*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_TRUE(obj2->AsForm()->form()->GetStream());
267*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(obj1->AsForm()->form()->GetStream(),
268*3ac0a46fSAndroid Build Coastguard Worker             obj2->AsForm()->form()->GetStream());
269*3ac0a46fSAndroid Build Coastguard Worker 
270*3ac0a46fSAndroid Build Coastguard Worker   for (FPDF_PAGE saved_page : saved_pages)
271*3ac0a46fSAndroid Build Coastguard Worker     CloseSavedPage(saved_page);
272*3ac0a46fSAndroid Build Coastguard Worker 
273*3ac0a46fSAndroid Build Coastguard Worker   CloseSavedDocument();
274*3ac0a46fSAndroid Build Coastguard Worker }
275*3ac0a46fSAndroid Build Coastguard Worker 
TEST_F(FPDFPPOEmbedderTest,ImportPageToXObjectWithSameDoc)276*3ac0a46fSAndroid Build Coastguard Worker TEST_F(FPDFPPOEmbedderTest, ImportPageToXObjectWithSameDoc) {
277*3ac0a46fSAndroid Build Coastguard Worker   const char* checksum = []() {
278*3ac0a46fSAndroid Build Coastguard Worker     if (CFX_DefaultRenderDevice::SkiaIsDefaultRenderer())
279*3ac0a46fSAndroid Build Coastguard Worker       return "8e7d672f49f9ca98fb9157824cefc204";
280*3ac0a46fSAndroid Build Coastguard Worker     return "4d5ca14827b7707f8283e639b33c121a";
281*3ac0a46fSAndroid Build Coastguard Worker   }();
282*3ac0a46fSAndroid Build Coastguard Worker 
283*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_TRUE(OpenDocument("rectangles.pdf"));
284*3ac0a46fSAndroid Build Coastguard Worker 
285*3ac0a46fSAndroid Build Coastguard Worker   FPDF_XOBJECT xobject = FPDF_NewXObjectFromPage(document(), document(), 0);
286*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_TRUE(xobject);
287*3ac0a46fSAndroid Build Coastguard Worker 
288*3ac0a46fSAndroid Build Coastguard Worker   FPDF_PAGE page = LoadPage(0);
289*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_TRUE(page);
290*3ac0a46fSAndroid Build Coastguard Worker 
291*3ac0a46fSAndroid Build Coastguard Worker   {
292*3ac0a46fSAndroid Build Coastguard Worker     ScopedFPDFBitmap bitmap = RenderLoadedPage(page);
293*3ac0a46fSAndroid Build Coastguard Worker     CompareBitmap(bitmap.get(), 200, 300, pdfium::RectanglesChecksum());
294*3ac0a46fSAndroid Build Coastguard Worker   }
295*3ac0a46fSAndroid Build Coastguard Worker 
296*3ac0a46fSAndroid Build Coastguard Worker   FPDF_PAGEOBJECT page_object = FPDF_NewFormObjectFromXObject(xobject);
297*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_TRUE(page_object);
298*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_EQ(FPDF_PAGEOBJ_FORM, FPDFPageObj_GetType(page_object));
299*3ac0a46fSAndroid Build Coastguard Worker 
300*3ac0a46fSAndroid Build Coastguard Worker   static constexpr FS_MATRIX kMatrix = {0.5f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f};
301*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(FPDFPageObj_SetMatrix(page_object, &kMatrix));
302*3ac0a46fSAndroid Build Coastguard Worker 
303*3ac0a46fSAndroid Build Coastguard Worker   FPDFPage_InsertObject(page, page_object);
304*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(FPDFPage_GenerateContent(page));
305*3ac0a46fSAndroid Build Coastguard Worker 
306*3ac0a46fSAndroid Build Coastguard Worker   {
307*3ac0a46fSAndroid Build Coastguard Worker     ScopedFPDFBitmap bitmap = RenderLoadedPage(page);
308*3ac0a46fSAndroid Build Coastguard Worker     CompareBitmap(bitmap.get(), 200, 300, checksum);
309*3ac0a46fSAndroid Build Coastguard Worker   }
310*3ac0a46fSAndroid Build Coastguard Worker 
311*3ac0a46fSAndroid Build Coastguard Worker   FPDF_CloseXObject(xobject);
312*3ac0a46fSAndroid Build Coastguard Worker 
313*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
314*3ac0a46fSAndroid Build Coastguard Worker   VerifySavedDocument(200, 300, checksum);
315*3ac0a46fSAndroid Build Coastguard Worker 
316*3ac0a46fSAndroid Build Coastguard Worker   UnloadPage(page);
317*3ac0a46fSAndroid Build Coastguard Worker }
318*3ac0a46fSAndroid Build Coastguard Worker 
TEST_F(FPDFPPOEmbedderTest,XObjectNullParams)319*3ac0a46fSAndroid Build Coastguard Worker TEST_F(FPDFPPOEmbedderTest, XObjectNullParams) {
320*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_TRUE(OpenDocument("rectangles.pdf"));
321*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_EQ(1, FPDF_GetPageCount(document()));
322*3ac0a46fSAndroid Build Coastguard Worker 
323*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(FPDF_NewXObjectFromPage(nullptr, nullptr, -1));
324*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(FPDF_NewXObjectFromPage(nullptr, nullptr, 0));
325*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(FPDF_NewXObjectFromPage(nullptr, nullptr, 1));
326*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(FPDF_NewXObjectFromPage(document(), nullptr, -1));
327*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(FPDF_NewXObjectFromPage(document(), nullptr, 0));
328*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(FPDF_NewXObjectFromPage(document(), nullptr, 1));
329*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(FPDF_NewXObjectFromPage(nullptr, document(), -1));
330*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(FPDF_NewXObjectFromPage(nullptr, document(), 0));
331*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(FPDF_NewXObjectFromPage(nullptr, document(), 1));
332*3ac0a46fSAndroid Build Coastguard Worker 
333*3ac0a46fSAndroid Build Coastguard Worker   {
334*3ac0a46fSAndroid Build Coastguard Worker     ScopedFPDFDocument output_doc(FPDF_CreateNewDocument());
335*3ac0a46fSAndroid Build Coastguard Worker     ASSERT_TRUE(output_doc);
336*3ac0a46fSAndroid Build Coastguard Worker     EXPECT_FALSE(FPDF_NewXObjectFromPage(output_doc.get(), document(), -1));
337*3ac0a46fSAndroid Build Coastguard Worker     EXPECT_FALSE(FPDF_NewXObjectFromPage(output_doc.get(), document(), 1));
338*3ac0a46fSAndroid Build Coastguard Worker   }
339*3ac0a46fSAndroid Build Coastguard Worker 
340*3ac0a46fSAndroid Build Coastguard Worker   // Should be a no-op.
341*3ac0a46fSAndroid Build Coastguard Worker   FPDF_CloseXObject(nullptr);
342*3ac0a46fSAndroid Build Coastguard Worker 
343*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(FPDF_NewFormObjectFromXObject(nullptr));
344*3ac0a46fSAndroid Build Coastguard Worker }
345*3ac0a46fSAndroid Build Coastguard Worker 
TEST_F(FPDFPPOEmbedderTest,BUG_925981)346*3ac0a46fSAndroid Build Coastguard Worker TEST_F(FPDFPPOEmbedderTest, BUG_925981) {
347*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_TRUE(OpenDocument("bug_925981.pdf"));
348*3ac0a46fSAndroid Build Coastguard Worker   ScopedFPDFDocument output_doc_2up(
349*3ac0a46fSAndroid Build Coastguard Worker       FPDF_ImportNPagesToOne(document(), 612, 792, 2, 1));
350*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(1, FPDF_GetPageCount(output_doc_2up.get()));
351*3ac0a46fSAndroid Build Coastguard Worker }
352*3ac0a46fSAndroid Build Coastguard Worker 
TEST_F(FPDFPPOEmbedderTest,BUG_1229106)353*3ac0a46fSAndroid Build Coastguard Worker TEST_F(FPDFPPOEmbedderTest, BUG_1229106) {
354*3ac0a46fSAndroid Build Coastguard Worker   static constexpr int kPageCount = 4;
355*3ac0a46fSAndroid Build Coastguard Worker   static constexpr int kTwoUpPageCount = 2;
356*3ac0a46fSAndroid Build Coastguard Worker   static const char kRectsChecksum[] = "140d629b3c96a07ced2e3e408ea85a1d";
357*3ac0a46fSAndroid Build Coastguard Worker   static const char kTwoUpChecksum[] = "fa4501562301b2e75da354bd067495ec";
358*3ac0a46fSAndroid Build Coastguard Worker 
359*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_TRUE(OpenDocument("bug_1229106.pdf"));
360*3ac0a46fSAndroid Build Coastguard Worker 
361*3ac0a46fSAndroid Build Coastguard Worker   // Show all pages render the same.
362*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_EQ(kPageCount, FPDF_GetPageCount(document()));
363*3ac0a46fSAndroid Build Coastguard Worker   for (int i = 0; i < kPageCount; ++i) {
364*3ac0a46fSAndroid Build Coastguard Worker     FPDF_PAGE page = LoadPage(0);
365*3ac0a46fSAndroid Build Coastguard Worker     ScopedFPDFBitmap bitmap = RenderLoadedPage(page);
366*3ac0a46fSAndroid Build Coastguard Worker     CompareBitmap(bitmap.get(), 792, 612, kRectsChecksum);
367*3ac0a46fSAndroid Build Coastguard Worker     UnloadPage(page);
368*3ac0a46fSAndroid Build Coastguard Worker   }
369*3ac0a46fSAndroid Build Coastguard Worker 
370*3ac0a46fSAndroid Build Coastguard Worker   // Create a 2-up PDF.
371*3ac0a46fSAndroid Build Coastguard Worker   ScopedFPDFDocument output_doc_2up(
372*3ac0a46fSAndroid Build Coastguard Worker       FPDF_ImportNPagesToOne(document(), 612, 792, 1, 2));
373*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_EQ(kTwoUpPageCount, FPDF_GetPageCount(output_doc_2up.get()));
374*3ac0a46fSAndroid Build Coastguard Worker   for (int i = 0; i < kTwoUpPageCount; ++i) {
375*3ac0a46fSAndroid Build Coastguard Worker     ScopedFPDFPage page(FPDF_LoadPage(output_doc_2up.get(), i));
376*3ac0a46fSAndroid Build Coastguard Worker     ScopedFPDFBitmap bitmap = RenderPage(page.get());
377*3ac0a46fSAndroid Build Coastguard Worker     CompareBitmap(bitmap.get(), 612, 792, kTwoUpChecksum);
378*3ac0a46fSAndroid Build Coastguard Worker   }
379*3ac0a46fSAndroid Build Coastguard Worker }
380*3ac0a46fSAndroid Build Coastguard Worker 
TEST_F(FPDFPPOEmbedderTest,BadRepeatViewerPref)381*3ac0a46fSAndroid Build Coastguard Worker TEST_F(FPDFPPOEmbedderTest, BadRepeatViewerPref) {
382*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_TRUE(OpenDocument("repeat_viewer_ref.pdf"));
383*3ac0a46fSAndroid Build Coastguard Worker 
384*3ac0a46fSAndroid Build Coastguard Worker   FPDF_DOCUMENT output_doc = FPDF_CreateNewDocument();
385*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(output_doc);
386*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(FPDF_CopyViewerPreferences(output_doc, document()));
387*3ac0a46fSAndroid Build Coastguard Worker 
388*3ac0a46fSAndroid Build Coastguard Worker   FPDF_FILEWRITE writer;
389*3ac0a46fSAndroid Build Coastguard Worker   writer.version = 1;
390*3ac0a46fSAndroid Build Coastguard Worker   writer.WriteBlock = FakeBlockWriter;
391*3ac0a46fSAndroid Build Coastguard Worker 
392*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(FPDF_SaveAsCopy(output_doc, &writer, 0));
393*3ac0a46fSAndroid Build Coastguard Worker   FPDF_CloseDocument(output_doc);
394*3ac0a46fSAndroid Build Coastguard Worker }
395*3ac0a46fSAndroid Build Coastguard Worker 
TEST_F(FPDFPPOEmbedderTest,BadCircularViewerPref)396*3ac0a46fSAndroid Build Coastguard Worker TEST_F(FPDFPPOEmbedderTest, BadCircularViewerPref) {
397*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_TRUE(OpenDocument("circular_viewer_ref.pdf"));
398*3ac0a46fSAndroid Build Coastguard Worker 
399*3ac0a46fSAndroid Build Coastguard Worker   FPDF_DOCUMENT output_doc = FPDF_CreateNewDocument();
400*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(output_doc);
401*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(FPDF_CopyViewerPreferences(output_doc, document()));
402*3ac0a46fSAndroid Build Coastguard Worker 
403*3ac0a46fSAndroid Build Coastguard Worker   FPDF_FILEWRITE writer;
404*3ac0a46fSAndroid Build Coastguard Worker   writer.version = 1;
405*3ac0a46fSAndroid Build Coastguard Worker   writer.WriteBlock = FakeBlockWriter;
406*3ac0a46fSAndroid Build Coastguard Worker 
407*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(FPDF_SaveAsCopy(output_doc, &writer, 0));
408*3ac0a46fSAndroid Build Coastguard Worker   FPDF_CloseDocument(output_doc);
409*3ac0a46fSAndroid Build Coastguard Worker }
410*3ac0a46fSAndroid Build Coastguard Worker 
TEST_F(FPDFPPOEmbedderTest,CopyViewerPrefTypes)411*3ac0a46fSAndroid Build Coastguard Worker TEST_F(FPDFPPOEmbedderTest, CopyViewerPrefTypes) {
412*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_TRUE(OpenDocument("viewer_pref_types.pdf"));
413*3ac0a46fSAndroid Build Coastguard Worker 
414*3ac0a46fSAndroid Build Coastguard Worker   ScopedFPDFDocument output_doc(FPDF_CreateNewDocument());
415*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_TRUE(output_doc);
416*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(FPDF_CopyViewerPreferences(output_doc.get(), document()));
417*3ac0a46fSAndroid Build Coastguard Worker 
418*3ac0a46fSAndroid Build Coastguard Worker   // Peek under the hook to check the result.
419*3ac0a46fSAndroid Build Coastguard Worker   const CPDF_Document* output_doc_impl =
420*3ac0a46fSAndroid Build Coastguard Worker       CPDFDocumentFromFPDFDocument(output_doc.get());
421*3ac0a46fSAndroid Build Coastguard Worker   RetainPtr<const CPDF_Dictionary> prefs =
422*3ac0a46fSAndroid Build Coastguard Worker       output_doc_impl->GetRoot()->GetDictFor("ViewerPreferences");
423*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_TRUE(prefs);
424*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(6u, prefs->size());
425*3ac0a46fSAndroid Build Coastguard Worker 
426*3ac0a46fSAndroid Build Coastguard Worker   RetainPtr<const CPDF_Object> bool_obj = prefs->GetObjectFor("Bool");
427*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_TRUE(bool_obj);
428*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(bool_obj->IsBoolean());
429*3ac0a46fSAndroid Build Coastguard Worker 
430*3ac0a46fSAndroid Build Coastguard Worker   RetainPtr<const CPDF_Number> num_obj = prefs->GetNumberFor("Num");
431*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_TRUE(num_obj);
432*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(num_obj->IsInteger());
433*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(1, num_obj->GetInteger());
434*3ac0a46fSAndroid Build Coastguard Worker 
435*3ac0a46fSAndroid Build Coastguard Worker   RetainPtr<const CPDF_String> str_obj = prefs->GetStringFor("Str");
436*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_TRUE(str_obj);
437*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ("str", str_obj->GetString());
438*3ac0a46fSAndroid Build Coastguard Worker 
439*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ("name", prefs->GetNameFor("Name"));
440*3ac0a46fSAndroid Build Coastguard Worker 
441*3ac0a46fSAndroid Build Coastguard Worker   RetainPtr<const CPDF_Array> empty_array_obj =
442*3ac0a46fSAndroid Build Coastguard Worker       prefs->GetArrayFor("EmptyArray");
443*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_TRUE(empty_array_obj);
444*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(empty_array_obj->IsEmpty());
445*3ac0a46fSAndroid Build Coastguard Worker 
446*3ac0a46fSAndroid Build Coastguard Worker   RetainPtr<const CPDF_Array> good_array_obj = prefs->GetArrayFor("GoodArray");
447*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_TRUE(good_array_obj);
448*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(4u, good_array_obj->size());
449*3ac0a46fSAndroid Build Coastguard Worker }
450*3ac0a46fSAndroid Build Coastguard Worker 
TEST_F(FPDFPPOEmbedderTest,BadIndices)451*3ac0a46fSAndroid Build Coastguard Worker TEST_F(FPDFPPOEmbedderTest, BadIndices) {
452*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_TRUE(OpenDocument("hello_world.pdf"));
453*3ac0a46fSAndroid Build Coastguard Worker 
454*3ac0a46fSAndroid Build Coastguard Worker   FPDF_PAGE page = LoadPage(0);
455*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(page);
456*3ac0a46fSAndroid Build Coastguard Worker 
457*3ac0a46fSAndroid Build Coastguard Worker   ScopedFPDFDocument output_doc(FPDF_CreateNewDocument());
458*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(output_doc);
459*3ac0a46fSAndroid Build Coastguard Worker 
460*3ac0a46fSAndroid Build Coastguard Worker   static constexpr int kBadIndices1[] = {-1};
461*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(FPDF_ImportPagesByIndex(
462*3ac0a46fSAndroid Build Coastguard Worker       output_doc.get(), document(), kBadIndices1, std::size(kBadIndices1), 0));
463*3ac0a46fSAndroid Build Coastguard Worker 
464*3ac0a46fSAndroid Build Coastguard Worker   static constexpr int kBadIndices2[] = {1};
465*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(FPDF_ImportPagesByIndex(
466*3ac0a46fSAndroid Build Coastguard Worker       output_doc.get(), document(), kBadIndices2, std::size(kBadIndices2), 0));
467*3ac0a46fSAndroid Build Coastguard Worker 
468*3ac0a46fSAndroid Build Coastguard Worker   static constexpr int kBadIndices3[] = {-1, 0, 1};
469*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(FPDF_ImportPagesByIndex(
470*3ac0a46fSAndroid Build Coastguard Worker       output_doc.get(), document(), kBadIndices3, std::size(kBadIndices3), 0));
471*3ac0a46fSAndroid Build Coastguard Worker 
472*3ac0a46fSAndroid Build Coastguard Worker   static constexpr int kBadIndices4[] = {42};
473*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(FPDF_ImportPagesByIndex(
474*3ac0a46fSAndroid Build Coastguard Worker       output_doc.get(), document(), kBadIndices4, std::size(kBadIndices4), 0));
475*3ac0a46fSAndroid Build Coastguard Worker 
476*3ac0a46fSAndroid Build Coastguard Worker   UnloadPage(page);
477*3ac0a46fSAndroid Build Coastguard Worker }
478*3ac0a46fSAndroid Build Coastguard Worker 
TEST_F(FPDFPPOEmbedderTest,GoodIndices)479*3ac0a46fSAndroid Build Coastguard Worker TEST_F(FPDFPPOEmbedderTest, GoodIndices) {
480*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_TRUE(OpenDocument("viewer_ref.pdf"));
481*3ac0a46fSAndroid Build Coastguard Worker 
482*3ac0a46fSAndroid Build Coastguard Worker   FPDF_PAGE page = LoadPage(0);
483*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(page);
484*3ac0a46fSAndroid Build Coastguard Worker 
485*3ac0a46fSAndroid Build Coastguard Worker   ScopedFPDFDocument output_doc(FPDF_CreateNewDocument());
486*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(output_doc);
487*3ac0a46fSAndroid Build Coastguard Worker 
488*3ac0a46fSAndroid Build Coastguard Worker   static constexpr int kGoodIndices1[] = {0, 0, 0, 0};
489*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(FPDF_ImportPagesByIndex(output_doc.get(), document(),
490*3ac0a46fSAndroid Build Coastguard Worker                                       kGoodIndices1, std::size(kGoodIndices1),
491*3ac0a46fSAndroid Build Coastguard Worker                                       0));
492*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(4, FPDF_GetPageCount(output_doc.get()));
493*3ac0a46fSAndroid Build Coastguard Worker 
494*3ac0a46fSAndroid Build Coastguard Worker   static constexpr int kGoodIndices2[] = {0};
495*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(FPDF_ImportPagesByIndex(output_doc.get(), document(),
496*3ac0a46fSAndroid Build Coastguard Worker                                       kGoodIndices2, std::size(kGoodIndices2),
497*3ac0a46fSAndroid Build Coastguard Worker                                       0));
498*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(5, FPDF_GetPageCount(output_doc.get()));
499*3ac0a46fSAndroid Build Coastguard Worker 
500*3ac0a46fSAndroid Build Coastguard Worker   static constexpr int kGoodIndices3[] = {4};
501*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(FPDF_ImportPagesByIndex(output_doc.get(), document(),
502*3ac0a46fSAndroid Build Coastguard Worker                                       kGoodIndices3, std::size(kGoodIndices3),
503*3ac0a46fSAndroid Build Coastguard Worker                                       0));
504*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(6, FPDF_GetPageCount(output_doc.get()));
505*3ac0a46fSAndroid Build Coastguard Worker 
506*3ac0a46fSAndroid Build Coastguard Worker   static constexpr int kGoodIndices4[] = {1, 2, 3};
507*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(FPDF_ImportPagesByIndex(output_doc.get(), document(),
508*3ac0a46fSAndroid Build Coastguard Worker                                       kGoodIndices4, std::size(kGoodIndices4),
509*3ac0a46fSAndroid Build Coastguard Worker                                       0));
510*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(9, FPDF_GetPageCount(output_doc.get()));
511*3ac0a46fSAndroid Build Coastguard Worker 
512*3ac0a46fSAndroid Build Coastguard Worker   // Passing in a nullptr should import all the pages.
513*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(
514*3ac0a46fSAndroid Build Coastguard Worker       FPDF_ImportPagesByIndex(output_doc.get(), document(), nullptr, 0, 0));
515*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(14, FPDF_GetPageCount(output_doc.get()));
516*3ac0a46fSAndroid Build Coastguard Worker 
517*3ac0a46fSAndroid Build Coastguard Worker   UnloadPage(page);
518*3ac0a46fSAndroid Build Coastguard Worker }
519*3ac0a46fSAndroid Build Coastguard Worker 
TEST_F(FPDFPPOEmbedderTest,BadRanges)520*3ac0a46fSAndroid Build Coastguard Worker TEST_F(FPDFPPOEmbedderTest, BadRanges) {
521*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_TRUE(OpenDocument("hello_world.pdf"));
522*3ac0a46fSAndroid Build Coastguard Worker 
523*3ac0a46fSAndroid Build Coastguard Worker   FPDF_PAGE page = LoadPage(0);
524*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(page);
525*3ac0a46fSAndroid Build Coastguard Worker 
526*3ac0a46fSAndroid Build Coastguard Worker   FPDF_DOCUMENT output_doc = FPDF_CreateNewDocument();
527*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(output_doc);
528*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(FPDF_ImportPages(output_doc, document(), "clams", 0));
529*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(FPDF_ImportPages(output_doc, document(), "0", 0));
530*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(FPDF_ImportPages(output_doc, document(), "42", 0));
531*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(FPDF_ImportPages(output_doc, document(), "1,2", 0));
532*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(FPDF_ImportPages(output_doc, document(), "1-2", 0));
533*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(FPDF_ImportPages(output_doc, document(), ",1", 0));
534*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(FPDF_ImportPages(output_doc, document(), "1,", 0));
535*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(FPDF_ImportPages(output_doc, document(), "1-", 0));
536*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(FPDF_ImportPages(output_doc, document(), "-1", 0));
537*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(FPDF_ImportPages(output_doc, document(), "-,0,,,1-", 0));
538*3ac0a46fSAndroid Build Coastguard Worker   FPDF_CloseDocument(output_doc);
539*3ac0a46fSAndroid Build Coastguard Worker 
540*3ac0a46fSAndroid Build Coastguard Worker   UnloadPage(page);
541*3ac0a46fSAndroid Build Coastguard Worker }
542*3ac0a46fSAndroid Build Coastguard Worker 
TEST_F(FPDFPPOEmbedderTest,GoodRanges)543*3ac0a46fSAndroid Build Coastguard Worker TEST_F(FPDFPPOEmbedderTest, GoodRanges) {
544*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_TRUE(OpenDocument("viewer_ref.pdf"));
545*3ac0a46fSAndroid Build Coastguard Worker 
546*3ac0a46fSAndroid Build Coastguard Worker   FPDF_PAGE page = LoadPage(0);
547*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(page);
548*3ac0a46fSAndroid Build Coastguard Worker 
549*3ac0a46fSAndroid Build Coastguard Worker   FPDF_DOCUMENT output_doc = FPDF_CreateNewDocument();
550*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(output_doc);
551*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(FPDF_CopyViewerPreferences(output_doc, document()));
552*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(FPDF_ImportPages(output_doc, document(), "1,1,1,1", 0));
553*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(4, FPDF_GetPageCount(output_doc));
554*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(FPDF_ImportPages(output_doc, document(), "1-1", 0));
555*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(5, FPDF_GetPageCount(output_doc));
556*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(FPDF_ImportPages(output_doc, document(), "5-5", 0));
557*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(6, FPDF_GetPageCount(output_doc));
558*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(FPDF_ImportPages(output_doc, document(), "2-4", 0));
559*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(9, FPDF_GetPageCount(output_doc));
560*3ac0a46fSAndroid Build Coastguard Worker   FPDF_CloseDocument(output_doc);
561*3ac0a46fSAndroid Build Coastguard Worker 
562*3ac0a46fSAndroid Build Coastguard Worker   UnloadPage(page);
563*3ac0a46fSAndroid Build Coastguard Worker }
564*3ac0a46fSAndroid Build Coastguard Worker 
TEST_F(FPDFPPOEmbedderTest,BUG_664284)565*3ac0a46fSAndroid Build Coastguard Worker TEST_F(FPDFPPOEmbedderTest, BUG_664284) {
566*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_TRUE(OpenDocument("bug_664284.pdf"));
567*3ac0a46fSAndroid Build Coastguard Worker 
568*3ac0a46fSAndroid Build Coastguard Worker   FPDF_PAGE page = LoadPage(0);
569*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_NE(nullptr, page);
570*3ac0a46fSAndroid Build Coastguard Worker 
571*3ac0a46fSAndroid Build Coastguard Worker   FPDF_DOCUMENT output_doc = FPDF_CreateNewDocument();
572*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(output_doc);
573*3ac0a46fSAndroid Build Coastguard Worker 
574*3ac0a46fSAndroid Build Coastguard Worker   static constexpr int kIndices[] = {0};
575*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(FPDF_ImportPagesByIndex(output_doc, document(), kIndices,
576*3ac0a46fSAndroid Build Coastguard Worker                                       std::size(kIndices), 0));
577*3ac0a46fSAndroid Build Coastguard Worker   FPDF_CloseDocument(output_doc);
578*3ac0a46fSAndroid Build Coastguard Worker 
579*3ac0a46fSAndroid Build Coastguard Worker   UnloadPage(page);
580*3ac0a46fSAndroid Build Coastguard Worker }
581*3ac0a46fSAndroid Build Coastguard Worker 
TEST_F(FPDFPPOEmbedderTest,BUG_750568)582*3ac0a46fSAndroid Build Coastguard Worker TEST_F(FPDFPPOEmbedderTest, BUG_750568) {
583*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_TRUE(OpenDocument("bug_750568.pdf"));
584*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_EQ(4, FPDF_GetPageCount(document()));
585*3ac0a46fSAndroid Build Coastguard Worker 
586*3ac0a46fSAndroid Build Coastguard Worker   for (size_t i = 0; i < 4; ++i) {
587*3ac0a46fSAndroid Build Coastguard Worker     FPDF_PAGE page = LoadPage(i);
588*3ac0a46fSAndroid Build Coastguard Worker     ASSERT_TRUE(page);
589*3ac0a46fSAndroid Build Coastguard Worker 
590*3ac0a46fSAndroid Build Coastguard Worker     ScopedFPDFBitmap bitmap = RenderLoadedPage(page);
591*3ac0a46fSAndroid Build Coastguard Worker     CompareBitmap(bitmap.get(), 200, 200, Bug750568PageHash(i));
592*3ac0a46fSAndroid Build Coastguard Worker     UnloadPage(page);
593*3ac0a46fSAndroid Build Coastguard Worker   }
594*3ac0a46fSAndroid Build Coastguard Worker 
595*3ac0a46fSAndroid Build Coastguard Worker   FPDF_DOCUMENT output_doc = FPDF_CreateNewDocument();
596*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_TRUE(output_doc);
597*3ac0a46fSAndroid Build Coastguard Worker 
598*3ac0a46fSAndroid Build Coastguard Worker   static constexpr int kIndices[] = {0, 1, 2, 3};
599*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(FPDF_ImportPagesByIndex(output_doc, document(), kIndices,
600*3ac0a46fSAndroid Build Coastguard Worker                                       std::size(kIndices), 0));
601*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_EQ(4, FPDF_GetPageCount(output_doc));
602*3ac0a46fSAndroid Build Coastguard Worker   for (size_t i = 0; i < 4; ++i) {
603*3ac0a46fSAndroid Build Coastguard Worker     FPDF_PAGE page = FPDF_LoadPage(output_doc, i);
604*3ac0a46fSAndroid Build Coastguard Worker     ASSERT_TRUE(page);
605*3ac0a46fSAndroid Build Coastguard Worker 
606*3ac0a46fSAndroid Build Coastguard Worker     ScopedFPDFBitmap bitmap = RenderPage(page);
607*3ac0a46fSAndroid Build Coastguard Worker     CompareBitmap(bitmap.get(), 200, 200, Bug750568PageHash(i));
608*3ac0a46fSAndroid Build Coastguard Worker     FPDF_ClosePage(page);
609*3ac0a46fSAndroid Build Coastguard Worker   }
610*3ac0a46fSAndroid Build Coastguard Worker   FPDF_CloseDocument(output_doc);
611*3ac0a46fSAndroid Build Coastguard Worker }
612*3ac0a46fSAndroid Build Coastguard Worker 
TEST_F(FPDFPPOEmbedderTest,ImportWithZeroLengthStream)613*3ac0a46fSAndroid Build Coastguard Worker TEST_F(FPDFPPOEmbedderTest, ImportWithZeroLengthStream) {
614*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_TRUE(OpenDocument("zero_length_stream.pdf"));
615*3ac0a46fSAndroid Build Coastguard Worker   FPDF_PAGE page = LoadPage(0);
616*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_TRUE(page);
617*3ac0a46fSAndroid Build Coastguard Worker 
618*3ac0a46fSAndroid Build Coastguard Worker   ScopedFPDFBitmap bitmap = RenderLoadedPage(page);
619*3ac0a46fSAndroid Build Coastguard Worker   CompareBitmap(bitmap.get(), 200, 200, pdfium::HelloWorldChecksum());
620*3ac0a46fSAndroid Build Coastguard Worker   UnloadPage(page);
621*3ac0a46fSAndroid Build Coastguard Worker 
622*3ac0a46fSAndroid Build Coastguard Worker   ScopedFPDFDocument new_doc(FPDF_CreateNewDocument());
623*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_TRUE(new_doc);
624*3ac0a46fSAndroid Build Coastguard Worker 
625*3ac0a46fSAndroid Build Coastguard Worker   static constexpr int kIndices[] = {0};
626*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(FPDF_ImportPagesByIndex(new_doc.get(), document(), kIndices,
627*3ac0a46fSAndroid Build Coastguard Worker                                       std::size(kIndices), 0));
628*3ac0a46fSAndroid Build Coastguard Worker 
629*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(1, FPDF_GetPageCount(new_doc.get()));
630*3ac0a46fSAndroid Build Coastguard Worker   ScopedFPDFPage new_page(FPDF_LoadPage(new_doc.get(), 0));
631*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_TRUE(new_page);
632*3ac0a46fSAndroid Build Coastguard Worker   ScopedFPDFBitmap new_bitmap = RenderPage(new_page.get());
633*3ac0a46fSAndroid Build Coastguard Worker   CompareBitmap(new_bitmap.get(), 200, 200, pdfium::HelloWorldChecksum());
634*3ac0a46fSAndroid Build Coastguard Worker }
635