Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
fpdf_doc_embeddertest.cpp
Go to the documentation of this file.
1// Copyright 2015 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 <set>
6#include <vector>
7
8#include "core/fpdfapi/parser/cpdf_document.h"
9#include "core/fxcrt/bytestring.h"
10#include "core/fxge/cfx_defaultrenderdevice.h"
11#include "fpdfsdk/cpdfsdk_helpers.h"
12#include "public/cpp/fpdf_scopers.h"
13#include "public/fpdf_doc.h"
14#include "public/fpdf_edit.h"
15#include "public/fpdfview.h"
16#include "testing/embedder_test.h"
17#include "testing/fx_string_testhelpers.h"
18#include "testing/gtest/include/gtest/gtest.h"
19
21
23 ASSERT_TRUE(OpenDocument("hello_world.pdf"));
24 CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document());
25
26 std::set<FPDF_PAGE> unique_pages;
27 std::vector<ScopedFPDFPage> owned_pages(4);
28 for (auto& ref : owned_pages) {
29 ref.reset(FPDF_LoadPage(document(), 0));
30 unique_pages.insert(ref.get());
31 }
32#ifdef PDF_ENABLE_XFA
33 EXPECT_EQ(1u, unique_pages.size());
34 EXPECT_EQ(1u, pDoc->GetParsedPageCountForTesting());
35#else // PDF_ENABLE_XFA
36 EXPECT_EQ(4u, unique_pages.size());
37 EXPECT_EQ(4u, pDoc->GetParsedPageCountForTesting());
38#endif // PDF_ENABLE_XFA
39}
40
42 ASSERT_TRUE(OpenDocument("named_dests.pdf"));
43
44 // NULL argument cases.
45 EXPECT_EQ(-1, FPDFDest_GetDestPageIndex(nullptr, nullptr));
46 EXPECT_EQ(-1, FPDFDest_GetDestPageIndex(document(), nullptr));
47
48 // Page number directly in item from Dests NameTree.
49 FPDF_DEST dest = FPDF_GetNamedDestByName(document(), "First");
50 EXPECT_TRUE(dest);
51 EXPECT_EQ(1, FPDFDest_GetDestPageIndex(document(), dest));
52
53 // Page number via object reference in item from Dests NameTree.
54 dest = FPDF_GetNamedDestByName(document(), "Next");
55 EXPECT_TRUE(dest);
56 EXPECT_EQ(1, FPDFDest_GetDestPageIndex(document(), dest));
57
58 // Page number directly in item from Dests dictionary.
59 dest = FPDF_GetNamedDestByName(document(), "FirstAlternate");
60 EXPECT_TRUE(dest);
61 EXPECT_EQ(11, FPDFDest_GetDestPageIndex(document(), dest));
62
63 // Invalid object reference in item from Dests NameTree.
64 dest = FPDF_GetNamedDestByName(document(), "LastAlternate");
65 EXPECT_TRUE(dest);
66 EXPECT_EQ(-1, FPDFDest_GetDestPageIndex(document(), dest));
67}
68
70 ASSERT_TRUE(OpenDocument("named_dests.pdf"));
71
72 unsigned long numParams;
73 FS_FLOAT params[4];
74
75 numParams = 42;
76 std::fill_n(params, 4, 42.4242f);
77 EXPECT_EQ(static_cast<unsigned long>(PDFDEST_VIEW_UNKNOWN_MODE),
78 FPDFDest_GetView(nullptr, &numParams, params));
79 EXPECT_EQ(0U, numParams);
80 EXPECT_FLOAT_EQ(42.4242f, params[0]);
81
82 numParams = 42;
83 std::fill_n(params, 4, 42.4242f);
84 FPDF_DEST dest = FPDF_GetNamedDestByName(document(), "First");
85 EXPECT_TRUE(dest);
86 EXPECT_EQ(static_cast<unsigned long>(PDFDEST_VIEW_XYZ),
87 FPDFDest_GetView(dest, &numParams, params));
88 EXPECT_EQ(3U, numParams);
89 EXPECT_FLOAT_EQ(0, params[0]);
90 EXPECT_FLOAT_EQ(0, params[1]);
91 EXPECT_FLOAT_EQ(1, params[2]);
92 EXPECT_FLOAT_EQ(42.4242f, params[3]);
93
94 numParams = 42;
95 std::fill_n(params, 4, 42.4242f);
96 dest = FPDF_GetNamedDestByName(document(), "Next");
97 EXPECT_TRUE(dest);
98 EXPECT_EQ(static_cast<unsigned long>(PDFDEST_VIEW_FIT),
99 FPDFDest_GetView(dest, &numParams, params));
100 EXPECT_EQ(0U, numParams);
101 EXPECT_FLOAT_EQ(42.4242f, params[0]);
102
103 numParams = 42;
104 std::fill_n(params, 4, 42.4242f);
105 dest = FPDF_GetNamedDestByName(document(), "FirstAlternate");
106 EXPECT_TRUE(dest);
107 EXPECT_EQ(static_cast<unsigned long>(PDFDEST_VIEW_XYZ),
108 FPDFDest_GetView(dest, &numParams, params));
109 EXPECT_EQ(3U, numParams);
110 EXPECT_FLOAT_EQ(200, params[0]);
111 EXPECT_FLOAT_EQ(400, params[1]);
112 EXPECT_FLOAT_EQ(800, params[2]);
113 EXPECT_FLOAT_EQ(42.4242f, params[3]);
114
115 numParams = 42;
116 std::fill_n(params, 4, 42.4242f);
117 dest = FPDF_GetNamedDestByName(document(), "LastAlternate");
118 EXPECT_TRUE(dest);
119 EXPECT_EQ(static_cast<unsigned long>(PDFDEST_VIEW_XYZ),
120 FPDFDest_GetView(dest, &numParams, params));
121 EXPECT_EQ(3U, numParams);
122 EXPECT_FLOAT_EQ(0, params[0]);
123 EXPECT_FLOAT_EQ(0, params[1]);
124 EXPECT_FLOAT_EQ(-200, params[2]);
125 EXPECT_FLOAT_EQ(42.4242f, params[3]);
126}
127
129 ASSERT_TRUE(OpenDocument("named_dests.pdf"));
130
131 FPDF_DEST dest = FPDF_GetNamedDestByName(document(), "First");
132 EXPECT_TRUE(dest);
133
134 FPDF_BOOL hasX = 0;
135 FPDF_BOOL hasY = 0;
136 FPDF_BOOL hasZoom = 0;
137 FS_FLOAT x = -1.0f;
138 FS_FLOAT y = -1.0f;
139 FS_FLOAT zoom = -1.0f;
140
141 // NULL argument case
142 EXPECT_FALSE(FPDFDest_GetLocationInPage(nullptr, &hasX, &hasY, &hasZoom, &x,
143 &y, &zoom));
144
145 // Actual argument case.
146 EXPECT_TRUE(
147 FPDFDest_GetLocationInPage(dest, &hasX, &hasY, &hasZoom, &x, &y, &zoom));
148 EXPECT_TRUE(hasX);
149 EXPECT_TRUE(hasY);
150 EXPECT_TRUE(hasZoom);
151 EXPECT_EQ(0, x);
152 EXPECT_EQ(0, y);
153 EXPECT_EQ(1, zoom);
154}
155
157 ASSERT_TRUE(OpenDocument("bug_1506.pdf"));
158
159 FPDF_DEST dest = FPDF_GetNamedDestByName(document(), "First");
160 ASSERT_TRUE(dest);
161 EXPECT_EQ(3, FPDFDest_GetDestPageIndex(document(), dest));
162}
163
165 ASSERT_TRUE(OpenDocument("bug_1506.pdf"));
166
167 std::vector<FPDF_PAGE> pages;
168 for (int i : {0, 2})
169 pages.push_back(LoadPage(i));
170
171 FPDF_DEST dest = FPDF_GetNamedDestByName(document(), "First");
172 ASSERT_TRUE(dest);
173 EXPECT_EQ(3, FPDFDest_GetDestPageIndex(document(), dest));
174
175 for (FPDF_PAGE page : pages)
176 UnloadPage(page);
177}
178
180 ASSERT_TRUE(OpenDocument("bug_1506.pdf"));
181
182 std::vector<FPDF_PAGE> pages;
183 for (int i : {0, 1, 3})
184 pages.push_back(LoadPage(i));
185
186 FPDF_DEST dest = FPDF_GetNamedDestByName(document(), "First");
187 ASSERT_TRUE(dest);
188 EXPECT_EQ(3, FPDFDest_GetDestPageIndex(document(), dest));
189
190 for (FPDF_PAGE page : pages)
191 UnloadPage(page);
192}
193
195 ASSERT_TRUE(OpenDocument("bug_680376.pdf"));
196
197 // Page number directly in item from Dests NameTree.
198 FPDF_DEST dest = FPDF_GetNamedDestByName(document(), "First");
199 EXPECT_TRUE(dest);
200 EXPECT_EQ(-1, FPDFDest_GetDestPageIndex(document(), dest));
201}
202
204 ASSERT_TRUE(OpenDocument("bug_821454.pdf"));
205
206 FPDF_PAGE page = LoadPage(0);
207 ASSERT_TRUE(page);
208
209 // Cover some invalid argument cases while we're at it.
210 EXPECT_FALSE(FPDFLink_GetLinkAtPoint(nullptr, 150, 360));
211 EXPECT_EQ(-1, FPDFLink_GetLinkZOrderAtPoint(nullptr, 150, 360));
212
213 FPDF_LINK link1 = FPDFLink_GetLinkAtPoint(page, 150, 360);
214 ASSERT_TRUE(link1);
215 FPDF_LINK link2 = FPDFLink_GetLinkAtPoint(page, 150, 420);
216 ASSERT_TRUE(link2);
217
218 EXPECT_EQ(0, FPDFLink_GetLinkZOrderAtPoint(page, 150, 360));
219 EXPECT_EQ(1, FPDFLink_GetLinkZOrderAtPoint(page, 150, 420));
220
221 FPDF_DEST dest1 = FPDFLink_GetDest(document(), link1);
222 ASSERT_TRUE(dest1);
223 FPDF_DEST dest2 = FPDFLink_GetDest(document(), link2);
224 ASSERT_TRUE(dest2);
225
226 // Cover more invalid argument cases while we're at it.
227 EXPECT_FALSE(FPDFLink_GetDest(nullptr, nullptr));
228 EXPECT_FALSE(FPDFLink_GetDest(nullptr, link1));
229 EXPECT_FALSE(FPDFLink_GetDest(document(), nullptr));
230
231 EXPECT_EQ(0, FPDFDest_GetDestPageIndex(document(), dest1));
232 EXPECT_EQ(0, FPDFDest_GetDestPageIndex(document(), dest2));
233
234 {
235 FPDF_BOOL has_x_coord;
236 FPDF_BOOL has_y_coord;
237 FPDF_BOOL has_zoom;
238 FS_FLOAT x;
239 FS_FLOAT y;
240 FS_FLOAT zoom;
241 FPDF_BOOL success = FPDFDest_GetLocationInPage(
242 dest1, &has_x_coord, &has_y_coord, &has_zoom, &x, &y, &zoom);
243 ASSERT_TRUE(success);
244 EXPECT_TRUE(has_x_coord);
245 EXPECT_TRUE(has_y_coord);
246 EXPECT_FALSE(has_zoom);
247 EXPECT_FLOAT_EQ(100.0f, x);
248 EXPECT_FLOAT_EQ(200.0f, y);
249 }
250 {
251 FPDF_BOOL has_x_coord;
252 FPDF_BOOL has_y_coord;
253 FPDF_BOOL has_zoom;
254 FS_FLOAT x;
255 FS_FLOAT y;
256 FS_FLOAT zoom;
257 FPDF_BOOL success = FPDFDest_GetLocationInPage(
258 dest2, &has_x_coord, &has_y_coord, &has_zoom, &x, &y, &zoom);
259 ASSERT_TRUE(success);
260 EXPECT_TRUE(has_x_coord);
261 EXPECT_TRUE(has_y_coord);
262 EXPECT_FALSE(has_zoom);
263 EXPECT_FLOAT_EQ(150.0f, x);
264 EXPECT_FLOAT_EQ(250.0f, y);
265 }
266
267 UnloadPage(page);
268}
269
271 ASSERT_TRUE(OpenDocument("launch_action.pdf"));
272 EXPECT_EQ(static_cast<unsigned long>(PDFACTION_UNSUPPORTED),
273 FPDFAction_GetType(nullptr));
274
275 EXPECT_FALSE(FPDFAction_GetDest(nullptr, nullptr));
276 EXPECT_FALSE(FPDFAction_GetDest(document(), nullptr));
277 EXPECT_EQ(0u, FPDFAction_GetFilePath(nullptr, nullptr, 0));
278 EXPECT_EQ(0u, FPDFAction_GetURIPath(nullptr, nullptr, nullptr, 0));
279 EXPECT_EQ(0u, FPDFAction_GetURIPath(document(), nullptr, nullptr, 0));
280}
281
283 ASSERT_TRUE(OpenDocument("launch_action.pdf"));
284
285 FPDF_PAGE page = LoadPage(0);
286 ASSERT_TRUE(page);
287
288 // The target action is nearly the size of the whole page.
289 FPDF_LINK link = FPDFLink_GetLinkAtPoint(page, 100, 100);
290 ASSERT_TRUE(link);
291
292 FPDF_ACTION action = FPDFLink_GetAction(link);
293 ASSERT_TRUE(action);
294 EXPECT_EQ(static_cast<unsigned long>(PDFACTION_LAUNCH),
296
297 const char kExpectedResult[] = "test.pdf";
298 const unsigned long kExpectedLength = sizeof(kExpectedResult);
299 unsigned long bufsize = FPDFAction_GetFilePath(action, nullptr, 0);
300 EXPECT_EQ(kExpectedLength, bufsize);
301
302 char buf[1024];
303 EXPECT_EQ(bufsize, FPDFAction_GetFilePath(action, buf, bufsize));
304 EXPECT_STREQ(kExpectedResult, buf);
305
306 // Other public methods are not appropriate for launch actions.
307 EXPECT_FALSE(FPDFAction_GetDest(document(), action));
308 EXPECT_EQ(0u, FPDFAction_GetURIPath(document(), action, buf, sizeof(buf)));
309
310 UnloadPage(page);
311}
312
314 ASSERT_TRUE(OpenDocument("uri_action.pdf"));
315
316 FPDF_PAGE page = LoadPage(0);
317 ASSERT_TRUE(page);
318
319 // The target action is nearly the size of the whole page.
320 FPDF_LINK link = FPDFLink_GetLinkAtPoint(page, 100, 100);
321 ASSERT_TRUE(link);
322
323 FPDF_ACTION action = FPDFLink_GetAction(link);
324 ASSERT_TRUE(action);
325 EXPECT_EQ(static_cast<unsigned long>(PDFACTION_URI),
327
328 const char kExpectedResult[] = "https://example.com/page.html";
329 const unsigned long kExpectedLength = sizeof(kExpectedResult);
330 unsigned long bufsize = FPDFAction_GetURIPath(document(), action, nullptr, 0);
331 ASSERT_EQ(kExpectedLength, bufsize);
332
333 char buf[1024];
334 EXPECT_EQ(bufsize, FPDFAction_GetURIPath(document(), action, buf, bufsize));
335 EXPECT_STREQ(kExpectedResult, buf);
336
337 // Other public methods are not appropriate for URI actions
338 EXPECT_FALSE(FPDFAction_GetDest(document(), action));
339 EXPECT_EQ(0u, FPDFAction_GetFilePath(action, buf, sizeof(buf)));
340
341 UnloadPage(page);
342}
343
345 ASSERT_TRUE(OpenDocument("uri_action_nonascii.pdf"));
346
347 FPDF_PAGE page = LoadPage(0);
348 ASSERT_TRUE(page);
349
350 // The target action is nearly the size of the whole page.
351 FPDF_LINK link = FPDFLink_GetLinkAtPoint(page, 100, 100);
352 ASSERT_TRUE(link);
353
354 FPDF_ACTION action = FPDFLink_GetAction(link);
355 ASSERT_TRUE(action);
356 EXPECT_EQ(static_cast<unsigned long>(PDFACTION_URI),
358
359 // FPDFAction_GetURIPath() may return data in any encoding, or even with bad
360 // encoding.
361 const char kExpectedResult[] =
362 "https://example.com/\xA5octal\xC7"
363 "chars";
364 const unsigned long kExpectedLength = sizeof(kExpectedResult);
365 unsigned long bufsize = FPDFAction_GetURIPath(document(), action, nullptr, 0);
366 ASSERT_EQ(kExpectedLength, bufsize);
367
368 char buf[1024];
369 EXPECT_EQ(bufsize, FPDFAction_GetURIPath(document(), action, buf, bufsize));
370 EXPECT_STREQ(kExpectedResult, buf);
371
372 UnloadPage(page);
373}
374
376 ASSERT_TRUE(OpenDocument("annots.pdf"));
377 FPDF_PAGE page = LoadPage(0);
378 ASSERT_TRUE(page);
379 {
380 FPDF_LINK first_link = FPDFLink_GetLinkAtPoint(page, 69.00, 653.00);
381 ScopedFPDFAnnotation first_annot(FPDFLink_GetAnnot(page, first_link));
382 EXPECT_EQ(0, FPDFPage_GetAnnotIndex(page, first_annot.get()));
383
384 FPDF_LINK second_link = FPDFLink_GetLinkAtPoint(page, 80.00, 633.00);
385 ScopedFPDFAnnotation second_annot(FPDFLink_GetAnnot(page, second_link));
386 EXPECT_EQ(1, FPDFPage_GetAnnotIndex(page, second_annot.get()));
387
388 // Also test invalid arguments.
389 EXPECT_FALSE(FPDFLink_GetAnnot(nullptr, nullptr));
390 EXPECT_FALSE(FPDFLink_GetAnnot(page, nullptr));
391 EXPECT_FALSE(FPDFLink_GetAnnot(nullptr, second_link));
392 }
393
394 UnloadPage(page);
395}
396
398 ASSERT_TRUE(OpenDocument("goto_action.pdf"));
399
400 FPDF_PAGE page = LoadPage(0);
401 ASSERT_TRUE(page);
402
403 // The target action is nearly the size of the whole page.
404 FPDF_LINK link = FPDFLink_GetLinkAtPoint(page, 100, 100);
405 ASSERT_TRUE(link);
406
407 FPDF_ACTION action = FPDFLink_GetAction(link);
408 ASSERT_TRUE(action);
409 EXPECT_EQ(static_cast<unsigned long>(PDFACTION_GOTO),
411
412 EXPECT_TRUE(FPDFAction_GetDest(document(), action));
413
414 // Other public methods are not appropriate for GoTo actions.
415 char buf[1024];
416 EXPECT_EQ(0u, FPDFAction_GetFilePath(action, buf, sizeof(buf)));
417 EXPECT_EQ(0u, FPDFAction_GetURIPath(document(), action, buf, sizeof(buf)));
418
419 UnloadPage(page);
420}
421
423 ASSERT_TRUE(OpenDocument("gotoe_action.pdf"));
424
425 FPDF_PAGE page = LoadPage(0);
426 ASSERT_TRUE(page);
427
428 // The target action is nearly the size of the whole page.
429 FPDF_LINK link = FPDFLink_GetLinkAtPoint(page, 100, 100);
430 ASSERT_TRUE(link);
431
432 FPDF_ACTION action = FPDFLink_GetAction(link);
433 ASSERT_TRUE(action);
434 EXPECT_EQ(static_cast<unsigned long>(PDFACTION_EMBEDDEDGOTO),
436
437 FPDF_DEST dest = FPDFAction_GetDest(document(), action);
438 EXPECT_TRUE(dest);
439
440 unsigned long num_params = 42;
441 FS_FLOAT params[4];
442 std::fill_n(params, 4, 42.4242f);
443 EXPECT_EQ(static_cast<unsigned long>(PDFDEST_VIEW_FIT),
444 FPDFDest_GetView(dest, &num_params, params));
445 EXPECT_EQ(0u, num_params);
446 EXPECT_FLOAT_EQ(42.4242f, params[0]);
447
448 const char kExpectedResult[] = "ExampleFile.pdf";
449 const unsigned long kExpectedLength = sizeof(kExpectedResult);
450 char buf[1024];
451 unsigned long bufsize = FPDFAction_GetFilePath(action, nullptr, 0);
452 EXPECT_EQ(kExpectedLength, bufsize);
453 EXPECT_EQ(kExpectedLength, FPDFAction_GetFilePath(action, buf, bufsize));
454 EXPECT_STREQ(kExpectedResult, buf);
455
456 UnloadPage(page);
457}
458
460 ASSERT_TRUE(OpenDocument("nonesuch_action.pdf"));
461
462 FPDF_PAGE page = LoadPage(0);
463 ASSERT_TRUE(page);
464
465 // The target action is nearly the size of the whole page.
466 FPDF_LINK link = FPDFLink_GetLinkAtPoint(page, 100, 100);
467 ASSERT_TRUE(link);
468
469 FPDF_ACTION action = FPDFLink_GetAction(link);
470 ASSERT_TRUE(action);
471 EXPECT_EQ(static_cast<unsigned long>(PDFACTION_UNSUPPORTED),
473
474 // No public methods are appropriate for unsupported actions.
475 char buf[1024];
476 EXPECT_FALSE(FPDFAction_GetDest(document(), action));
477 EXPECT_EQ(0u, FPDFAction_GetFilePath(action, buf, sizeof(buf)));
478 EXPECT_EQ(0u, FPDFAction_GetURIPath(document(), action, buf, sizeof(buf)));
479
480 UnloadPage(page);
481}
482
484 unsigned short buf[128];
485
486 // Open a file with no bookmarks.
487 ASSERT_TRUE(OpenDocument("named_dests.pdf"));
488
489 // NULL argument cases.
490 EXPECT_EQ(0u, FPDFBookmark_GetTitle(nullptr, buf, sizeof(buf)));
491 EXPECT_FALSE(FPDFBookmark_GetFirstChild(nullptr, nullptr));
492 EXPECT_FALSE(FPDFBookmark_GetFirstChild(document(), nullptr));
493 EXPECT_FALSE(FPDFBookmark_GetNextSibling(nullptr, nullptr));
494 EXPECT_FALSE(FPDFBookmark_GetNextSibling(document(), nullptr));
495 EXPECT_FALSE(FPDFBookmark_Find(nullptr, nullptr));
496 EXPECT_FALSE(FPDFBookmark_Find(document(), nullptr));
497 EXPECT_FALSE(FPDFBookmark_GetDest(nullptr, nullptr));
498 EXPECT_FALSE(FPDFBookmark_GetDest(document(), nullptr));
499 EXPECT_FALSE(FPDFBookmark_GetAction(nullptr));
500}
501
503 unsigned short buf[128];
504
505 // Open a file with many bookmarks.
506 ASSERT_TRUE(OpenDocument("bookmarks.pdf"));
507
508 FPDF_BOOKMARK child = FPDFBookmark_GetFirstChild(document(), nullptr);
509 EXPECT_TRUE(child);
510 EXPECT_EQ(34u, FPDFBookmark_GetTitle(child, buf, sizeof(buf)));
511 EXPECT_EQ(L"A Good Beginning", GetPlatformWString(buf));
512 EXPECT_EQ(0, FPDFBookmark_GetCount(child));
513 EXPECT_EQ(0, FPDFBookmark_GetCount(nullptr));
514
515 EXPECT_FALSE(FPDFBookmark_GetDest(document(), child));
516 EXPECT_FALSE(FPDFBookmark_GetAction(child));
517
518 FPDF_BOOKMARK grand_child = FPDFBookmark_GetFirstChild(document(), child);
519 EXPECT_FALSE(grand_child);
520
521 FPDF_BOOKMARK sibling = FPDFBookmark_GetNextSibling(document(), child);
522 EXPECT_TRUE(sibling);
523 EXPECT_EQ(24u, FPDFBookmark_GetTitle(sibling, buf, sizeof(buf)));
524 EXPECT_EQ(L"Open Middle", GetPlatformWString(buf));
525 EXPECT_TRUE(FPDFBookmark_GetAction(sibling));
526 EXPECT_EQ(1, FPDFBookmark_GetCount(sibling));
527
528 FPDF_BOOKMARK sibling2 = FPDFBookmark_GetNextSibling(document(), sibling);
529 EXPECT_TRUE(sibling2);
530 EXPECT_EQ(42u, FPDFBookmark_GetTitle(sibling2, buf, sizeof(buf)));
531 EXPECT_EQ(L"A Good Closed Ending", GetPlatformWString(buf));
532 EXPECT_EQ(-2, FPDFBookmark_GetCount(sibling2));
533
534 EXPECT_FALSE(FPDFBookmark_GetNextSibling(document(), sibling2));
535
536 grand_child = FPDFBookmark_GetFirstChild(document(), sibling);
537 EXPECT_TRUE(grand_child);
538 EXPECT_EQ(46u, FPDFBookmark_GetTitle(grand_child, buf, sizeof(buf)));
539 EXPECT_EQ(L"Open Middle Descendant", GetPlatformWString(buf));
540 EXPECT_EQ(0, FPDFBookmark_GetCount(grand_child));
541 EXPECT_TRUE(FPDFBookmark_GetDest(document(), grand_child));
542
543 EXPECT_FALSE(FPDFBookmark_GetNextSibling(document(), grand_child));
544}
545
547 unsigned short buf[128];
548
549 // Open a file with many bookmarks.
550 ASSERT_TRUE(OpenDocument("bookmarks.pdf"));
551
552 // Find the first one, based on its known title.
553 ScopedFPDFWideString title = GetFPDFWideString(L"A Good Beginning");
554 FPDF_BOOKMARK child = FPDFBookmark_Find(document(), title.get());
555 EXPECT_TRUE(child);
556
557 // Check that the string matches.
558 EXPECT_EQ(34u, FPDFBookmark_GetTitle(child, buf, sizeof(buf)));
559 EXPECT_EQ(L"A Good Beginning", GetPlatformWString(buf));
560
561 // Check that it is them same as the one returned by GetFirstChild.
562 EXPECT_EQ(child, FPDFBookmark_GetFirstChild(document(), nullptr));
563
564 // Try to find one using a non-existent title.
565 ScopedFPDFWideString bad_title = GetFPDFWideString(L"A BAD Beginning");
566 EXPECT_FALSE(FPDFBookmark_Find(document(), bad_title.get()));
567}
568
569// Check circular bookmarks will not cause infinite loop.
571 // Open a file with circular bookmarks.
572 ASSERT_TRUE(OpenDocument("bookmarks_circular.pdf"));
573
574 // Try to find a title.
575 ScopedFPDFWideString title = GetFPDFWideString(L"anything");
576 EXPECT_FALSE(FPDFBookmark_Find(document(), title.get()));
577}
578
580 ASSERT_TRUE(OpenDocument("hello_world.pdf"));
581 EXPECT_EQ(1, FPDF_GetPageCount(document()));
582
583 FPDFPage_Delete(nullptr, 0);
584 EXPECT_EQ(1, FPDF_GetPageCount(document()));
585
586 FPDFPage_Delete(document(), -1);
587 EXPECT_EQ(1, FPDF_GetPageCount(document()));
588 FPDFPage_Delete(document(), 1);
589 EXPECT_EQ(1, FPDF_GetPageCount(document()));
590
591 FPDFPage_Delete(document(), 0);
592 EXPECT_EQ(0, FPDF_GetPageCount(document()));
593}
594
596 struct PageData {
597 int width;
598 int height;
599 const char* checksum;
600 };
601 const PageData expected_page_data[5] = {
602 {200, 250,
603 []() {
604 return CFX_DefaultRenderDevice::UseSkiaRenderer()
605 ? "4b6590a267eae90b8be1607e808fb57f"
606 : "1e5d1cf19ffbb9cf9dbf099483cea327";
607 }()},
608 {250, 200,
609 []() {
610 return CFX_DefaultRenderDevice::UseSkiaRenderer()
611 ? "e8edd3655f6629ff489bd8c3bb110c82"
612 : "65c80685916aa36e767dd2270ba4d72b";
613 }()},
614 {200, 250,
615 []() {
616 return CFX_DefaultRenderDevice::UseSkiaRenderer()
617 ? "a2bde6b68d7981e665ab25bc633746aa"
618 : "a53b21c68edf43c1cddb5c06e361bb45";
619 }()},
620 {200, 250,
621 []() {
622 return CFX_DefaultRenderDevice::UseSkiaRenderer()
623 ? "a8c5b3e626f665eddf593c6d4c32ae9e"
624 : "dcd768be15efb9c6e5093cf74508752c";
625 }()},
626 {200, 250, []() {
627 return CFX_DefaultRenderDevice::UseSkiaRenderer()
628 ? "72eb157853ae2d19b70ea62e3f5ac202"
629 : "7a3f8f79ebcb350854c0d69607729ec5";
630 }()}};
631
632 // Render the original document. (page indices 0-4)
633 ASSERT_TRUE(OpenDocument("rectangles_multi_pages.pdf"));
634 EXPECT_EQ(5, FPDF_GetPageCount(document()));
635 for (int i = 0; i < 5; ++i) {
636 FPDF_PAGE page = LoadPage(i);
637 ASSERT_TRUE(page);
638 ScopedFPDFBitmap bitmap = RenderLoadedPage(page);
639 const PageData& expected = expected_page_data[i];
640 CompareBitmap(bitmap.get(), expected.width, expected.height,
641 expected.checksum);
642 UnloadPage(page);
643 }
644
645 // Delete the first page and render again. (original page indices 1-4)
646 FPDFPage_Delete(document(), 0);
647 EXPECT_EQ(4, FPDF_GetPageCount(document()));
648 for (int i = 0; i < 4; ++i) {
649 FPDF_PAGE page = LoadPage(i);
650 ASSERT_TRUE(page);
651 ScopedFPDFBitmap bitmap = RenderLoadedPage(page);
652 const PageData& expected = expected_page_data[i + 1];
653 CompareBitmap(bitmap.get(), expected.width, expected.height,
654 expected.checksum);
655 UnloadPage(page);
656 }
657
658 // Delete the last page and render again. (original page indices 1-3)
659 FPDFPage_Delete(document(), 3);
660 EXPECT_EQ(3, FPDF_GetPageCount(document()));
661 for (int i = 0; i < 3; ++i) {
662 FPDF_PAGE page = LoadPage(i);
663 ASSERT_TRUE(page);
664 ScopedFPDFBitmap bitmap = RenderLoadedPage(page);
665 const PageData& expected = expected_page_data[i + 1];
666 CompareBitmap(bitmap.get(), expected.width, expected.height,
667 expected.checksum);
668 UnloadPage(page);
669 }
670
671 // Delete the middle page and render again. (original page indices 1, 3)
672 FPDFPage_Delete(document(), 1);
673 EXPECT_EQ(2, FPDF_GetPageCount(document()));
674 for (int i = 0; i < 2; ++i) {
675 FPDF_PAGE page = LoadPage(i);
676 ASSERT_TRUE(page);
677 ScopedFPDFBitmap bitmap = RenderLoadedPage(page);
678 int adjusted_index = i == 0 ? 1 : 3;
679 const PageData& expected = expected_page_data[adjusted_index];
680 CompareBitmap(bitmap.get(), expected.width, expected.height,
681 expected.checksum);
682 UnloadPage(page);
683 }
684}
685
687 ASSERT_TRUE(OpenDocument("split_streams.pdf"));
688 constexpr size_t kMd5Length = 17;
689 char buf[kMd5Length];
690 EXPECT_EQ(0u,
691 FPDF_GetFileIdentifier(document(), static_cast<FPDF_FILEIDTYPE>(-1),
692 buf, sizeof(buf)));
693 EXPECT_EQ(0u,
694 FPDF_GetFileIdentifier(document(), static_cast<FPDF_FILEIDTYPE>(2),
695 buf, sizeof(buf)));
696 EXPECT_EQ(0u, FPDF_GetFileIdentifier(nullptr, FILEIDTYPE_PERMANENT, buf,
697 sizeof(buf)));
698 EXPECT_EQ(kMd5Length, FPDF_GetFileIdentifier(document(), FILEIDTYPE_PERMANENT,
699 nullptr, 0));
700
701 constexpr char kExpectedPermanent[] =
702 "\xF3\x41\xAE\x65\x4A\x77\xAC\xD5\x06\x5A\x76\x45\xE5\x96\xE6\xE6";
703 ASSERT_EQ(kMd5Length, FPDF_GetFileIdentifier(document(), FILEIDTYPE_PERMANENT,
704 buf, sizeof(buf)));
705 EXPECT_EQ(kExpectedPermanent, ByteString(buf));
706
707 constexpr char kExpectedChanging[] =
708 "\xBC\x37\x29\x8A\x3F\x87\xF4\x79\x22\x9B\xCE\x99\x7C\xA7\x91\xF7";
709 ASSERT_EQ(kMd5Length, FPDF_GetFileIdentifier(document(), FILEIDTYPE_CHANGING,
710 buf, sizeof(buf)));
711 EXPECT_EQ(kExpectedChanging, ByteString(buf));
712}
713
715 ASSERT_TRUE(OpenDocument("non_hex_file_id.pdf"));
716 char buf[18];
717
718 constexpr char kPermanentNonHex[] = "permanent non-hex";
719 ASSERT_EQ(18u, FPDF_GetFileIdentifier(document(), FILEIDTYPE_PERMANENT, buf,
720 sizeof(buf)));
721 EXPECT_EQ(kPermanentNonHex, ByteString(buf));
722
723 constexpr char kChangingNonHex[] = "changing non-hex";
724 ASSERT_EQ(17u, FPDF_GetFileIdentifier(document(), FILEIDTYPE_CHANGING, buf,
725 sizeof(buf)));
726 EXPECT_EQ(kChangingNonHex, ByteString(buf));
727}
728
730 ASSERT_TRUE(OpenDocument("hello_world.pdf"));
731 EXPECT_EQ(
732 0u, FPDF_GetFileIdentifier(document(), FILEIDTYPE_PERMANENT, nullptr, 0));
733 EXPECT_EQ(
734 0u, FPDF_GetFileIdentifier(document(), FILEIDTYPE_CHANGING, nullptr, 0));
735}
736
738 ASSERT_TRUE(OpenDocument("bug_601362.pdf"));
739
740 // Invalid document / tag results in 0.
741 unsigned short buf[128];
742 EXPECT_EQ(0u, FPDF_GetMetaText(document(), nullptr, buf, sizeof(buf)));
743 EXPECT_EQ(0u, FPDF_GetMetaText(nullptr, "", buf, sizeof(buf)));
744
745 // Tags that do not eixst results in an empty wide string.
746 EXPECT_EQ(2u, FPDF_GetMetaText(document(), "", buf, sizeof(buf)));
747 EXPECT_EQ(2u, FPDF_GetMetaText(document(), "foo", buf, sizeof(buf)));
748 ASSERT_EQ(2u, FPDF_GetMetaText(document(), "Title", buf, sizeof(buf)));
749 ASSERT_EQ(2u, FPDF_GetMetaText(document(), "Author", buf, sizeof(buf)));
750 ASSERT_EQ(2u, FPDF_GetMetaText(document(), "Subject", buf, sizeof(buf)));
751 ASSERT_EQ(2u, FPDF_GetMetaText(document(), "Keywords", buf, sizeof(buf)));
752 ASSERT_EQ(2u, FPDF_GetMetaText(document(), "Producer", buf, sizeof(buf)));
753
754 ASSERT_EQ(30u, FPDF_GetMetaText(document(), "Creator", buf, sizeof(buf)));
755 EXPECT_EQ(L"Microsoft Word", GetPlatformWString(buf));
756
757 ASSERT_EQ(48u,
758 FPDF_GetMetaText(document(), "CreationDate", buf, sizeof(buf)));
759 EXPECT_EQ(L"D:20160411190039+00'00'", GetPlatformWString(buf));
760
761 ASSERT_EQ(48u, FPDF_GetMetaText(document(), "ModDate", buf, sizeof(buf)));
762 EXPECT_EQ(L"D:20160411190039+00'00'", GetPlatformWString(buf));
763}
764
766 ASSERT_TRUE(OpenDocument("utf-8.pdf"));
767
768 unsigned short buf[128];
769
770 ASSERT_EQ(34u, FPDF_GetMetaText(document(), "Producer", buf, sizeof(buf)));
771 EXPECT_EQ(L"Manüally Created", GetPlatformWString(buf));
772
773 FPDF_BOOKMARK child = FPDFBookmark_GetFirstChild(document(), nullptr);
774 EXPECT_TRUE(child);
775 EXPECT_EQ(16u, FPDFBookmark_GetTitle(child, buf, sizeof(buf)));
776 EXPECT_EQ(L"Titlè 1", GetPlatformWString(buf));
777}
778
780 ASSERT_TRUE(OpenDocument("bug_182.pdf"));
781
782 unsigned short buf[128];
783
784 ASSERT_EQ(48u, FPDF_GetMetaText(document(), "Title", buf, sizeof(buf)));
785 EXPECT_EQ(L"Super Visual Formade 印刷", GetPlatformWString(buf));
786}
787
789 ASSERT_TRUE(OpenDocument("annotation_highlight_square_with_ap.pdf"));
790
791 // The PDF has been edited. It has two %%EOF markers, and 2 objects numbered
792 // (1 0). Both objects are /Info dictionaries, but contain different data.
793 // Make sure ModDate is the date of the last modification.
794 unsigned short buf[128];
795 ASSERT_EQ(48u, FPDF_GetMetaText(document(), "ModDate", buf, sizeof(buf)));
796 EXPECT_EQ(L"D:20170612232940-04'00'", GetPlatformWString(buf));
797}
798
800 ASSERT_TRUE(OpenDocument("embedded_attachments.pdf"));
801
802 // Make sure this is the date from the PDF itself and not the attached PDF.
803 unsigned short buf[128];
804 ASSERT_EQ(48u, FPDF_GetMetaText(document(), "ModDate", buf, sizeof(buf)));
805 EXPECT_EQ(L"D:20170712214448-07'00'", GetPlatformWString(buf));
806}
807
809 ScopedFPDFDocument empty_doc(FPDF_CreateNewDocument());
810 unsigned short buf[128];
811 EXPECT_EQ(2u, FPDF_GetMetaText(empty_doc.get(), "Title", buf, sizeof(buf)));
812}
813
815 ASSERT_TRUE(OpenDocument("get_page_aaction.pdf"));
816 FPDF_PAGE page = LoadPage(0);
817 EXPECT_TRUE(page);
818
821 EXPECT_FALSE(FPDF_GetPageAAction(page, -1));
822 EXPECT_FALSE(FPDF_GetPageAAction(page, 999));
823
824 FPDF_ACTION action = FPDF_GetPageAAction(page, FPDFPAGE_AACTION_OPEN);
825 EXPECT_EQ(static_cast<unsigned long>(PDFACTION_EMBEDDEDGOTO),
827
828 const char kExpectedResult[] = "\\\\127.0.0.1\\c$\\Program Files\\test.exe";
829 const unsigned long kExpectedLength = sizeof(kExpectedResult);
830 char buf[1024];
831
832 unsigned long bufsize = FPDFAction_GetFilePath(action, nullptr, 0);
833 EXPECT_EQ(kExpectedLength, bufsize);
834 EXPECT_EQ(kExpectedLength, FPDFAction_GetFilePath(action, buf, bufsize));
835 EXPECT_STREQ(kExpectedResult, buf);
836
837 UnloadPage(page);
838
839 page = LoadPage(1);
840 EXPECT_TRUE(page);
841 EXPECT_FALSE(FPDF_GetPageAAction(page, -1));
842
843 UnloadPage(page);
844}
845
847 ASSERT_TRUE(OpenDocument("about_blank.pdf"));
848 EXPECT_EQ(1, FPDF_GetPageCount(document()));
849
850 ASSERT_EQ(0u, FPDF_GetPageLabel(document(), 0, nullptr, 0));
851}
852
854 ASSERT_TRUE(OpenDocument("page_labels.pdf"));
855 EXPECT_EQ(7, FPDF_GetPageCount(document()));
856
857 // We do not request labels, when use FPDFAvail_IsXXXAvail.
858 // Flush all data, to allow read labels.
859 SetWholeFileAvailable();
860
861 unsigned short buf[128];
862 EXPECT_EQ(0u, FPDF_GetPageLabel(document(), -2, buf, sizeof(buf)));
863 EXPECT_EQ(0u, FPDF_GetPageLabel(document(), -1, buf, sizeof(buf)));
864
865 ASSERT_EQ(4u, FPDF_GetPageLabel(document(), 0, buf, sizeof(buf)));
866 EXPECT_EQ(L"i", GetPlatformWString(buf));
867
868 ASSERT_EQ(6u, FPDF_GetPageLabel(document(), 1, buf, sizeof(buf)));
869 EXPECT_EQ(L"ii", GetPlatformWString(buf));
870
871 ASSERT_EQ(4u, FPDF_GetPageLabel(document(), 2, buf, sizeof(buf)));
872 EXPECT_EQ(L"1", GetPlatformWString(buf));
873
874 ASSERT_EQ(4u, FPDF_GetPageLabel(document(), 3, buf, sizeof(buf)));
875 EXPECT_EQ(L"2", GetPlatformWString(buf));
876
877 ASSERT_EQ(8u, FPDF_GetPageLabel(document(), 4, buf, sizeof(buf)));
878 EXPECT_EQ(L"zzA", GetPlatformWString(buf));
879
880 ASSERT_EQ(8u, FPDF_GetPageLabel(document(), 5, buf, sizeof(buf)));
881 EXPECT_EQ(L"zzB", GetPlatformWString(buf));
882
883 ASSERT_EQ(2u, FPDF_GetPageLabel(document(), 6, buf, sizeof(buf)));
884 EXPECT_EQ(L"", GetPlatformWString(buf));
885
886 ASSERT_EQ(0u, FPDF_GetPageLabel(document(), 7, buf, sizeof(buf)));
887 ASSERT_EQ(0u, FPDF_GetPageLabel(document(), 8, buf, sizeof(buf)));
888}
889
890#ifdef PDF_ENABLE_XFA
891TEST_F(FPDFDocEmbedderTest, GetXFALinks) {
892 ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
893
894 ScopedFPDFPage page(FPDF_LoadPage(document(), 0));
895 ASSERT_TRUE(page);
896
897 FPDFLink_GetLinkAtPoint(page.get(), 150, 360);
898 FPDFLink_GetLinkAtPoint(page.get(), 150, 420);
899
900 // Test passes if it doesn't crash. See https://crbug.com/840922
901}
902#endif // PDF_ENABLE_XFA
uint32_t GetParsedPageCountForTesting()
ByteString(const char *ptr)
FPDF_EXPORT FPDF_ACTION FPDF_CALLCONV FPDFLink_GetAction(FPDF_LINK link)
Definition fpdf_doc.cpp:355
FPDF_EXPORT FPDF_DEST FPDF_CALLCONV FPDFLink_GetDest(FPDF_DOCUMENT document, FPDF_LINK link)
Definition fpdf_doc.cpp:337
FPDF_EXPORT FPDF_ACTION FPDF_CALLCONV FPDFBookmark_GetAction(FPDF_BOOKMARK bookmark)
Definition fpdf_doc.cpp:164
FPDF_EXPORT FPDF_DEST FPDF_CALLCONV FPDFAction_GetDest(FPDF_DOCUMENT document, FPDF_ACTION action)
Definition fpdf_doc.cpp:194
FPDF_EXPORT FPDF_BOOKMARK FPDF_CALLCONV FPDFBookmark_Find(FPDF_DOCUMENT document, FPDF_WIDESTRING title)
Definition fpdf_doc.cpp:126
FPDF_EXPORT unsigned long FPDF_CALLCONV FPDFDest_GetView(FPDF_DEST dest, unsigned long *pNumParams, FS_FLOAT *pParams)
Definition fpdf_doc.cpp:259
FPDF_EXPORT unsigned long FPDF_CALLCONV FPDFBookmark_GetTitle(FPDF_BOOKMARK bookmark, void *buffer, unsigned long buflen)
Definition fpdf_doc.cpp:106
FPDF_EXPORT FPDF_ACTION FPDF_CALLCONV FPDF_GetPageAAction(FPDF_PAGE page, int aa_type)
Definition fpdf_doc.cpp:438
FPDF_EXPORT FPDF_BOOKMARK FPDF_CALLCONV FPDFBookmark_GetNextSibling(FPDF_DOCUMENT document, FPDF_BOOKMARK bookmark)
Definition fpdf_doc.cpp:90
FPDF_EXPORT int FPDF_CALLCONV FPDFLink_GetLinkZOrderAtPoint(FPDF_PAGE page, double x, double y)
Definition fpdf_doc.cpp:319
FPDF_EXPORT FPDF_DEST FPDF_CALLCONV FPDFBookmark_GetDest(FPDF_DOCUMENT document, FPDF_BOOKMARK bookmark)
Definition fpdf_doc.cpp:142
FPDF_EXPORT unsigned long FPDF_CALLCONV FPDFAction_GetFilePath(FPDF_ACTION action, void *buffer, unsigned long buflen)
Definition fpdf_doc.cpp:210
FPDF_EXPORT int FPDF_CALLCONV FPDFBookmark_GetCount(FPDF_BOOKMARK bookmark)
Definition fpdf_doc.cpp:117
FPDF_EXPORT FPDF_ANNOTATION FPDF_CALLCONV FPDFLink_GetAnnot(FPDF_PAGE page, FPDF_LINK link_annot)
Definition fpdf_doc.cpp:389
FPDF_EXPORT unsigned long FPDF_CALLCONV FPDFAction_GetType(FPDF_ACTION action)
Definition fpdf_doc.cpp:173
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFDest_GetLocationInPage(FPDF_DEST dest, FPDF_BOOL *hasXVal, FPDF_BOOL *hasYVal, FPDF_BOOL *hasZoomVal, FS_FLOAT *x, FS_FLOAT *y, FS_FLOAT *zoom)
Definition fpdf_doc.cpp:276
FPDF_EXPORT unsigned long FPDF_CALLCONV FPDFAction_GetURIPath(FPDF_DOCUMENT document, FPDF_ACTION action, void *buffer, unsigned long buflen)
Definition fpdf_doc.cpp:223
FPDF_EXPORT unsigned long FPDF_CALLCONV FPDF_GetMetaText(FPDF_DOCUMENT document, FPDF_BYTESTRING tag, void *buffer, unsigned long buflen)
Definition fpdf_doc.cpp:487
FPDF_EXPORT FPDF_LINK FPDF_CALLCONV FPDFLink_GetLinkAtPoint(FPDF_PAGE page, double x, double y)
Definition fpdf_doc.cpp:301
FPDF_EXPORT FPDF_BOOKMARK FPDF_CALLCONV FPDFBookmark_GetFirstChild(FPDF_DOCUMENT document, FPDF_BOOKMARK bookmark)
Definition fpdf_doc.cpp:78
FPDF_EXPORT int FPDF_CALLCONV FPDFDest_GetDestPageIndex(FPDF_DOCUMENT document, FPDF_DEST dest)
Definition fpdf_doc.cpp:245
#define PDFDEST_VIEW_UNKNOWN_MODE
Definition fpdf_doc.h:31
#define PDFDEST_VIEW_XYZ
Definition fpdf_doc.h:32
#define PDFACTION_GOTO
Definition fpdf_doc.h:20
#define PDFACTION_EMBEDDEDGOTO
Definition fpdf_doc.h:28
#define PDFACTION_UNSUPPORTED
Definition fpdf_doc.h:18
#define PDFDEST_VIEW_FIT
Definition fpdf_doc.h:33
#define PDFACTION_LAUNCH
Definition fpdf_doc.h:26
#define PDFACTION_URI
Definition fpdf_doc.h:24
TEST_F(FPDFDocEmbedderTest, MultipleSamePage)
FPDF_EXPORT void FPDF_CALLCONV FPDFPage_Delete(FPDF_DOCUMENT document, int page_index)
#define FPDFPAGE_AACTION_CLOSE
#define FPDFPAGE_AACTION_OPEN
std::wstring GetPlatformWString(FPDF_WIDESTRING wstr)