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 "core/include/fxcrt/fx_string.h"
6 #include "public/fpdf_doc.h"
7 #include "public/fpdfview.h"
8 #include "testing/embedder_test.h"
9 #include "testing/fx_string_testhelpers.h"
10 #include "testing/test_support.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12 
13 class FPDFDocEmbeddertest : public EmbedderTest {};
14 
TEST_F(FPDFDocEmbeddertest,DestGetPageIndex)15 TEST_F(FPDFDocEmbeddertest, DestGetPageIndex) {
16   EXPECT_TRUE(OpenDocument("named_dests.pdf"));
17 
18   // NULL FPDF_DEST case.
19   EXPECT_EQ(0U, FPDFDest_GetPageIndex(document(), nullptr));
20 
21   // Page number directly in item from Dests NameTree.
22   FPDF_DEST dest = FPDF_GetNamedDestByName(document(), "First");
23   EXPECT_NE(nullptr, dest);
24   EXPECT_EQ(1U, FPDFDest_GetPageIndex(document(), dest));
25 
26   // Page number via object reference in item from Dests NameTree.
27   dest = FPDF_GetNamedDestByName(document(), "Next");
28   EXPECT_NE(nullptr, dest);
29   EXPECT_EQ(1U, FPDFDest_GetPageIndex(document(), dest));
30 
31   // Page number directly in item from Dests dictionary.
32   dest = FPDF_GetNamedDestByName(document(), "FirstAlternate");
33   EXPECT_NE(nullptr, dest);
34   EXPECT_EQ(11U, FPDFDest_GetPageIndex(document(), dest));
35 
36   // Invalid object reference in item from Dests NameTree.
37   dest = FPDF_GetNamedDestByName(document(), "LastAlternate");
38   EXPECT_NE(nullptr, dest);
39   EXPECT_EQ(0U, FPDFDest_GetPageIndex(document(), dest));
40 }
41 
TEST_F(FPDFDocEmbeddertest,ActionGetFilePath)42 TEST_F(FPDFDocEmbeddertest, ActionGetFilePath) {
43   EXPECT_TRUE(OpenDocument("launch_action.pdf"));
44 
45   FPDF_PAGE page = FPDF_LoadPage(document(), 0);
46   ASSERT_TRUE(page);
47 
48   // The target action is nearly the size of the whole page.
49   FPDF_LINK link = FPDFLink_GetLinkAtPoint(page, 100, 100);
50   ASSERT_TRUE(link);
51 
52   FPDF_ACTION action = FPDFLink_GetAction(link);
53   ASSERT_TRUE(action);
54 
55   const char kExpectedResult[] = "test.pdf";
56   const unsigned long kExpectedLength = sizeof(kExpectedResult);
57   unsigned long bufsize = FPDFAction_GetFilePath(action, nullptr, 0);
58   ASSERT_EQ(kExpectedLength, bufsize);
59 
60   char buf[kExpectedLength];
61   EXPECT_EQ(bufsize, FPDFAction_GetFilePath(action, buf, bufsize));
62   EXPECT_EQ(std::string(kExpectedResult), std::string(buf));
63 
64   FPDF_ClosePage(page);
65 }
66 
TEST_F(FPDFDocEmbeddertest,NoBookmarks)67 TEST_F(FPDFDocEmbeddertest, NoBookmarks) {
68   // Open a file with no bookmarks.
69   EXPECT_TRUE(OpenDocument("named_dests.pdf"));
70 
71   // The non-existent top-level bookmark has no title.
72   unsigned short buf[128];
73   EXPECT_EQ(0, FPDFBookmark_GetTitle(nullptr, buf, sizeof(buf)));
74 
75   // The non-existent top-level bookmark has no children.
76   EXPECT_EQ(nullptr, FPDFBookmark_GetFirstChild(document(), nullptr));
77 }
78 
TEST_F(FPDFDocEmbeddertest,Bookmarks)79 TEST_F(FPDFDocEmbeddertest, Bookmarks) {
80   // Open a file with two bookmarks.
81   EXPECT_TRUE(OpenDocument("bookmarks.pdf"));
82 
83   // The existent top-level bookmark has no title.
84   unsigned short buf[128];
85   EXPECT_EQ(0, FPDFBookmark_GetTitle(nullptr, buf, sizeof(buf)));
86 
87   FPDF_BOOKMARK child = FPDFBookmark_GetFirstChild(document(), nullptr);
88   EXPECT_NE(nullptr, child);
89   EXPECT_EQ(34, FPDFBookmark_GetTitle(child, buf, sizeof(buf)));
90   EXPECT_EQ(CFX_WideString(L"A Good Beginning"),
91             CFX_WideString::FromUTF16LE(buf, 16));
92 
93   EXPECT_EQ(nullptr, FPDFBookmark_GetFirstChild(document(), child));
94 
95   FPDF_BOOKMARK sibling = FPDFBookmark_GetNextSibling(document(), child);
96   EXPECT_NE(nullptr, sibling);
97   EXPECT_EQ(28, FPDFBookmark_GetTitle(sibling, buf, sizeof(buf)));
98   EXPECT_EQ(CFX_WideString(L"A Good Ending"),
99             CFX_WideString::FromUTF16LE(buf, 13));
100 
101   EXPECT_EQ(nullptr, FPDFBookmark_GetNextSibling(document(), sibling));
102 }
103 
TEST_F(FPDFDocEmbeddertest,FindBookmarks)104 TEST_F(FPDFDocEmbeddertest, FindBookmarks) {
105   // Open a file with two bookmarks.
106   EXPECT_TRUE(OpenDocument("bookmarks.pdf"));
107 
108   // Find the first one, based on its known title.
109   std::unique_ptr<unsigned short, pdfium::FreeDeleter> title =
110       GetFPDFWideString(L"A Good Beginning");
111   FPDF_BOOKMARK child = FPDFBookmark_Find(document(), title.get());
112   EXPECT_NE(nullptr, child);
113 
114   // Check that the string matches.
115   unsigned short buf[128];
116   EXPECT_EQ(34, FPDFBookmark_GetTitle(child, buf, sizeof(buf)));
117   EXPECT_EQ(CFX_WideString(L"A Good Beginning"),
118             CFX_WideString::FromUTF16LE(buf, 16));
119 
120   // Check that it is them same as the one returned by GetFirstChild.
121   EXPECT_EQ(child, FPDFBookmark_GetFirstChild(document(), nullptr));
122 
123   // Try to find one using a non-existent title.
124   std::unique_ptr<unsigned short, pdfium::FreeDeleter> bad_title =
125       GetFPDFWideString(L"A BAD Beginning");
126   EXPECT_EQ(nullptr, FPDFBookmark_Find(document(), bad_title.get()));
127 }
128