blob: 5441bb3ecf4dcb8cd9b825fe463ec29d0f51b1c2 [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
Lei Zhange0947b32015-09-17 14:51:48 -070071TEST_F(FPDFDocEmbeddertest, ActionGetFilePath) {
Wei Li091f7a02015-11-09 12:09:55 -080072 EXPECT_TRUE(OpenDocument("launch_action.pdf"));
Lei Zhange0947b32015-09-17 14:51:48 -070073
74 FPDF_PAGE page = FPDF_LoadPage(document(), 0);
75 ASSERT_TRUE(page);
76
77 // The target action is nearly the size of the whole page.
78 FPDF_LINK link = FPDFLink_GetLinkAtPoint(page, 100, 100);
79 ASSERT_TRUE(link);
80
81 FPDF_ACTION action = FPDFLink_GetAction(link);
82 ASSERT_TRUE(action);
83
84 const char kExpectedResult[] = "test.pdf";
85 const unsigned long kExpectedLength = sizeof(kExpectedResult);
86 unsigned long bufsize = FPDFAction_GetFilePath(action, nullptr, 0);
87 ASSERT_EQ(kExpectedLength, bufsize);
88
89 char buf[kExpectedLength];
90 EXPECT_EQ(bufsize, FPDFAction_GetFilePath(action, buf, bufsize));
91 EXPECT_EQ(std::string(kExpectedResult), std::string(buf));
92
93 FPDF_ClosePage(page);
94}
Tom Sepez758ae142015-10-14 09:26:32 -070095
96TEST_F(FPDFDocEmbeddertest, NoBookmarks) {
97 // Open a file with no bookmarks.
Wei Li091f7a02015-11-09 12:09:55 -080098 EXPECT_TRUE(OpenDocument("named_dests.pdf"));
Tom Sepez758ae142015-10-14 09:26:32 -070099
100 // The non-existent top-level bookmark has no title.
101 unsigned short buf[128];
Wei Li05d53f02016-03-29 16:42:53 -0700102 EXPECT_EQ(0u, FPDFBookmark_GetTitle(nullptr, buf, sizeof(buf)));
Tom Sepez758ae142015-10-14 09:26:32 -0700103
104 // The non-existent top-level bookmark has no children.
105 EXPECT_EQ(nullptr, FPDFBookmark_GetFirstChild(document(), nullptr));
106}
107
108TEST_F(FPDFDocEmbeddertest, Bookmarks) {
109 // Open a file with two bookmarks.
Wei Li091f7a02015-11-09 12:09:55 -0800110 EXPECT_TRUE(OpenDocument("bookmarks.pdf"));
Tom Sepez758ae142015-10-14 09:26:32 -0700111
112 // The existent top-level bookmark has no title.
113 unsigned short buf[128];
Wei Li05d53f02016-03-29 16:42:53 -0700114 EXPECT_EQ(0u, FPDFBookmark_GetTitle(nullptr, buf, sizeof(buf)));
Tom Sepez758ae142015-10-14 09:26:32 -0700115
116 FPDF_BOOKMARK child = FPDFBookmark_GetFirstChild(document(), nullptr);
thestig4997b222016-06-07 10:46:22 -0700117 EXPECT_TRUE(child);
Wei Li05d53f02016-03-29 16:42:53 -0700118 EXPECT_EQ(34u, FPDFBookmark_GetTitle(child, buf, sizeof(buf)));
Tom Sepez758ae142015-10-14 09:26:32 -0700119 EXPECT_EQ(CFX_WideString(L"A Good Beginning"),
120 CFX_WideString::FromUTF16LE(buf, 16));
121
122 EXPECT_EQ(nullptr, FPDFBookmark_GetFirstChild(document(), child));
123
124 FPDF_BOOKMARK sibling = FPDFBookmark_GetNextSibling(document(), child);
thestig4997b222016-06-07 10:46:22 -0700125 EXPECT_TRUE(sibling);
Wei Li05d53f02016-03-29 16:42:53 -0700126 EXPECT_EQ(28u, FPDFBookmark_GetTitle(sibling, buf, sizeof(buf)));
Tom Sepez758ae142015-10-14 09:26:32 -0700127 EXPECT_EQ(CFX_WideString(L"A Good Ending"),
128 CFX_WideString::FromUTF16LE(buf, 13));
129
130 EXPECT_EQ(nullptr, FPDFBookmark_GetNextSibling(document(), sibling));
131}
Tom Sepez0861c162016-01-04 16:35:52 -0800132
133TEST_F(FPDFDocEmbeddertest, FindBookmarks) {
Tom Sepez8ab45ea2016-01-05 10:17:30 -0800134 // Open a file with two bookmarks.
Tom Sepez0861c162016-01-04 16:35:52 -0800135 EXPECT_TRUE(OpenDocument("bookmarks.pdf"));
136
Tom Sepez8ab45ea2016-01-05 10:17:30 -0800137 // Find the first one, based on its known title.
Tom Sepez0aa35312016-01-06 10:16:32 -0800138 std::unique_ptr<unsigned short, pdfium::FreeDeleter> title =
139 GetFPDFWideString(L"A Good Beginning");
140 FPDF_BOOKMARK child = FPDFBookmark_Find(document(), title.get());
thestig4997b222016-06-07 10:46:22 -0700141 EXPECT_TRUE(child);
Tom Sepez8ab45ea2016-01-05 10:17:30 -0800142
143 // Check that the string matches.
144 unsigned short buf[128];
Wei Li05d53f02016-03-29 16:42:53 -0700145 EXPECT_EQ(34u, FPDFBookmark_GetTitle(child, buf, sizeof(buf)));
Tom Sepez0861c162016-01-04 16:35:52 -0800146 EXPECT_EQ(CFX_WideString(L"A Good Beginning"),
147 CFX_WideString::FromUTF16LE(buf, 16));
148
Tom Sepez8ab45ea2016-01-05 10:17:30 -0800149 // Check that it is them same as the one returned by GetFirstChild.
150 EXPECT_EQ(child, FPDFBookmark_GetFirstChild(document(), nullptr));
Tom Sepez0861c162016-01-04 16:35:52 -0800151
152 // Try to find one using a non-existent title.
Tom Sepez0aa35312016-01-06 10:16:32 -0800153 std::unique_ptr<unsigned short, pdfium::FreeDeleter> bad_title =
154 GetFPDFWideString(L"A BAD Beginning");
155 EXPECT_EQ(nullptr, FPDFBookmark_Find(document(), bad_title.get()));
Tom Sepez0861c162016-01-04 16:35:52 -0800156}
Wei Li0e2e5d72016-03-03 11:28:06 -0800157
158// Check circular bookmarks will not cause infinite loop.
159TEST_F(FPDFDocEmbeddertest, FindBookmarks_bug420) {
160 // Open a file with circular bookmarks.
161 EXPECT_TRUE(OpenDocument("bookmarks_circular.pdf"));
162
163 // Try to find a title.
164 std::unique_ptr<unsigned short, pdfium::FreeDeleter> title =
165 GetFPDFWideString(L"anything");
166 EXPECT_EQ(nullptr, FPDFBookmark_Find(document(), title.get()));
167}
dsinclair1f5f2ff2016-04-25 14:14:56 -0700168
169TEST_F(FPDFDocEmbeddertest, DeletePage) {
170 EXPECT_TRUE(OpenDocument("hello_world.pdf"));
171 EXPECT_EQ(1, FPDF_GetPageCount(document()));
172 FPDFPage_Delete(document(), 0);
173 EXPECT_EQ(0, FPDF_GetPageCount(document()));
174}
thestig733e0682016-11-23 05:52:39 -0800175
176TEST_F(FPDFDocEmbeddertest, NoPageLabels) {
177 EXPECT_TRUE(OpenDocument("about_blank.pdf"));
178 EXPECT_EQ(1, FPDF_GetPageCount(document()));
179
dsinclair6bdb56c2016-12-06 09:53:27 -0800180 ASSERT_EQ(0u, FPDF_GetPageLabel(document(), 0, nullptr, 0));
thestig733e0682016-11-23 05:52:39 -0800181}
182
183TEST_F(FPDFDocEmbeddertest, GetPageLabels) {
184 EXPECT_TRUE(OpenDocument("page_labels.pdf"));
185 EXPECT_EQ(7, FPDF_GetPageCount(document()));
186
187 unsigned short buf[128];
dsinclair6bdb56c2016-12-06 09:53:27 -0800188 EXPECT_EQ(0u, FPDF_GetPageLabel(document(), -2, buf, sizeof(buf)));
189 EXPECT_EQ(0u, FPDF_GetPageLabel(document(), -1, buf, sizeof(buf)));
thestig733e0682016-11-23 05:52:39 -0800190
191 const FX_WCHAR kExpectedPageLabel0[] = L"i";
dsinclair6bdb56c2016-12-06 09:53:27 -0800192 ASSERT_EQ(4u, FPDF_GetPageLabel(document(), 0, buf, sizeof(buf)));
thestig733e0682016-11-23 05:52:39 -0800193 EXPECT_EQ(CFX_WideString(kExpectedPageLabel0),
194 CFX_WideString::FromUTF16LE(buf, FXSYS_len(kExpectedPageLabel0)));
195
196 const FX_WCHAR kExpectedPageLabel1[] = L"ii";
dsinclair6bdb56c2016-12-06 09:53:27 -0800197 ASSERT_EQ(6u, FPDF_GetPageLabel(document(), 1, buf, sizeof(buf)));
thestig733e0682016-11-23 05:52:39 -0800198 EXPECT_EQ(CFX_WideString(kExpectedPageLabel1),
199 CFX_WideString::FromUTF16LE(buf, FXSYS_len(kExpectedPageLabel1)));
200
201 const FX_WCHAR kExpectedPageLabel2[] = L"1";
dsinclair6bdb56c2016-12-06 09:53:27 -0800202 ASSERT_EQ(4u, FPDF_GetPageLabel(document(), 2, buf, sizeof(buf)));
thestig733e0682016-11-23 05:52:39 -0800203 EXPECT_EQ(CFX_WideString(kExpectedPageLabel2),
204 CFX_WideString::FromUTF16LE(buf, FXSYS_len(kExpectedPageLabel2)));
205
206 const FX_WCHAR kExpectedPageLabel3[] = L"2";
dsinclair6bdb56c2016-12-06 09:53:27 -0800207 ASSERT_EQ(4u, FPDF_GetPageLabel(document(), 3, buf, sizeof(buf)));
thestig733e0682016-11-23 05:52:39 -0800208 EXPECT_EQ(CFX_WideString(kExpectedPageLabel3),
209 CFX_WideString::FromUTF16LE(buf, FXSYS_len(kExpectedPageLabel3)));
210
211 const FX_WCHAR kExpectedPageLabel4[] = L"zzA";
dsinclair6bdb56c2016-12-06 09:53:27 -0800212 ASSERT_EQ(8u, FPDF_GetPageLabel(document(), 4, buf, sizeof(buf)));
thestig733e0682016-11-23 05:52:39 -0800213 EXPECT_EQ(CFX_WideString(kExpectedPageLabel4),
214 CFX_WideString::FromUTF16LE(buf, FXSYS_len(kExpectedPageLabel4)));
215
216 const FX_WCHAR kExpectedPageLabel5[] = L"zzB";
dsinclair6bdb56c2016-12-06 09:53:27 -0800217 ASSERT_EQ(8u, FPDF_GetPageLabel(document(), 5, buf, sizeof(buf)));
thestig733e0682016-11-23 05:52:39 -0800218 EXPECT_EQ(CFX_WideString(kExpectedPageLabel5),
219 CFX_WideString::FromUTF16LE(buf, FXSYS_len(kExpectedPageLabel5)));
220
221 const FX_WCHAR kExpectedPageLabel6[] = L"";
dsinclair6bdb56c2016-12-06 09:53:27 -0800222 ASSERT_EQ(2u, FPDF_GetPageLabel(document(), 6, buf, sizeof(buf)));
thestig733e0682016-11-23 05:52:39 -0800223 EXPECT_EQ(CFX_WideString(kExpectedPageLabel6),
224 CFX_WideString::FromUTF16LE(buf, FXSYS_len(kExpectedPageLabel6)));
225
dsinclair6bdb56c2016-12-06 09:53:27 -0800226 ASSERT_EQ(0u, FPDF_GetPageLabel(document(), 7, buf, sizeof(buf)));
227 ASSERT_EQ(0u, FPDF_GetPageLabel(document(), 8, buf, sizeof(buf)));
thestig733e0682016-11-23 05:52:39 -0800228}