blob: 2472db9746f2186a3c86a5f9a2997f9b74d7a5ef [file] [log] [blame]
Tom Sepezc8f6ab62015-01-22 11:20:06 -08001// 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
Dan Sinclair85c8e7f2016-11-21 13:50:32 -05005#include <memory>
Dan Sinclair3ebd1212016-03-09 09:59:23 -05006#include <string>
7
dsinclaira52ab742016-09-29 13:59:29 -07008#include "core/fxcrt/fx_string.h"
Lei Zhangb4e7f302015-11-06 15:52:32 -08009#include "public/fpdf_doc.h"
dsinclair1f5f2ff2016-04-25 14:14:56 -070010#include "public/fpdf_edit.h"
Lei Zhangb4e7f302015-11-06 15:52:32 -080011#include "public/fpdfview.h"
Wei Li091f7a02015-11-09 12:09:55 -080012#include "testing/embedder_test.h"
13#include "testing/fx_string_testhelpers.h"
Tom Sepezc8f6ab62015-01-22 11:20:06 -080014#include "testing/gtest/include/gtest/gtest.h"
Dan Sinclair61046b92016-02-18 14:48:48 -050015#include "testing/test_support.h"
Tom Sepezc8f6ab62015-01-22 11:20:06 -080016
Nico Weber9d8ec5a2015-08-04 13:00:21 -070017class FPDFDocEmbeddertest : public EmbedderTest {};
Tom Sepezc8f6ab62015-01-22 11:20:06 -080018
19TEST_F(FPDFDocEmbeddertest, DestGetPageIndex) {
Wei Li091f7a02015-11-09 12:09:55 -080020 EXPECT_TRUE(OpenDocument("named_dests.pdf"));
Tom Sepezc8f6ab62015-01-22 11:20:06 -080021
22 // NULL FPDF_DEST case.
Lei Zhangb9c31972015-08-11 14:09:35 -070023 EXPECT_EQ(0U, FPDFDest_GetPageIndex(document(), nullptr));
Tom Sepezc8f6ab62015-01-22 11:20:06 -080024
25 // Page number directly in item from Dests NameTree.
26 FPDF_DEST dest = FPDF_GetNamedDestByName(document(), "First");
thestig4997b222016-06-07 10:46:22 -070027 EXPECT_TRUE(dest);
Lei Zhangb9c31972015-08-11 14:09:35 -070028 EXPECT_EQ(1U, FPDFDest_GetPageIndex(document(), dest));
Tom Sepezc8f6ab62015-01-22 11:20:06 -080029
30 // Page number via object reference in item from Dests NameTree.
31 dest = FPDF_GetNamedDestByName(document(), "Next");
thestig4997b222016-06-07 10:46:22 -070032 EXPECT_TRUE(dest);
Lei Zhangb9c31972015-08-11 14:09:35 -070033 EXPECT_EQ(1U, FPDFDest_GetPageIndex(document(), dest));
Tom Sepezc8f6ab62015-01-22 11:20:06 -080034
35 // Page number directly in item from Dests dictionary.
36 dest = FPDF_GetNamedDestByName(document(), "FirstAlternate");
thestig4997b222016-06-07 10:46:22 -070037 EXPECT_TRUE(dest);
Lei Zhangb9c31972015-08-11 14:09:35 -070038 EXPECT_EQ(11U, FPDFDest_GetPageIndex(document(), dest));
Tom Sepezc8f6ab62015-01-22 11:20:06 -080039
40 // Invalid object reference in item from Dests NameTree.
41 dest = FPDF_GetNamedDestByName(document(), "LastAlternate");
thestig4997b222016-06-07 10:46:22 -070042 EXPECT_TRUE(dest);
Lei Zhangb9c31972015-08-11 14:09:35 -070043 EXPECT_EQ(0U, FPDFDest_GetPageIndex(document(), dest));
Tom Sepezc8f6ab62015-01-22 11:20:06 -080044}
Lei Zhange0947b32015-09-17 14:51:48 -070045
dsinclairc59fa882016-11-08 06:55:40 -080046TEST_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
tsepeze507dc52017-01-18 10:24:35 -080071TEST_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
Lei Zhange0947b32015-09-17 14:51:48 -070081TEST_F(FPDFDocEmbeddertest, ActionGetFilePath) {
Wei Li091f7a02015-11-09 12:09:55 -080082 EXPECT_TRUE(OpenDocument("launch_action.pdf"));
Lei Zhange0947b32015-09-17 14:51:48 -070083
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}
Tom Sepez758ae142015-10-14 09:26:32 -0700105
106TEST_F(FPDFDocEmbeddertest, NoBookmarks) {
107 // Open a file with no bookmarks.
Wei Li091f7a02015-11-09 12:09:55 -0800108 EXPECT_TRUE(OpenDocument("named_dests.pdf"));
Tom Sepez758ae142015-10-14 09:26:32 -0700109
110 // The non-existent top-level bookmark has no title.
111 unsigned short buf[128];
Wei Li05d53f02016-03-29 16:42:53 -0700112 EXPECT_EQ(0u, FPDFBookmark_GetTitle(nullptr, buf, sizeof(buf)));
Tom Sepez758ae142015-10-14 09:26:32 -0700113
114 // The non-existent top-level bookmark has no children.
115 EXPECT_EQ(nullptr, FPDFBookmark_GetFirstChild(document(), nullptr));
116}
117
118TEST_F(FPDFDocEmbeddertest, Bookmarks) {
119 // Open a file with two bookmarks.
Wei Li091f7a02015-11-09 12:09:55 -0800120 EXPECT_TRUE(OpenDocument("bookmarks.pdf"));
Tom Sepez758ae142015-10-14 09:26:32 -0700121
122 // The existent top-level bookmark has no title.
123 unsigned short buf[128];
Wei Li05d53f02016-03-29 16:42:53 -0700124 EXPECT_EQ(0u, FPDFBookmark_GetTitle(nullptr, buf, sizeof(buf)));
Tom Sepez758ae142015-10-14 09:26:32 -0700125
126 FPDF_BOOKMARK child = FPDFBookmark_GetFirstChild(document(), nullptr);
thestig4997b222016-06-07 10:46:22 -0700127 EXPECT_TRUE(child);
Wei Li05d53f02016-03-29 16:42:53 -0700128 EXPECT_EQ(34u, FPDFBookmark_GetTitle(child, buf, sizeof(buf)));
Tom Sepez758ae142015-10-14 09:26:32 -0700129 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);
thestig4997b222016-06-07 10:46:22 -0700135 EXPECT_TRUE(sibling);
Wei Li05d53f02016-03-29 16:42:53 -0700136 EXPECT_EQ(28u, FPDFBookmark_GetTitle(sibling, buf, sizeof(buf)));
Tom Sepez758ae142015-10-14 09:26:32 -0700137 EXPECT_EQ(CFX_WideString(L"A Good Ending"),
138 CFX_WideString::FromUTF16LE(buf, 13));
139
140 EXPECT_EQ(nullptr, FPDFBookmark_GetNextSibling(document(), sibling));
141}
Tom Sepez0861c162016-01-04 16:35:52 -0800142
143TEST_F(FPDFDocEmbeddertest, FindBookmarks) {
Tom Sepez8ab45ea2016-01-05 10:17:30 -0800144 // Open a file with two bookmarks.
Tom Sepez0861c162016-01-04 16:35:52 -0800145 EXPECT_TRUE(OpenDocument("bookmarks.pdf"));
146
Tom Sepez8ab45ea2016-01-05 10:17:30 -0800147 // Find the first one, based on its known title.
Tom Sepez0aa35312016-01-06 10:16:32 -0800148 std::unique_ptr<unsigned short, pdfium::FreeDeleter> title =
149 GetFPDFWideString(L"A Good Beginning");
150 FPDF_BOOKMARK child = FPDFBookmark_Find(document(), title.get());
thestig4997b222016-06-07 10:46:22 -0700151 EXPECT_TRUE(child);
Tom Sepez8ab45ea2016-01-05 10:17:30 -0800152
153 // Check that the string matches.
154 unsigned short buf[128];
Wei Li05d53f02016-03-29 16:42:53 -0700155 EXPECT_EQ(34u, FPDFBookmark_GetTitle(child, buf, sizeof(buf)));
Tom Sepez0861c162016-01-04 16:35:52 -0800156 EXPECT_EQ(CFX_WideString(L"A Good Beginning"),
157 CFX_WideString::FromUTF16LE(buf, 16));
158
Tom Sepez8ab45ea2016-01-05 10:17:30 -0800159 // Check that it is them same as the one returned by GetFirstChild.
160 EXPECT_EQ(child, FPDFBookmark_GetFirstChild(document(), nullptr));
Tom Sepez0861c162016-01-04 16:35:52 -0800161
162 // Try to find one using a non-existent title.
Tom Sepez0aa35312016-01-06 10:16:32 -0800163 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()));
Tom Sepez0861c162016-01-04 16:35:52 -0800166}
Wei Li0e2e5d72016-03-03 11:28:06 -0800167
168// Check circular bookmarks will not cause infinite loop.
169TEST_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}
dsinclair1f5f2ff2016-04-25 14:14:56 -0700178
179TEST_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}
thestig733e0682016-11-23 05:52:39 -0800185
186TEST_F(FPDFDocEmbeddertest, NoPageLabels) {
187 EXPECT_TRUE(OpenDocument("about_blank.pdf"));
188 EXPECT_EQ(1, FPDF_GetPageCount(document()));
189
dsinclair6bdb56c2016-12-06 09:53:27 -0800190 ASSERT_EQ(0u, FPDF_GetPageLabel(document(), 0, nullptr, 0));
thestig733e0682016-11-23 05:52:39 -0800191}
192
193TEST_F(FPDFDocEmbeddertest, GetPageLabels) {
194 EXPECT_TRUE(OpenDocument("page_labels.pdf"));
195 EXPECT_EQ(7, FPDF_GetPageCount(document()));
196
197 unsigned short buf[128];
dsinclair6bdb56c2016-12-06 09:53:27 -0800198 EXPECT_EQ(0u, FPDF_GetPageLabel(document(), -2, buf, sizeof(buf)));
199 EXPECT_EQ(0u, FPDF_GetPageLabel(document(), -1, buf, sizeof(buf)));
thestig733e0682016-11-23 05:52:39 -0800200
Dan Sinclair812e96c2017-03-13 16:43:37 -0400201 const wchar_t kExpectedPageLabel0[] = L"i";
dsinclair6bdb56c2016-12-06 09:53:27 -0800202 ASSERT_EQ(4u, FPDF_GetPageLabel(document(), 0, buf, sizeof(buf)));
thestig733e0682016-11-23 05:52:39 -0800203 EXPECT_EQ(CFX_WideString(kExpectedPageLabel0),
204 CFX_WideString::FromUTF16LE(buf, FXSYS_len(kExpectedPageLabel0)));
205
Dan Sinclair812e96c2017-03-13 16:43:37 -0400206 const wchar_t kExpectedPageLabel1[] = L"ii";
dsinclair6bdb56c2016-12-06 09:53:27 -0800207 ASSERT_EQ(6u, FPDF_GetPageLabel(document(), 1, buf, sizeof(buf)));
thestig733e0682016-11-23 05:52:39 -0800208 EXPECT_EQ(CFX_WideString(kExpectedPageLabel1),
209 CFX_WideString::FromUTF16LE(buf, FXSYS_len(kExpectedPageLabel1)));
210
Dan Sinclair812e96c2017-03-13 16:43:37 -0400211 const wchar_t kExpectedPageLabel2[] = L"1";
dsinclair6bdb56c2016-12-06 09:53:27 -0800212 ASSERT_EQ(4u, FPDF_GetPageLabel(document(), 2, buf, sizeof(buf)));
thestig733e0682016-11-23 05:52:39 -0800213 EXPECT_EQ(CFX_WideString(kExpectedPageLabel2),
214 CFX_WideString::FromUTF16LE(buf, FXSYS_len(kExpectedPageLabel2)));
215
Dan Sinclair812e96c2017-03-13 16:43:37 -0400216 const wchar_t kExpectedPageLabel3[] = L"2";
dsinclair6bdb56c2016-12-06 09:53:27 -0800217 ASSERT_EQ(4u, FPDF_GetPageLabel(document(), 3, buf, sizeof(buf)));
thestig733e0682016-11-23 05:52:39 -0800218 EXPECT_EQ(CFX_WideString(kExpectedPageLabel3),
219 CFX_WideString::FromUTF16LE(buf, FXSYS_len(kExpectedPageLabel3)));
220
Dan Sinclair812e96c2017-03-13 16:43:37 -0400221 const wchar_t kExpectedPageLabel4[] = L"zzA";
dsinclair6bdb56c2016-12-06 09:53:27 -0800222 ASSERT_EQ(8u, FPDF_GetPageLabel(document(), 4, buf, sizeof(buf)));
thestig733e0682016-11-23 05:52:39 -0800223 EXPECT_EQ(CFX_WideString(kExpectedPageLabel4),
224 CFX_WideString::FromUTF16LE(buf, FXSYS_len(kExpectedPageLabel4)));
225
Dan Sinclair812e96c2017-03-13 16:43:37 -0400226 const wchar_t kExpectedPageLabel5[] = L"zzB";
dsinclair6bdb56c2016-12-06 09:53:27 -0800227 ASSERT_EQ(8u, FPDF_GetPageLabel(document(), 5, buf, sizeof(buf)));
thestig733e0682016-11-23 05:52:39 -0800228 EXPECT_EQ(CFX_WideString(kExpectedPageLabel5),
229 CFX_WideString::FromUTF16LE(buf, FXSYS_len(kExpectedPageLabel5)));
230
Dan Sinclair812e96c2017-03-13 16:43:37 -0400231 const wchar_t kExpectedPageLabel6[] = L"";
dsinclair6bdb56c2016-12-06 09:53:27 -0800232 ASSERT_EQ(2u, FPDF_GetPageLabel(document(), 6, buf, sizeof(buf)));
thestig733e0682016-11-23 05:52:39 -0800233 EXPECT_EQ(CFX_WideString(kExpectedPageLabel6),
234 CFX_WideString::FromUTF16LE(buf, FXSYS_len(kExpectedPageLabel6)));
235
dsinclair6bdb56c2016-12-06 09:53:27 -0800236 ASSERT_EQ(0u, FPDF_GetPageLabel(document(), 7, buf, sizeof(buf)));
237 ASSERT_EQ(0u, FPDF_GetPageLabel(document(), 8, buf, sizeof(buf)));
thestig733e0682016-11-23 05:52:39 -0800238}