1 // Copyright 2015 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 <memory>
6 #include <set>
7 #include <string>
8 #include <vector>
9
10 #include "core/fpdfapi/parser/cpdf_document.h"
11 #include "core/fxcrt/fx_string.h"
12 #include "fpdfsdk/cpdfsdk_helpers.h"
13 #include "public/cpp/fpdf_scopers.h"
14 #include "public/fpdf_doc.h"
15 #include "public/fpdf_edit.h"
16 #include "public/fpdfview.h"
17 #include "testing/embedder_test.h"
18 #include "testing/fx_string_testhelpers.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20
21 class FPDFDocEmbedderTest : public EmbedderTest {};
22
TEST_F(FPDFDocEmbedderTest,MultipleSamePage)23 TEST_F(FPDFDocEmbedderTest, MultipleSamePage) {
24 EXPECT_TRUE(OpenDocument("hello_world.pdf"));
25 CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document());
26
27 std::set<FPDF_PAGE> unique_pages;
28 std::vector<ScopedFPDFPage> owned_pages(4);
29 for (auto& ref : owned_pages) {
30 ref.reset(FPDF_LoadPage(document(), 0));
31 unique_pages.insert(ref.get());
32 }
33 #ifdef PDF_ENABLE_XFA
34 EXPECT_EQ(1u, unique_pages.size());
35 EXPECT_EQ(1u, pDoc->GetParsedPageCountForTesting());
36 #else // PDF_ENABLE_XFA
37 EXPECT_EQ(4u, unique_pages.size());
38 EXPECT_EQ(4u, pDoc->GetParsedPageCountForTesting());
39 #endif // PDF_ENABLE_XFA
40 }
41
TEST_F(FPDFDocEmbedderTest,DestGetPageIndex)42 TEST_F(FPDFDocEmbedderTest, DestGetPageIndex) {
43 EXPECT_TRUE(OpenDocument("named_dests.pdf"));
44
45 // NULL argument cases.
46 EXPECT_EQ(-1, FPDFDest_GetDestPageIndex(nullptr, nullptr));
47 EXPECT_EQ(-1, FPDFDest_GetDestPageIndex(document(), nullptr));
48
49 // Page number directly in item from Dests NameTree.
50 FPDF_DEST dest = FPDF_GetNamedDestByName(document(), "First");
51 EXPECT_TRUE(dest);
52 EXPECT_EQ(1, FPDFDest_GetDestPageIndex(document(), dest));
53
54 // Page number via object reference in item from Dests NameTree.
55 dest = FPDF_GetNamedDestByName(document(), "Next");
56 EXPECT_TRUE(dest);
57 EXPECT_EQ(1, FPDFDest_GetDestPageIndex(document(), dest));
58
59 // Page number directly in item from Dests dictionary.
60 dest = FPDF_GetNamedDestByName(document(), "FirstAlternate");
61 EXPECT_TRUE(dest);
62 EXPECT_EQ(11, FPDFDest_GetDestPageIndex(document(), dest));
63
64 // Invalid object reference in item from Dests NameTree.
65 dest = FPDF_GetNamedDestByName(document(), "LastAlternate");
66 EXPECT_TRUE(dest);
67 EXPECT_EQ(-1, FPDFDest_GetDestPageIndex(document(), dest));
68 }
69
TEST_F(FPDFDocEmbedderTest,DestGetView)70 TEST_F(FPDFDocEmbedderTest, DestGetView) {
71 EXPECT_TRUE(OpenDocument("named_dests.pdf"));
72
73 unsigned long numParams;
74 FS_FLOAT params[4];
75
76 numParams = 42;
77 std::fill_n(params, 4, 42.4242f);
78 EXPECT_EQ(static_cast<unsigned long>(PDFDEST_VIEW_UNKNOWN_MODE),
79 FPDFDest_GetView(nullptr, &numParams, params));
80 EXPECT_EQ(0U, numParams);
81 EXPECT_FLOAT_EQ(42.4242f, params[0]);
82
83 numParams = 42;
84 std::fill_n(params, 4, 42.4242f);
85 FPDF_DEST dest = FPDF_GetNamedDestByName(document(), "First");
86 EXPECT_TRUE(dest);
87 EXPECT_EQ(static_cast<unsigned long>(PDFDEST_VIEW_XYZ),
88 FPDFDest_GetView(dest, &numParams, params));
89 EXPECT_EQ(3U, numParams);
90 EXPECT_FLOAT_EQ(0, params[0]);
91 EXPECT_FLOAT_EQ(0, params[1]);
92 EXPECT_FLOAT_EQ(1, params[2]);
93 EXPECT_FLOAT_EQ(42.4242f, params[3]);
94
95 numParams = 42;
96 std::fill_n(params, 4, 42.4242f);
97 dest = FPDF_GetNamedDestByName(document(), "Next");
98 EXPECT_TRUE(dest);
99 EXPECT_EQ(static_cast<unsigned long>(PDFDEST_VIEW_FIT),
100 FPDFDest_GetView(dest, &numParams, params));
101 EXPECT_EQ(0U, numParams);
102 EXPECT_FLOAT_EQ(42.4242f, params[0]);
103
104 numParams = 42;
105 std::fill_n(params, 4, 42.4242f);
106 dest = FPDF_GetNamedDestByName(document(), "FirstAlternate");
107 EXPECT_TRUE(dest);
108 EXPECT_EQ(static_cast<unsigned long>(PDFDEST_VIEW_XYZ),
109 FPDFDest_GetView(dest, &numParams, params));
110 EXPECT_EQ(3U, numParams);
111 EXPECT_FLOAT_EQ(200, params[0]);
112 EXPECT_FLOAT_EQ(400, params[1]);
113 EXPECT_FLOAT_EQ(800, params[2]);
114 EXPECT_FLOAT_EQ(42.4242f, params[3]);
115
116 numParams = 42;
117 std::fill_n(params, 4, 42.4242f);
118 dest = FPDF_GetNamedDestByName(document(), "LastAlternate");
119 EXPECT_TRUE(dest);
120 EXPECT_EQ(static_cast<unsigned long>(PDFDEST_VIEW_XYZ),
121 FPDFDest_GetView(dest, &numParams, params));
122 EXPECT_EQ(3U, numParams);
123 EXPECT_FLOAT_EQ(0, params[0]);
124 EXPECT_FLOAT_EQ(0, params[1]);
125 EXPECT_FLOAT_EQ(-200, params[2]);
126 EXPECT_FLOAT_EQ(42.4242f, params[3]);
127 }
128
TEST_F(FPDFDocEmbedderTest,DestGetLocationInPage)129 TEST_F(FPDFDocEmbedderTest, DestGetLocationInPage) {
130 EXPECT_TRUE(OpenDocument("named_dests.pdf"));
131
132 FPDF_DEST dest = FPDF_GetNamedDestByName(document(), "First");
133 EXPECT_TRUE(dest);
134
135 FPDF_BOOL hasX = 0;
136 FPDF_BOOL hasY = 0;
137 FPDF_BOOL hasZoom = 0;
138 FS_FLOAT x = -1.0f;
139 FS_FLOAT y = -1.0f;
140 FS_FLOAT zoom = -1.0f;
141
142 // NULL argument case
143 EXPECT_FALSE(FPDFDest_GetLocationInPage(nullptr, &hasX, &hasY, &hasZoom, &x,
144 &y, &zoom));
145
146 // Actual argument case.
147 EXPECT_TRUE(
148 FPDFDest_GetLocationInPage(dest, &hasX, &hasY, &hasZoom, &x, &y, &zoom));
149 EXPECT_TRUE(hasX);
150 EXPECT_TRUE(hasY);
151 EXPECT_TRUE(hasZoom);
152 EXPECT_EQ(0, x);
153 EXPECT_EQ(0, y);
154 EXPECT_EQ(1, zoom);
155 }
156
TEST_F(FPDFDocEmbedderTest,BUG_680376)157 TEST_F(FPDFDocEmbedderTest, BUG_680376) {
158 EXPECT_TRUE(OpenDocument("bug_680376.pdf"));
159
160 // Page number directly in item from Dests NameTree.
161 FPDF_DEST dest = FPDF_GetNamedDestByName(document(), "First");
162 EXPECT_TRUE(dest);
163 EXPECT_EQ(-1, FPDFDest_GetDestPageIndex(document(), dest));
164 }
165
TEST_F(FPDFDocEmbedderTest,BUG_821454)166 TEST_F(FPDFDocEmbedderTest, BUG_821454) {
167 EXPECT_TRUE(OpenDocument("bug_821454.pdf"));
168
169 FPDF_PAGE page = LoadPage(0);
170 ASSERT_TRUE(page);
171
172 // Cover some NULL arg cases while we're at it.
173 EXPECT_FALSE(FPDFLink_GetLinkAtPoint(nullptr, 150, 360));
174 EXPECT_EQ(-1, FPDFLink_GetLinkZOrderAtPoint(nullptr, 150, 360));
175
176 FPDF_LINK link1 = FPDFLink_GetLinkAtPoint(page, 150, 360);
177 ASSERT_TRUE(link1);
178 FPDF_LINK link2 = FPDFLink_GetLinkAtPoint(page, 150, 420);
179 ASSERT_TRUE(link2);
180
181 EXPECT_EQ(0, FPDFLink_GetLinkZOrderAtPoint(page, 150, 360));
182 EXPECT_EQ(1, FPDFLink_GetLinkZOrderAtPoint(page, 150, 420));
183
184 FPDF_DEST dest1 = FPDFLink_GetDest(document(), link1);
185 ASSERT_TRUE(dest1);
186 FPDF_DEST dest2 = FPDFLink_GetDest(document(), link2);
187 ASSERT_TRUE(dest2);
188
189 EXPECT_EQ(0, FPDFDest_GetDestPageIndex(document(), dest1));
190 EXPECT_EQ(0, FPDFDest_GetDestPageIndex(document(), dest2));
191
192 {
193 FPDF_BOOL has_x_coord;
194 FPDF_BOOL has_y_coord;
195 FPDF_BOOL has_zoom;
196 FS_FLOAT x;
197 FS_FLOAT y;
198 FS_FLOAT zoom;
199 FPDF_BOOL success = FPDFDest_GetLocationInPage(
200 dest1, &has_x_coord, &has_y_coord, &has_zoom, &x, &y, &zoom);
201 ASSERT_TRUE(success);
202 EXPECT_TRUE(has_x_coord);
203 EXPECT_TRUE(has_y_coord);
204 EXPECT_FALSE(has_zoom);
205 EXPECT_FLOAT_EQ(100.0f, x);
206 EXPECT_FLOAT_EQ(200.0f, y);
207 }
208 {
209 FPDF_BOOL has_x_coord;
210 FPDF_BOOL has_y_coord;
211 FPDF_BOOL has_zoom;
212 FS_FLOAT x;
213 FS_FLOAT y;
214 FS_FLOAT zoom;
215 FPDF_BOOL success = FPDFDest_GetLocationInPage(
216 dest2, &has_x_coord, &has_y_coord, &has_zoom, &x, &y, &zoom);
217 ASSERT_TRUE(success);
218 EXPECT_TRUE(has_x_coord);
219 EXPECT_TRUE(has_y_coord);
220 EXPECT_FALSE(has_zoom);
221 EXPECT_FLOAT_EQ(150.0f, x);
222 EXPECT_FLOAT_EQ(250.0f, y);
223 }
224
225 UnloadPage(page);
226 }
227
TEST_F(FPDFDocEmbedderTest,ActionBadArguments)228 TEST_F(FPDFDocEmbedderTest, ActionBadArguments) {
229 EXPECT_TRUE(OpenDocument("launch_action.pdf"));
230 EXPECT_EQ(static_cast<unsigned long>(PDFACTION_UNSUPPORTED),
231 FPDFAction_GetType(nullptr));
232
233 EXPECT_EQ(nullptr, FPDFAction_GetDest(nullptr, nullptr));
234 EXPECT_EQ(nullptr, FPDFAction_GetDest(document(), nullptr));
235 EXPECT_EQ(0u, FPDFAction_GetFilePath(nullptr, nullptr, 0));
236 EXPECT_EQ(0u, FPDFAction_GetURIPath(nullptr, nullptr, nullptr, 0));
237 EXPECT_EQ(0u, FPDFAction_GetURIPath(document(), nullptr, nullptr, 0));
238 }
239
TEST_F(FPDFDocEmbedderTest,ActionLaunch)240 TEST_F(FPDFDocEmbedderTest, ActionLaunch) {
241 EXPECT_TRUE(OpenDocument("launch_action.pdf"));
242
243 FPDF_PAGE page = LoadPage(0);
244 ASSERT_TRUE(page);
245
246 // The target action is nearly the size of the whole page.
247 FPDF_LINK link = FPDFLink_GetLinkAtPoint(page, 100, 100);
248 ASSERT_TRUE(link);
249
250 FPDF_ACTION action = FPDFLink_GetAction(link);
251 ASSERT_TRUE(action);
252 EXPECT_EQ(static_cast<unsigned long>(PDFACTION_LAUNCH),
253 FPDFAction_GetType(action));
254
255 const char kExpectedResult[] = "test.pdf";
256 const unsigned long kExpectedLength = sizeof(kExpectedResult);
257 unsigned long bufsize = FPDFAction_GetFilePath(action, nullptr, 0);
258 EXPECT_EQ(kExpectedLength, bufsize);
259
260 char buf[1024];
261 EXPECT_EQ(bufsize, FPDFAction_GetFilePath(action, buf, bufsize));
262 EXPECT_STREQ(kExpectedResult, buf);
263
264 // Other public methods are not appropriate for launch actions.
265 EXPECT_EQ(nullptr, FPDFAction_GetDest(document(), action));
266 EXPECT_EQ(0u, FPDFAction_GetURIPath(document(), action, buf, sizeof(buf)));
267
268 UnloadPage(page);
269 }
270
TEST_F(FPDFDocEmbedderTest,ActionURI)271 TEST_F(FPDFDocEmbedderTest, ActionURI) {
272 EXPECT_TRUE(OpenDocument("uri_action.pdf"));
273
274 FPDF_PAGE page = LoadPage(0);
275 ASSERT_TRUE(page);
276
277 // The target action is nearly the size of the whole page.
278 FPDF_LINK link = FPDFLink_GetLinkAtPoint(page, 100, 100);
279 ASSERT_TRUE(link);
280
281 FPDF_ACTION action = FPDFLink_GetAction(link);
282 ASSERT_TRUE(action);
283 EXPECT_EQ(static_cast<unsigned long>(PDFACTION_URI),
284 FPDFAction_GetType(action));
285
286 const char kExpectedResult[] = "https://example.com/page.html";
287 const unsigned long kExpectedLength = sizeof(kExpectedResult);
288 unsigned long bufsize = FPDFAction_GetURIPath(document(), action, nullptr, 0);
289 ASSERT_EQ(kExpectedLength, bufsize);
290
291 char buf[1024];
292 EXPECT_EQ(bufsize, FPDFAction_GetURIPath(document(), action, buf, bufsize));
293 EXPECT_STREQ(kExpectedResult, buf);
294
295 // Other public methods are not appropriate for URI actions
296 EXPECT_EQ(nullptr, FPDFAction_GetDest(document(), action));
297 EXPECT_EQ(0u, FPDFAction_GetFilePath(action, buf, sizeof(buf)));
298
299 UnloadPage(page);
300 }
301
TEST_F(FPDFDocEmbedderTest,ActionGoto)302 TEST_F(FPDFDocEmbedderTest, ActionGoto) {
303 EXPECT_TRUE(OpenDocument("goto_action.pdf"));
304
305 FPDF_PAGE page = LoadPage(0);
306 ASSERT_TRUE(page);
307
308 // The target action is nearly the size of the whole page.
309 FPDF_LINK link = FPDFLink_GetLinkAtPoint(page, 100, 100);
310 ASSERT_TRUE(link);
311
312 FPDF_ACTION action = FPDFLink_GetAction(link);
313 ASSERT_TRUE(action);
314 EXPECT_EQ(static_cast<unsigned long>(PDFACTION_GOTO),
315 FPDFAction_GetType(action));
316
317 EXPECT_TRUE(FPDFAction_GetDest(document(), action));
318
319 // Other public methods are not appropriate for GoTo actions.
320 char buf[1024];
321 EXPECT_EQ(0u, FPDFAction_GetFilePath(action, buf, sizeof(buf)));
322 EXPECT_EQ(0u, FPDFAction_GetURIPath(document(), action, buf, sizeof(buf)));
323
324 UnloadPage(page);
325 }
326
TEST_F(FPDFDocEmbedderTest,ActionNonesuch)327 TEST_F(FPDFDocEmbedderTest, ActionNonesuch) {
328 EXPECT_TRUE(OpenDocument("nonesuch_action.pdf"));
329
330 FPDF_PAGE page = LoadPage(0);
331 ASSERT_TRUE(page);
332
333 // The target action is nearly the size of the whole page.
334 FPDF_LINK link = FPDFLink_GetLinkAtPoint(page, 100, 100);
335 ASSERT_TRUE(link);
336
337 FPDF_ACTION action = FPDFLink_GetAction(link);
338 ASSERT_TRUE(action);
339 EXPECT_EQ(static_cast<unsigned long>(PDFACTION_UNSUPPORTED),
340 FPDFAction_GetType(action));
341
342 // No public methods are appropriate for unsupported actions.
343 char buf[1024];
344 EXPECT_FALSE(FPDFAction_GetDest(document(), action));
345 EXPECT_EQ(0u, FPDFAction_GetFilePath(action, buf, sizeof(buf)));
346 EXPECT_EQ(0u, FPDFAction_GetURIPath(document(), action, buf, sizeof(buf)));
347
348 UnloadPage(page);
349 }
350
TEST_F(FPDFDocEmbedderTest,NoBookmarks)351 TEST_F(FPDFDocEmbedderTest, NoBookmarks) {
352 unsigned short buf[128];
353
354 // Open a file with no bookmarks.
355 EXPECT_TRUE(OpenDocument("named_dests.pdf"));
356
357 // NULL argument cases.
358 EXPECT_EQ(0u, FPDFBookmark_GetTitle(nullptr, buf, sizeof(buf)));
359 EXPECT_EQ(nullptr, FPDFBookmark_GetFirstChild(nullptr, nullptr));
360 EXPECT_EQ(nullptr, FPDFBookmark_GetFirstChild(document(), nullptr));
361 EXPECT_EQ(nullptr, FPDFBookmark_GetNextSibling(nullptr, nullptr));
362 EXPECT_EQ(nullptr, FPDFBookmark_GetNextSibling(document(), nullptr));
363 EXPECT_EQ(nullptr, FPDFBookmark_Find(nullptr, nullptr));
364 EXPECT_EQ(nullptr, FPDFBookmark_Find(document(), nullptr));
365 EXPECT_EQ(nullptr, FPDFBookmark_GetDest(nullptr, nullptr));
366 EXPECT_EQ(nullptr, FPDFBookmark_GetDest(document(), nullptr));
367 EXPECT_EQ(nullptr, FPDFBookmark_GetAction(nullptr));
368 }
369
TEST_F(FPDFDocEmbedderTest,Bookmarks)370 TEST_F(FPDFDocEmbedderTest, Bookmarks) {
371 unsigned short buf[128];
372
373 // Open a file with two bookmarks.
374 EXPECT_TRUE(OpenDocument("bookmarks.pdf"));
375
376 FPDF_BOOKMARK child = FPDFBookmark_GetFirstChild(document(), nullptr);
377 EXPECT_TRUE(child);
378 EXPECT_EQ(34u, FPDFBookmark_GetTitle(child, buf, sizeof(buf)));
379 EXPECT_EQ(WideString(L"A Good Beginning"), WideString::FromUTF16LE(buf, 16));
380
381 FPDF_DEST dest = FPDFBookmark_GetDest(document(), child);
382 EXPECT_FALSE(dest); // TODO(tsepez): put real dest into bookmarks.pdf
383
384 FPDF_ACTION action = FPDFBookmark_GetAction(child);
385 EXPECT_FALSE(action); // TODO(tsepez): put real action into bookmarks.pdf
386
387 FPDF_BOOKMARK grand_child = FPDFBookmark_GetFirstChild(document(), child);
388 EXPECT_FALSE(grand_child);
389
390 FPDF_BOOKMARK sibling = FPDFBookmark_GetNextSibling(document(), child);
391 EXPECT_TRUE(sibling);
392 EXPECT_EQ(28u, FPDFBookmark_GetTitle(sibling, buf, sizeof(buf)));
393 EXPECT_EQ(WideString(L"A Good Ending"), WideString::FromUTF16LE(buf, 13));
394
395 EXPECT_EQ(nullptr, FPDFBookmark_GetNextSibling(document(), sibling));
396 }
397
TEST_F(FPDFDocEmbedderTest,FindBookmarks)398 TEST_F(FPDFDocEmbedderTest, FindBookmarks) {
399 unsigned short buf[128];
400
401 // Open a file with two bookmarks.
402 EXPECT_TRUE(OpenDocument("bookmarks.pdf"));
403
404 // Find the first one, based on its known title.
405 ScopedFPDFWideString title = GetFPDFWideString(L"A Good Beginning");
406 FPDF_BOOKMARK child = FPDFBookmark_Find(document(), title.get());
407 EXPECT_TRUE(child);
408
409 // Check that the string matches.
410 EXPECT_EQ(34u, FPDFBookmark_GetTitle(child, buf, sizeof(buf)));
411 EXPECT_EQ(WideString(L"A Good Beginning"), WideString::FromUTF16LE(buf, 16));
412
413 // Check that it is them same as the one returned by GetFirstChild.
414 EXPECT_EQ(child, FPDFBookmark_GetFirstChild(document(), nullptr));
415
416 // Try to find one using a non-existent title.
417 ScopedFPDFWideString bad_title = GetFPDFWideString(L"A BAD Beginning");
418 EXPECT_EQ(nullptr, FPDFBookmark_Find(document(), bad_title.get()));
419 }
420
421 // Check circular bookmarks will not cause infinite loop.
TEST_F(FPDFDocEmbedderTest,FindBookmarks_bug420)422 TEST_F(FPDFDocEmbedderTest, FindBookmarks_bug420) {
423 // Open a file with circular bookmarks.
424 EXPECT_TRUE(OpenDocument("bookmarks_circular.pdf"));
425
426 // Try to find a title.
427 ScopedFPDFWideString title = GetFPDFWideString(L"anything");
428 EXPECT_EQ(nullptr, FPDFBookmark_Find(document(), title.get()));
429 }
430
TEST_F(FPDFDocEmbedderTest,DeletePage)431 TEST_F(FPDFDocEmbedderTest, DeletePage) {
432 EXPECT_TRUE(OpenDocument("hello_world.pdf"));
433 EXPECT_EQ(1, FPDF_GetPageCount(document()));
434
435 FPDFPage_Delete(nullptr, 0);
436 EXPECT_EQ(1, FPDF_GetPageCount(document()));
437
438 FPDFPage_Delete(document(), -1);
439 EXPECT_EQ(1, FPDF_GetPageCount(document()));
440 FPDFPage_Delete(document(), 1);
441 EXPECT_EQ(1, FPDF_GetPageCount(document()));
442
443 FPDFPage_Delete(document(), 0);
444 EXPECT_EQ(0, FPDF_GetPageCount(document()));
445 }
446
TEST_F(FPDFDocEmbedderTest,GetMetaText)447 TEST_F(FPDFDocEmbedderTest, GetMetaText) {
448 ASSERT_TRUE(OpenDocument("bug_601362.pdf"));
449
450 // Invalid document / tag results in 0.
451 unsigned short buf[128];
452 EXPECT_EQ(0u, FPDF_GetMetaText(document(), nullptr, buf, sizeof(buf)));
453 EXPECT_EQ(0u, FPDF_GetMetaText(nullptr, "", buf, sizeof(buf)));
454
455 // Tags that do not eixst results in an empty wide string.
456 EXPECT_EQ(2u, FPDF_GetMetaText(document(), "", buf, sizeof(buf)));
457 EXPECT_EQ(2u, FPDF_GetMetaText(document(), "foo", buf, sizeof(buf)));
458 ASSERT_EQ(2u, FPDF_GetMetaText(document(), "Title", buf, sizeof(buf)));
459 ASSERT_EQ(2u, FPDF_GetMetaText(document(), "Author", buf, sizeof(buf)));
460 ASSERT_EQ(2u, FPDF_GetMetaText(document(), "Subject", buf, sizeof(buf)));
461 ASSERT_EQ(2u, FPDF_GetMetaText(document(), "Keywords", buf, sizeof(buf)));
462 ASSERT_EQ(2u, FPDF_GetMetaText(document(), "Producer", buf, sizeof(buf)));
463
464 constexpr wchar_t kExpectedCreator[] = L"Microsoft Word";
465 ASSERT_EQ(30u, FPDF_GetMetaText(document(), "Creator", buf, sizeof(buf)));
466 EXPECT_EQ(WideString(kExpectedCreator),
467 WideString::FromUTF16LE(buf, FXSYS_len(kExpectedCreator)));
468
469 constexpr wchar_t kExpectedCreationDate[] = L"D:20160411190039+00'00'";
470 ASSERT_EQ(48u,
471 FPDF_GetMetaText(document(), "CreationDate", buf, sizeof(buf)));
472 EXPECT_EQ(WideString(kExpectedCreationDate),
473 WideString::FromUTF16LE(buf, FXSYS_len(kExpectedCreationDate)));
474
475 constexpr wchar_t kExpectedModDate[] = L"D:20160411190039+00'00'";
476 ASSERT_EQ(48u, FPDF_GetMetaText(document(), "ModDate", buf, sizeof(buf)));
477 EXPECT_EQ(WideString(kExpectedModDate),
478 WideString::FromUTF16LE(buf, FXSYS_len(kExpectedModDate)));
479 }
480
TEST_F(FPDFDocEmbedderTest,Bug_182)481 TEST_F(FPDFDocEmbedderTest, Bug_182) {
482 ASSERT_TRUE(OpenDocument("bug_182.pdf"));
483
484 unsigned short buf[128];
485 constexpr wchar_t kExpectedTitle[] = L"Super Visual Formade 印刷";
486
487 ASSERT_EQ(48u, FPDF_GetMetaText(document(), "Title", buf, sizeof(buf)));
488 EXPECT_EQ(WideString(kExpectedTitle),
489 WideString::FromUTF16LE(buf, FXSYS_len(kExpectedTitle)));
490 }
491
TEST_F(FPDFDocEmbedderTest,GetMetaTextSameObjectNumber)492 TEST_F(FPDFDocEmbedderTest, GetMetaTextSameObjectNumber) {
493 ASSERT_TRUE(OpenDocument("annotation_highlight_square_with_ap.pdf"));
494
495 // The PDF has been edited. It has two %%EOF markers, and 2 objects numbered
496 // (1 0). Both objects are /Info dictionaries, but contain different data.
497 // Make sure ModDate is the date of the last modification.
498 unsigned short buf[128];
499 constexpr wchar_t kExpectedModDate[] = L"D:20170612232940-04'00'";
500 ASSERT_EQ(48u, FPDF_GetMetaText(document(), "ModDate", buf, sizeof(buf)));
501 EXPECT_EQ(WideString(kExpectedModDate),
502 WideString::FromUTF16LE(buf, FXSYS_len(kExpectedModDate)));
503 }
504
TEST_F(FPDFDocEmbedderTest,GetMetaTextInAttachmentFile)505 TEST_F(FPDFDocEmbedderTest, GetMetaTextInAttachmentFile) {
506 ASSERT_TRUE(OpenDocument("embedded_attachments.pdf"));
507
508 // Make sure this is the date from the PDF itself and not the attached PDF.
509 unsigned short buf[128];
510 constexpr wchar_t kExpectedModDate[] = L"D:20170712214448-07'00'";
511 ASSERT_EQ(48u, FPDF_GetMetaText(document(), "ModDate", buf, sizeof(buf)));
512 EXPECT_EQ(WideString(kExpectedModDate),
513 WideString::FromUTF16LE(buf, FXSYS_len(kExpectedModDate)));
514 }
515
TEST_F(FPDFDocEmbedderTest,GetMetaTextFromNewDocument)516 TEST_F(FPDFDocEmbedderTest, GetMetaTextFromNewDocument) {
517 FPDF_DOCUMENT empty_doc = FPDF_CreateNewDocument();
518 unsigned short buf[128];
519 EXPECT_EQ(2u, FPDF_GetMetaText(empty_doc, "Title", buf, sizeof(buf)));
520 FPDF_CloseDocument(empty_doc);
521 }
522
TEST_F(FPDFDocEmbedderTest,NoPageLabels)523 TEST_F(FPDFDocEmbedderTest, NoPageLabels) {
524 EXPECT_TRUE(OpenDocument("about_blank.pdf"));
525 EXPECT_EQ(1, FPDF_GetPageCount(document()));
526
527 ASSERT_EQ(0u, FPDF_GetPageLabel(document(), 0, nullptr, 0));
528 }
529
TEST_F(FPDFDocEmbedderTest,GetPageLabels)530 TEST_F(FPDFDocEmbedderTest, GetPageLabels) {
531 EXPECT_TRUE(OpenDocument("page_labels.pdf"));
532 EXPECT_EQ(7, FPDF_GetPageCount(document()));
533
534 // We do not request labels, when use FPDFAvail_IsXXXAvail.
535 // Flush all data, to allow read labels.
536 SetWholeFileAvailable();
537
538 unsigned short buf[128];
539 EXPECT_EQ(0u, FPDF_GetPageLabel(document(), -2, buf, sizeof(buf)));
540 EXPECT_EQ(0u, FPDF_GetPageLabel(document(), -1, buf, sizeof(buf)));
541
542 const wchar_t kExpectedPageLabel0[] = L"i";
543 ASSERT_EQ(4u, FPDF_GetPageLabel(document(), 0, buf, sizeof(buf)));
544 EXPECT_EQ(WideString(kExpectedPageLabel0),
545 WideString::FromUTF16LE(buf, FXSYS_len(kExpectedPageLabel0)));
546
547 const wchar_t kExpectedPageLabel1[] = L"ii";
548 ASSERT_EQ(6u, FPDF_GetPageLabel(document(), 1, buf, sizeof(buf)));
549 EXPECT_EQ(WideString(kExpectedPageLabel1),
550 WideString::FromUTF16LE(buf, FXSYS_len(kExpectedPageLabel1)));
551
552 const wchar_t kExpectedPageLabel2[] = L"1";
553 ASSERT_EQ(4u, FPDF_GetPageLabel(document(), 2, buf, sizeof(buf)));
554 EXPECT_EQ(WideString(kExpectedPageLabel2),
555 WideString::FromUTF16LE(buf, FXSYS_len(kExpectedPageLabel2)));
556
557 const wchar_t kExpectedPageLabel3[] = L"2";
558 ASSERT_EQ(4u, FPDF_GetPageLabel(document(), 3, buf, sizeof(buf)));
559 EXPECT_EQ(WideString(kExpectedPageLabel3),
560 WideString::FromUTF16LE(buf, FXSYS_len(kExpectedPageLabel3)));
561
562 const wchar_t kExpectedPageLabel4[] = L"zzA";
563 ASSERT_EQ(8u, FPDF_GetPageLabel(document(), 4, buf, sizeof(buf)));
564 EXPECT_EQ(WideString(kExpectedPageLabel4),
565 WideString::FromUTF16LE(buf, FXSYS_len(kExpectedPageLabel4)));
566
567 const wchar_t kExpectedPageLabel5[] = L"zzB";
568 ASSERT_EQ(8u, FPDF_GetPageLabel(document(), 5, buf, sizeof(buf)));
569 EXPECT_EQ(WideString(kExpectedPageLabel5),
570 WideString::FromUTF16LE(buf, FXSYS_len(kExpectedPageLabel5)));
571
572 const wchar_t kExpectedPageLabel6[] = L"";
573 ASSERT_EQ(2u, FPDF_GetPageLabel(document(), 6, buf, sizeof(buf)));
574 EXPECT_EQ(WideString(kExpectedPageLabel6),
575 WideString::FromUTF16LE(buf, FXSYS_len(kExpectedPageLabel6)));
576
577 ASSERT_EQ(0u, FPDF_GetPageLabel(document(), 7, buf, sizeof(buf)));
578 ASSERT_EQ(0u, FPDF_GetPageLabel(document(), 8, buf, sizeof(buf)));
579 }
580
581 #ifdef PDF_ENABLE_XFA
TEST_F(FPDFDocEmbedderTest,GetXFALinks)582 TEST_F(FPDFDocEmbedderTest, GetXFALinks) {
583 EXPECT_TRUE(OpenDocument("simple_xfa.pdf"));
584
585 ScopedFPDFPage page(FPDF_LoadPage(document(), 0));
586 ASSERT_TRUE(page);
587
588 FPDFLink_GetLinkAtPoint(page.get(), 150, 360);
589 FPDFLink_GetLinkAtPoint(page.get(), 150, 420);
590
591 // Test passes if it doesn't crash. See https://crbug.com/840922
592 }
593 #endif // PDF_ENABLE_XFA
594