• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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