• Home
  • 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 <string>
7 
8 #include "core/fxcrt/fx_string.h"
9 #include "public/fpdf_doc.h"
10 #include "public/fpdf_edit.h"
11 #include "public/fpdfview.h"
12 #include "testing/embedder_test.h"
13 #include "testing/fx_string_testhelpers.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15 #include "testing/test_support.h"
16 
17 class FPDFDocEmbeddertest : public EmbedderTest {};
18 
TEST_F(FPDFDocEmbeddertest,DestGetPageIndex)19 TEST_F(FPDFDocEmbeddertest, DestGetPageIndex) {
20   EXPECT_TRUE(OpenDocument("named_dests.pdf"));
21 
22   // NULL FPDF_DEST case.
23   EXPECT_EQ(0U, FPDFDest_GetPageIndex(document(), nullptr));
24 
25   // Page number directly in item from Dests NameTree.
26   FPDF_DEST dest = FPDF_GetNamedDestByName(document(), "First");
27   EXPECT_TRUE(dest);
28   EXPECT_EQ(1U, FPDFDest_GetPageIndex(document(), dest));
29 
30   // Page number via object reference in item from Dests NameTree.
31   dest = FPDF_GetNamedDestByName(document(), "Next");
32   EXPECT_TRUE(dest);
33   EXPECT_EQ(1U, FPDFDest_GetPageIndex(document(), dest));
34 
35   // Page number directly in item from Dests dictionary.
36   dest = FPDF_GetNamedDestByName(document(), "FirstAlternate");
37   EXPECT_TRUE(dest);
38   EXPECT_EQ(11U, FPDFDest_GetPageIndex(document(), dest));
39 
40   // Invalid object reference in item from Dests NameTree.
41   dest = FPDF_GetNamedDestByName(document(), "LastAlternate");
42   EXPECT_TRUE(dest);
43   EXPECT_EQ(0U, FPDFDest_GetPageIndex(document(), dest));
44 }
45 
TEST_F(FPDFDocEmbeddertest,DestGetLocationInPage)46 TEST_F(FPDFDocEmbeddertest, DestGetLocationInPage) {
47   EXPECT_TRUE(OpenDocument("named_dests.pdf"));
48 
49   // NULL FPDF_DEST case.
50   EXPECT_EQ(0U, FPDFDest_GetPageIndex(document(), nullptr));
51 
52   FPDF_DEST dest = FPDF_GetNamedDestByName(document(), "First");
53   EXPECT_TRUE(dest);
54 
55   FPDF_BOOL hasX;
56   FPDF_BOOL hasY;
57   FPDF_BOOL hasZoom;
58   FS_FLOAT x;
59   FS_FLOAT y;
60   FS_FLOAT zoom;
61   EXPECT_TRUE(
62       FPDFDest_GetLocationInPage(dest, &hasX, &hasY, &hasZoom, &x, &y, &zoom));
63   EXPECT_TRUE(hasX);
64   EXPECT_TRUE(hasY);
65   EXPECT_TRUE(hasZoom);
66   EXPECT_EQ(0, x);
67   EXPECT_EQ(0, y);
68   EXPECT_EQ(1, zoom);
69 }
70 
TEST_F(FPDFDocEmbeddertest,BUG_680376)71 TEST_F(FPDFDocEmbeddertest, BUG_680376) {
72   EXPECT_TRUE(OpenDocument("bug_680376.pdf"));
73 
74   // Page number directly in item from Dests NameTree.
75   FPDF_DEST dest = FPDF_GetNamedDestByName(document(), "First");
76   EXPECT_TRUE(dest);
77   EXPECT_EQ(static_cast<unsigned long>(-1),
78             FPDFDest_GetPageIndex(document(), dest));
79 }
80 
TEST_F(FPDFDocEmbeddertest,ActionGetFilePath)81 TEST_F(FPDFDocEmbeddertest, ActionGetFilePath) {
82   EXPECT_TRUE(OpenDocument("launch_action.pdf"));
83 
84   FPDF_PAGE page = FPDF_LoadPage(document(), 0);
85   ASSERT_TRUE(page);
86 
87   // The target action is nearly the size of the whole page.
88   FPDF_LINK link = FPDFLink_GetLinkAtPoint(page, 100, 100);
89   ASSERT_TRUE(link);
90 
91   FPDF_ACTION action = FPDFLink_GetAction(link);
92   ASSERT_TRUE(action);
93 
94   const char kExpectedResult[] = "test.pdf";
95   const unsigned long kExpectedLength = sizeof(kExpectedResult);
96   unsigned long bufsize = FPDFAction_GetFilePath(action, nullptr, 0);
97   ASSERT_EQ(kExpectedLength, bufsize);
98 
99   char buf[kExpectedLength];
100   EXPECT_EQ(bufsize, FPDFAction_GetFilePath(action, buf, bufsize));
101   EXPECT_EQ(std::string(kExpectedResult), std::string(buf));
102 
103   FPDF_ClosePage(page);
104 }
105 
TEST_F(FPDFDocEmbeddertest,NoBookmarks)106 TEST_F(FPDFDocEmbeddertest, NoBookmarks) {
107   // Open a file with no bookmarks.
108   EXPECT_TRUE(OpenDocument("named_dests.pdf"));
109 
110   // The non-existent top-level bookmark has no title.
111   unsigned short buf[128];
112   EXPECT_EQ(0u, FPDFBookmark_GetTitle(nullptr, buf, sizeof(buf)));
113 
114   // The non-existent top-level bookmark has no children.
115   EXPECT_EQ(nullptr, FPDFBookmark_GetFirstChild(document(), nullptr));
116 }
117 
TEST_F(FPDFDocEmbeddertest,Bookmarks)118 TEST_F(FPDFDocEmbeddertest, Bookmarks) {
119   // Open a file with two bookmarks.
120   EXPECT_TRUE(OpenDocument("bookmarks.pdf"));
121 
122   // The existent top-level bookmark has no title.
123   unsigned short buf[128];
124   EXPECT_EQ(0u, FPDFBookmark_GetTitle(nullptr, buf, sizeof(buf)));
125 
126   FPDF_BOOKMARK child = FPDFBookmark_GetFirstChild(document(), nullptr);
127   EXPECT_TRUE(child);
128   EXPECT_EQ(34u, FPDFBookmark_GetTitle(child, buf, sizeof(buf)));
129   EXPECT_EQ(CFX_WideString(L"A Good Beginning"),
130             CFX_WideString::FromUTF16LE(buf, 16));
131 
132   EXPECT_EQ(nullptr, FPDFBookmark_GetFirstChild(document(), child));
133 
134   FPDF_BOOKMARK sibling = FPDFBookmark_GetNextSibling(document(), child);
135   EXPECT_TRUE(sibling);
136   EXPECT_EQ(28u, FPDFBookmark_GetTitle(sibling, buf, sizeof(buf)));
137   EXPECT_EQ(CFX_WideString(L"A Good Ending"),
138             CFX_WideString::FromUTF16LE(buf, 13));
139 
140   EXPECT_EQ(nullptr, FPDFBookmark_GetNextSibling(document(), sibling));
141 }
142 
TEST_F(FPDFDocEmbeddertest,FindBookmarks)143 TEST_F(FPDFDocEmbeddertest, FindBookmarks) {
144   // Open a file with two bookmarks.
145   EXPECT_TRUE(OpenDocument("bookmarks.pdf"));
146 
147   // Find the first one, based on its known title.
148   std::unique_ptr<unsigned short, pdfium::FreeDeleter> title =
149       GetFPDFWideString(L"A Good Beginning");
150   FPDF_BOOKMARK child = FPDFBookmark_Find(document(), title.get());
151   EXPECT_TRUE(child);
152 
153   // Check that the string matches.
154   unsigned short buf[128];
155   EXPECT_EQ(34u, FPDFBookmark_GetTitle(child, buf, sizeof(buf)));
156   EXPECT_EQ(CFX_WideString(L"A Good Beginning"),
157             CFX_WideString::FromUTF16LE(buf, 16));
158 
159   // Check that it is them same as the one returned by GetFirstChild.
160   EXPECT_EQ(child, FPDFBookmark_GetFirstChild(document(), nullptr));
161 
162   // Try to find one using a non-existent title.
163   std::unique_ptr<unsigned short, pdfium::FreeDeleter> bad_title =
164       GetFPDFWideString(L"A BAD Beginning");
165   EXPECT_EQ(nullptr, FPDFBookmark_Find(document(), bad_title.get()));
166 }
167 
168 // Check circular bookmarks will not cause infinite loop.
TEST_F(FPDFDocEmbeddertest,FindBookmarks_bug420)169 TEST_F(FPDFDocEmbeddertest, FindBookmarks_bug420) {
170   // Open a file with circular bookmarks.
171   EXPECT_TRUE(OpenDocument("bookmarks_circular.pdf"));
172 
173   // Try to find a title.
174   std::unique_ptr<unsigned short, pdfium::FreeDeleter> title =
175       GetFPDFWideString(L"anything");
176   EXPECT_EQ(nullptr, FPDFBookmark_Find(document(), title.get()));
177 }
178 
TEST_F(FPDFDocEmbeddertest,DeletePage)179 TEST_F(FPDFDocEmbeddertest, DeletePage) {
180   EXPECT_TRUE(OpenDocument("hello_world.pdf"));
181   EXPECT_EQ(1, FPDF_GetPageCount(document()));
182   FPDFPage_Delete(document(), 0);
183   EXPECT_EQ(0, FPDF_GetPageCount(document()));
184 }
185 
TEST_F(FPDFDocEmbeddertest,NoPageLabels)186 TEST_F(FPDFDocEmbeddertest, NoPageLabels) {
187   EXPECT_TRUE(OpenDocument("about_blank.pdf"));
188   EXPECT_EQ(1, FPDF_GetPageCount(document()));
189 
190   ASSERT_EQ(0u, FPDF_GetPageLabel(document(), 0, nullptr, 0));
191 }
192 
TEST_F(FPDFDocEmbeddertest,GetPageLabels)193 TEST_F(FPDFDocEmbeddertest, GetPageLabels) {
194   EXPECT_TRUE(OpenDocument("page_labels.pdf"));
195   EXPECT_EQ(7, FPDF_GetPageCount(document()));
196 
197   unsigned short buf[128];
198   EXPECT_EQ(0u, FPDF_GetPageLabel(document(), -2, buf, sizeof(buf)));
199   EXPECT_EQ(0u, FPDF_GetPageLabel(document(), -1, buf, sizeof(buf)));
200 
201   const FX_WCHAR kExpectedPageLabel0[] = L"i";
202   ASSERT_EQ(4u, FPDF_GetPageLabel(document(), 0, buf, sizeof(buf)));
203   EXPECT_EQ(CFX_WideString(kExpectedPageLabel0),
204             CFX_WideString::FromUTF16LE(buf, FXSYS_len(kExpectedPageLabel0)));
205 
206   const FX_WCHAR kExpectedPageLabel1[] = L"ii";
207   ASSERT_EQ(6u, FPDF_GetPageLabel(document(), 1, buf, sizeof(buf)));
208   EXPECT_EQ(CFX_WideString(kExpectedPageLabel1),
209             CFX_WideString::FromUTF16LE(buf, FXSYS_len(kExpectedPageLabel1)));
210 
211   const FX_WCHAR kExpectedPageLabel2[] = L"1";
212   ASSERT_EQ(4u, FPDF_GetPageLabel(document(), 2, buf, sizeof(buf)));
213   EXPECT_EQ(CFX_WideString(kExpectedPageLabel2),
214             CFX_WideString::FromUTF16LE(buf, FXSYS_len(kExpectedPageLabel2)));
215 
216   const FX_WCHAR kExpectedPageLabel3[] = L"2";
217   ASSERT_EQ(4u, FPDF_GetPageLabel(document(), 3, buf, sizeof(buf)));
218   EXPECT_EQ(CFX_WideString(kExpectedPageLabel3),
219             CFX_WideString::FromUTF16LE(buf, FXSYS_len(kExpectedPageLabel3)));
220 
221   const FX_WCHAR kExpectedPageLabel4[] = L"zzA";
222   ASSERT_EQ(8u, FPDF_GetPageLabel(document(), 4, buf, sizeof(buf)));
223   EXPECT_EQ(CFX_WideString(kExpectedPageLabel4),
224             CFX_WideString::FromUTF16LE(buf, FXSYS_len(kExpectedPageLabel4)));
225 
226   const FX_WCHAR kExpectedPageLabel5[] = L"zzB";
227   ASSERT_EQ(8u, FPDF_GetPageLabel(document(), 5, buf, sizeof(buf)));
228   EXPECT_EQ(CFX_WideString(kExpectedPageLabel5),
229             CFX_WideString::FromUTF16LE(buf, FXSYS_len(kExpectedPageLabel5)));
230 
231   const FX_WCHAR kExpectedPageLabel6[] = L"";
232   ASSERT_EQ(2u, FPDF_GetPageLabel(document(), 6, buf, sizeof(buf)));
233   EXPECT_EQ(CFX_WideString(kExpectedPageLabel6),
234             CFX_WideString::FromUTF16LE(buf, FXSYS_len(kExpectedPageLabel6)));
235 
236   ASSERT_EQ(0u, FPDF_GetPageLabel(document(), 7, buf, sizeof(buf)));
237   ASSERT_EQ(0u, FPDF_GetPageLabel(document(), 8, buf, sizeof(buf)));
238 }
239