1 // Copyright 2016 The PDFium Authors
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 <string>
6
7 #include "build/build_config.h"
8 #include "core/fpdfapi/parser/cpdf_dictionary.h"
9 #include "core/fpdfapi/parser/cpdf_document.h"
10 #include "core/fpdfapi/parser/cpdf_parser.h"
11 #include "core/fxcrt/fx_system.h"
12 #include "core/fxge/cfx_defaultrenderdevice.h"
13 #include "public/cpp/fpdf_scopers.h"
14 #include "public/fpdf_edit.h"
15 #include "public/fpdf_save.h"
16 #include "public/fpdfview.h"
17 #include "testing/embedder_test.h"
18 #include "testing/embedder_test_constants.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20
21 namespace {
22
23 const char kAgeUTF8[] =
24 "\xc3\xa2"
25 "ge";
26 const char kAgeLatin1[] =
27 "\xe2"
28 "ge";
29
30 const char kHotelUTF8[] =
31 "h"
32 "\xc3\xb4"
33 "tel";
34 const char kHotelLatin1[] =
35 "h"
36 "\xf4"
37 "tel";
38
39 } // namespace
40
41 class CPDFSecurityHandlerEmbedderTest : public EmbedderTest {
42 protected:
OpenAndVerifyHelloWorldDocumentWithPassword(const char * filename,const char * password)43 void OpenAndVerifyHelloWorldDocumentWithPassword(const char* filename,
44 const char* password) {
45 ASSERT_TRUE(OpenDocumentWithPassword(filename, password));
46 FPDF_PAGE page = LoadPage(0);
47 VerifyHelloWorldPage(page);
48 UnloadPage(page);
49 }
50
VerifySavedHelloWorldDocumentWithPassword(const char * password)51 void VerifySavedHelloWorldDocumentWithPassword(const char* password) {
52 ASSERT_TRUE(OpenSavedDocumentWithPassword(password));
53 FPDF_PAGE page = LoadSavedPage(0);
54 VerifyHelloWorldPage(page);
55 CloseSavedPage(page);
56 CloseSavedDocument();
57 }
58
VerifySavedModifiedHelloWorldDocumentWithPassword(const char * password)59 void VerifySavedModifiedHelloWorldDocumentWithPassword(const char* password) {
60 ASSERT_TRUE(OpenSavedDocumentWithPassword(password));
61 FPDF_PAGE page = LoadSavedPage(0);
62 VerifyModifiedHelloWorldPage(page);
63 CloseSavedPage(page);
64 CloseSavedDocument();
65 }
66
RemoveTrailerIdFromDocument()67 void RemoveTrailerIdFromDocument() {
68 // This is cheating slightly to avoid a layering violation, since this file
69 // cannot include fpdfsdk/cpdfsdk_helpers.h to get access to
70 // CPDFDocumentFromFPDFDocument().
71 CPDF_Document* doc = reinterpret_cast<CPDF_Document*>((document()));
72 ASSERT_TRUE(doc);
73 CPDF_Parser* parser = doc->GetParser();
74 ASSERT_TRUE(parser);
75 CPDF_Dictionary* trailer = parser->GetMutableTrailerForTesting();
76 ASSERT_TRUE(trailer);
77 ASSERT_TRUE(trailer->RemoveFor("ID"));
78 }
79
RemoveGoodbyeObject()80 void RemoveGoodbyeObject() {
81 FPDF_PAGE page = LoadPage(0);
82 {
83 ScopedFPDFPageObject goodbye_object(FPDFPage_GetObject(page, 1));
84 ASSERT_TRUE(goodbye_object);
85 ASSERT_TRUE(FPDFPage_RemoveObject(page, goodbye_object.get()));
86 }
87 ASSERT_TRUE(FPDFPage_GenerateContent(page));
88 VerifyModifiedHelloWorldPage(page);
89 UnloadPage(page);
90 }
91
92 private:
VerifyHelloWorldPage(FPDF_PAGE page)93 void VerifyHelloWorldPage(FPDF_PAGE page) {
94 ASSERT_TRUE(page);
95
96 ScopedFPDFBitmap page_bitmap = RenderPage(page);
97 CompareBitmap(page_bitmap.get(), 200, 200, pdfium::HelloWorldChecksum());
98 }
99
VerifyModifiedHelloWorldPage(FPDF_PAGE page)100 void VerifyModifiedHelloWorldPage(FPDF_PAGE page) {
101 ASSERT_TRUE(page);
102
103 ScopedFPDFBitmap page_bitmap = RenderPage(page);
104 CompareBitmap(page_bitmap.get(), 200, 200,
105 pdfium::HelloWorldRemovedChecksum());
106 }
107 };
108
TEST_F(CPDFSecurityHandlerEmbedderTest,Unencrypted)109 TEST_F(CPDFSecurityHandlerEmbedderTest, Unencrypted) {
110 ASSERT_TRUE(OpenDocument("about_blank.pdf"));
111 EXPECT_EQ(0xFFFFFFFF, FPDF_GetDocPermissions(document()));
112 }
113
TEST_F(CPDFSecurityHandlerEmbedderTest,UnencryptedWithPassword)114 TEST_F(CPDFSecurityHandlerEmbedderTest, UnencryptedWithPassword) {
115 ASSERT_TRUE(OpenDocumentWithPassword("about_blank.pdf", "foobar"));
116 EXPECT_EQ(0xFFFFFFFF, FPDF_GetDocPermissions(document()));
117 }
118
TEST_F(CPDFSecurityHandlerEmbedderTest,NoPassword)119 TEST_F(CPDFSecurityHandlerEmbedderTest, NoPassword) {
120 EXPECT_FALSE(OpenDocument("encrypted.pdf"));
121 }
122
TEST_F(CPDFSecurityHandlerEmbedderTest,BadPassword)123 TEST_F(CPDFSecurityHandlerEmbedderTest, BadPassword) {
124 EXPECT_FALSE(OpenDocumentWithPassword("encrypted.pdf", "tiger"));
125 }
126
TEST_F(CPDFSecurityHandlerEmbedderTest,UserPassword)127 TEST_F(CPDFSecurityHandlerEmbedderTest, UserPassword) {
128 ASSERT_TRUE(OpenDocumentWithPassword("encrypted.pdf", "1234"));
129 EXPECT_EQ(0xFFFFF2C0, FPDF_GetDocPermissions(document()));
130 }
131
TEST_F(CPDFSecurityHandlerEmbedderTest,OwnerPassword)132 TEST_F(CPDFSecurityHandlerEmbedderTest, OwnerPassword) {
133 ASSERT_TRUE(OpenDocumentWithPassword("encrypted.pdf", "5678"));
134 EXPECT_EQ(0xFFFFFFFC, FPDF_GetDocPermissions(document()));
135 }
136
TEST_F(CPDFSecurityHandlerEmbedderTest,PasswordAfterGenerateSave)137 TEST_F(CPDFSecurityHandlerEmbedderTest, PasswordAfterGenerateSave) {
138 const char* checksum = []() {
139 if (CFX_DefaultRenderDevice::SkiaIsDefaultRenderer()) {
140 return "ad97491cab71c02f1f4ef5ba0a7b5593";
141 }
142 #if BUILDFLAG(IS_APPLE)
143 return "2a308e8cc20a6221112c387d122075a8";
144 #else
145 return "9fe7eef8e51d15a604001854be6ed1ee";
146 #endif // BUILDFLAG(IS_APPLE)
147 }();
148 {
149 ASSERT_TRUE(OpenDocumentWithOptions("encrypted.pdf", "5678",
150 LinearizeOption::kMustLinearize,
151 JavaScriptOption::kEnableJavaScript));
152 FPDF_PAGE page = LoadPage(0);
153 ASSERT_TRUE(page);
154 FPDF_PAGEOBJECT red_rect = FPDFPageObj_CreateNewRect(10, 10, 20, 20);
155 ASSERT_TRUE(red_rect);
156 EXPECT_TRUE(FPDFPageObj_SetFillColor(red_rect, 255, 0, 0, 255));
157 EXPECT_TRUE(FPDFPath_SetDrawMode(red_rect, FPDF_FILLMODE_ALTERNATE, 0));
158 FPDFPage_InsertObject(page, red_rect);
159 ScopedFPDFBitmap bitmap = RenderLoadedPage(page);
160 CompareBitmap(bitmap.get(), 612, 792, checksum);
161 EXPECT_TRUE(FPDFPage_GenerateContent(page));
162 SetWholeFileAvailable();
163 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
164 UnloadPage(page);
165 }
166 std::string new_file = GetString();
167 FPDF_FILEACCESS file_access;
168 memset(&file_access, 0, sizeof(file_access));
169 file_access.m_FileLen = new_file.size();
170 file_access.m_GetBlock = GetBlockFromString;
171 file_access.m_Param = &new_file;
172 EXPECT_FALSE(FPDF_LoadCustomDocument(&file_access, nullptr));
173
174 struct {
175 const char* password;
176 const unsigned long permissions;
177 } tests[] = {{"1234", 0xFFFFF2C0}, {"5678", 0xFFFFFFFC}};
178
179 for (const auto& test : tests) {
180 ASSERT_TRUE(OpenSavedDocumentWithPassword(test.password));
181 FPDF_PAGE page = LoadSavedPage(0);
182 ASSERT_TRUE(page);
183 VerifySavedRendering(page, 612, 792, checksum);
184 EXPECT_EQ(test.permissions, FPDF_GetDocPermissions(saved_document()));
185
186 CloseSavedPage(page);
187 CloseSavedDocument();
188 }
189 }
190
TEST_F(CPDFSecurityHandlerEmbedderTest,NoPasswordVersion5)191 TEST_F(CPDFSecurityHandlerEmbedderTest, NoPasswordVersion5) {
192 ASSERT_FALSE(OpenDocument("bug_644.pdf"));
193 }
194
TEST_F(CPDFSecurityHandlerEmbedderTest,BadPasswordVersion5)195 TEST_F(CPDFSecurityHandlerEmbedderTest, BadPasswordVersion5) {
196 ASSERT_FALSE(OpenDocumentWithPassword("bug_644.pdf", "tiger"));
197 }
198
TEST_F(CPDFSecurityHandlerEmbedderTest,OwnerPasswordVersion5)199 TEST_F(CPDFSecurityHandlerEmbedderTest, OwnerPasswordVersion5) {
200 ASSERT_TRUE(OpenDocumentWithPassword("bug_644.pdf", "a"));
201 EXPECT_EQ(0xFFFFFFFC, FPDF_GetDocPermissions(document()));
202 }
203
TEST_F(CPDFSecurityHandlerEmbedderTest,UserPasswordVersion5)204 TEST_F(CPDFSecurityHandlerEmbedderTest, UserPasswordVersion5) {
205 ASSERT_TRUE(OpenDocumentWithPassword("bug_644.pdf", "b"));
206 EXPECT_EQ(0xFFFFFFFC, FPDF_GetDocPermissions(document()));
207 }
208
209 // Should not crash. https://crbug.com/pdfium/1436
TEST_F(CPDFSecurityHandlerEmbedderTest,BadOkeyVersion2)210 TEST_F(CPDFSecurityHandlerEmbedderTest, BadOkeyVersion2) {
211 EXPECT_FALSE(
212 OpenDocumentWithPassword("encrypted_hello_world_r2_bad_okey.pdf", "a"));
213 }
214
215 // Should not crash. https://crbug.com/pdfium/1436
TEST_F(CPDFSecurityHandlerEmbedderTest,BadOkeyVersion3)216 TEST_F(CPDFSecurityHandlerEmbedderTest, BadOkeyVersion3) {
217 EXPECT_FALSE(
218 OpenDocumentWithPassword("encrypted_hello_world_r3_bad_okey.pdf", "a"));
219 }
220
TEST_F(CPDFSecurityHandlerEmbedderTest,OwnerPasswordVersion2UTF8)221 TEST_F(CPDFSecurityHandlerEmbedderTest, OwnerPasswordVersion2UTF8) {
222 // The password is "age", where the 'a' has a circumflex. Encoding the
223 // password as UTF-8 works.
224 OpenAndVerifyHelloWorldDocumentWithPassword("encrypted_hello_world_r2.pdf",
225 kAgeUTF8);
226 EXPECT_EQ(2, FPDF_GetSecurityHandlerRevision(document()));
227 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
228 VerifySavedHelloWorldDocumentWithPassword(kAgeLatin1);
229 VerifySavedHelloWorldDocumentWithPassword(kAgeUTF8);
230 VerifySavedHelloWorldDocumentWithPassword(kHotelLatin1);
231 VerifySavedHelloWorldDocumentWithPassword(kHotelUTF8);
232
233 ClearString();
234 RemoveTrailerIdFromDocument();
235 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
236 // With revision 2 and 3, the owner password is not tied to the document ID in
237 // the trailer, so the owner password entry remains in the copy and is still
238 // valid, even though the document ID has changed.
239 // The user password is tied to the document ID, so without an existing ID,
240 // the user password entry has to be regenerated with the owner password.
241 // Since the user password was not used to decrypt the document, it cannot be
242 // recovered. Thus only verify the owner password, which is now also the user
243 // password.
244 VerifySavedHelloWorldDocumentWithPassword(kAgeLatin1);
245 VerifySavedHelloWorldDocumentWithPassword(kAgeUTF8);
246
247 ClearString();
248 RemoveGoodbyeObject();
249 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
250 VerifySavedModifiedHelloWorldDocumentWithPassword(kAgeLatin1);
251 VerifySavedModifiedHelloWorldDocumentWithPassword(kAgeUTF8);
252 }
253
TEST_F(CPDFSecurityHandlerEmbedderTest,OwnerPasswordVersion2Latin1)254 TEST_F(CPDFSecurityHandlerEmbedderTest, OwnerPasswordVersion2Latin1) {
255 // The same password encoded as Latin-1 also works at revision 2.
256 OpenAndVerifyHelloWorldDocumentWithPassword("encrypted_hello_world_r2.pdf",
257 kAgeLatin1);
258 EXPECT_EQ(2, FPDF_GetSecurityHandlerRevision(document()));
259 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
260 VerifySavedHelloWorldDocumentWithPassword(kAgeLatin1);
261 VerifySavedHelloWorldDocumentWithPassword(kAgeUTF8);
262 VerifySavedHelloWorldDocumentWithPassword(kHotelLatin1);
263 VerifySavedHelloWorldDocumentWithPassword(kHotelUTF8);
264
265 ClearString();
266 RemoveTrailerIdFromDocument();
267 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
268 VerifySavedHelloWorldDocumentWithPassword(kAgeLatin1);
269 VerifySavedHelloWorldDocumentWithPassword(kAgeUTF8);
270
271 ClearString();
272 RemoveGoodbyeObject();
273 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
274 VerifySavedModifiedHelloWorldDocumentWithPassword(kAgeLatin1);
275 VerifySavedModifiedHelloWorldDocumentWithPassword(kAgeUTF8);
276 }
277
TEST_F(CPDFSecurityHandlerEmbedderTest,OwnerPasswordVersion3UTF8)278 TEST_F(CPDFSecurityHandlerEmbedderTest, OwnerPasswordVersion3UTF8) {
279 // Same as OwnerPasswordVersion2UTF8 test above.
280 OpenAndVerifyHelloWorldDocumentWithPassword("encrypted_hello_world_r3.pdf",
281 kAgeUTF8);
282 EXPECT_EQ(3, FPDF_GetSecurityHandlerRevision(document()));
283 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
284 VerifySavedHelloWorldDocumentWithPassword(kAgeLatin1);
285 VerifySavedHelloWorldDocumentWithPassword(kAgeUTF8);
286 VerifySavedHelloWorldDocumentWithPassword(kHotelLatin1);
287 VerifySavedHelloWorldDocumentWithPassword(kHotelUTF8);
288
289 ClearString();
290 RemoveTrailerIdFromDocument();
291 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
292 VerifySavedHelloWorldDocumentWithPassword(kAgeLatin1);
293 VerifySavedHelloWorldDocumentWithPassword(kAgeUTF8);
294
295 ClearString();
296 RemoveGoodbyeObject();
297 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
298 VerifySavedModifiedHelloWorldDocumentWithPassword(kAgeLatin1);
299 VerifySavedModifiedHelloWorldDocumentWithPassword(kAgeUTF8);
300 }
301
TEST_F(CPDFSecurityHandlerEmbedderTest,OwnerPasswordVersion3Latin1)302 TEST_F(CPDFSecurityHandlerEmbedderTest, OwnerPasswordVersion3Latin1) {
303 // Same as OwnerPasswordVersion2Latin1 test above.
304 OpenAndVerifyHelloWorldDocumentWithPassword("encrypted_hello_world_r3.pdf",
305 kAgeLatin1);
306 EXPECT_EQ(3, FPDF_GetSecurityHandlerRevision(document()));
307 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
308 VerifySavedHelloWorldDocumentWithPassword(kAgeLatin1);
309 VerifySavedHelloWorldDocumentWithPassword(kAgeUTF8);
310 VerifySavedHelloWorldDocumentWithPassword(kHotelLatin1);
311 VerifySavedHelloWorldDocumentWithPassword(kHotelUTF8);
312
313 ClearString();
314 RemoveTrailerIdFromDocument();
315 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
316 VerifySavedHelloWorldDocumentWithPassword(kAgeLatin1);
317 VerifySavedHelloWorldDocumentWithPassword(kAgeUTF8);
318
319 ClearString();
320 RemoveGoodbyeObject();
321 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
322 VerifySavedModifiedHelloWorldDocumentWithPassword(kAgeLatin1);
323 VerifySavedModifiedHelloWorldDocumentWithPassword(kAgeUTF8);
324 }
325
TEST_F(CPDFSecurityHandlerEmbedderTest,OwnerPasswordVersion5UTF8)326 TEST_F(CPDFSecurityHandlerEmbedderTest, OwnerPasswordVersion5UTF8) {
327 // Same as OwnerPasswordVersion2UTF8 test above.
328 OpenAndVerifyHelloWorldDocumentWithPassword("encrypted_hello_world_r5.pdf",
329 kAgeUTF8);
330 EXPECT_EQ(5, FPDF_GetSecurityHandlerRevision(document()));
331 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
332 VerifySavedHelloWorldDocumentWithPassword(kAgeLatin1);
333 VerifySavedHelloWorldDocumentWithPassword(kAgeUTF8);
334 VerifySavedHelloWorldDocumentWithPassword(kHotelLatin1);
335 VerifySavedHelloWorldDocumentWithPassword(kHotelUTF8);
336
337 ClearString();
338 RemoveTrailerIdFromDocument();
339 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
340 VerifySavedHelloWorldDocumentWithPassword(kAgeLatin1);
341 VerifySavedHelloWorldDocumentWithPassword(kAgeUTF8);
342 VerifySavedHelloWorldDocumentWithPassword(kHotelLatin1);
343 VerifySavedHelloWorldDocumentWithPassword(kHotelUTF8);
344
345 ClearString();
346 RemoveGoodbyeObject();
347 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
348 VerifySavedModifiedHelloWorldDocumentWithPassword(kAgeLatin1);
349 VerifySavedModifiedHelloWorldDocumentWithPassword(kAgeUTF8);
350 VerifySavedModifiedHelloWorldDocumentWithPassword(kHotelLatin1);
351 VerifySavedModifiedHelloWorldDocumentWithPassword(kHotelUTF8);
352 }
353
TEST_F(CPDFSecurityHandlerEmbedderTest,OwnerPasswordVersion5Latin1)354 TEST_F(CPDFSecurityHandlerEmbedderTest, OwnerPasswordVersion5Latin1) {
355 // Same as OwnerPasswordVersion2Latin1 test above.
356 OpenAndVerifyHelloWorldDocumentWithPassword("encrypted_hello_world_r5.pdf",
357 kAgeLatin1);
358 EXPECT_EQ(5, FPDF_GetSecurityHandlerRevision(document()));
359 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
360 VerifySavedHelloWorldDocumentWithPassword(kAgeLatin1);
361 VerifySavedHelloWorldDocumentWithPassword(kAgeUTF8);
362 VerifySavedHelloWorldDocumentWithPassword(kHotelLatin1);
363 VerifySavedHelloWorldDocumentWithPassword(kHotelUTF8);
364
365 ClearString();
366 RemoveTrailerIdFromDocument();
367 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
368 VerifySavedHelloWorldDocumentWithPassword(kAgeLatin1);
369 VerifySavedHelloWorldDocumentWithPassword(kAgeUTF8);
370 VerifySavedHelloWorldDocumentWithPassword(kHotelLatin1);
371 VerifySavedHelloWorldDocumentWithPassword(kHotelUTF8);
372
373 ClearString();
374 RemoveGoodbyeObject();
375 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
376 VerifySavedModifiedHelloWorldDocumentWithPassword(kAgeLatin1);
377 VerifySavedModifiedHelloWorldDocumentWithPassword(kAgeUTF8);
378 VerifySavedModifiedHelloWorldDocumentWithPassword(kHotelLatin1);
379 VerifySavedModifiedHelloWorldDocumentWithPassword(kHotelUTF8);
380 }
381
TEST_F(CPDFSecurityHandlerEmbedderTest,OwnerPasswordVersion6UTF8)382 TEST_F(CPDFSecurityHandlerEmbedderTest, OwnerPasswordVersion6UTF8) {
383 // Same as OwnerPasswordVersion2UTF8 test above.
384 OpenAndVerifyHelloWorldDocumentWithPassword("encrypted_hello_world_r6.pdf",
385 kAgeUTF8);
386 EXPECT_EQ(6, FPDF_GetSecurityHandlerRevision(document()));
387 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
388 VerifySavedHelloWorldDocumentWithPassword(kAgeLatin1);
389 VerifySavedHelloWorldDocumentWithPassword(kAgeUTF8);
390 VerifySavedHelloWorldDocumentWithPassword(kHotelLatin1);
391 VerifySavedHelloWorldDocumentWithPassword(kHotelUTF8);
392
393 ClearString();
394 RemoveTrailerIdFromDocument();
395 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
396 VerifySavedHelloWorldDocumentWithPassword(kAgeLatin1);
397 VerifySavedHelloWorldDocumentWithPassword(kAgeUTF8);
398 VerifySavedHelloWorldDocumentWithPassword(kHotelLatin1);
399 VerifySavedHelloWorldDocumentWithPassword(kHotelUTF8);
400
401 ClearString();
402 RemoveGoodbyeObject();
403 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
404 VerifySavedModifiedHelloWorldDocumentWithPassword(kAgeLatin1);
405 VerifySavedModifiedHelloWorldDocumentWithPassword(kAgeUTF8);
406 VerifySavedModifiedHelloWorldDocumentWithPassword(kHotelLatin1);
407 VerifySavedModifiedHelloWorldDocumentWithPassword(kHotelUTF8);
408 }
409
TEST_F(CPDFSecurityHandlerEmbedderTest,OwnerPasswordVersion6Latin1)410 TEST_F(CPDFSecurityHandlerEmbedderTest, OwnerPasswordVersion6Latin1) {
411 // Same as OwnerPasswordVersion2Latin1 test above.
412 OpenAndVerifyHelloWorldDocumentWithPassword("encrypted_hello_world_r6.pdf",
413 kAgeLatin1);
414 EXPECT_EQ(6, FPDF_GetSecurityHandlerRevision(document()));
415 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
416 VerifySavedHelloWorldDocumentWithPassword(kAgeLatin1);
417 VerifySavedHelloWorldDocumentWithPassword(kAgeUTF8);
418 VerifySavedHelloWorldDocumentWithPassword(kHotelLatin1);
419 VerifySavedHelloWorldDocumentWithPassword(kHotelUTF8);
420
421 ClearString();
422 RemoveTrailerIdFromDocument();
423 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
424 VerifySavedHelloWorldDocumentWithPassword(kAgeLatin1);
425 VerifySavedHelloWorldDocumentWithPassword(kAgeUTF8);
426 VerifySavedHelloWorldDocumentWithPassword(kHotelLatin1);
427 VerifySavedHelloWorldDocumentWithPassword(kHotelUTF8);
428
429 ClearString();
430 RemoveGoodbyeObject();
431 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
432 VerifySavedModifiedHelloWorldDocumentWithPassword(kAgeLatin1);
433 VerifySavedModifiedHelloWorldDocumentWithPassword(kAgeUTF8);
434 VerifySavedModifiedHelloWorldDocumentWithPassword(kHotelLatin1);
435 VerifySavedModifiedHelloWorldDocumentWithPassword(kHotelUTF8);
436 }
437
TEST_F(CPDFSecurityHandlerEmbedderTest,UserPasswordVersion2UTF8)438 TEST_F(CPDFSecurityHandlerEmbedderTest, UserPasswordVersion2UTF8) {
439 // The password is "hotel", where the 'o' has a circumflex. Encoding the
440 // password as UTF-8 works.
441 OpenAndVerifyHelloWorldDocumentWithPassword("encrypted_hello_world_r2.pdf",
442 kHotelUTF8);
443 EXPECT_EQ(2, FPDF_GetSecurityHandlerRevision(document()));
444 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
445 VerifySavedHelloWorldDocumentWithPassword(kAgeLatin1);
446 VerifySavedHelloWorldDocumentWithPassword(kAgeUTF8);
447 VerifySavedHelloWorldDocumentWithPassword(kHotelLatin1);
448 VerifySavedHelloWorldDocumentWithPassword(kHotelUTF8);
449
450 ClearString();
451 RemoveTrailerIdFromDocument();
452 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
453 // Unlike the OwnerPasswordVersion2UTF8 test case, the user password was used
454 // to decrypt the document, so it is available to regenerated the user
455 // password entry. Thus it is possible to verify with both the unmodified
456 // owner password, and the updated user password.
457 VerifySavedHelloWorldDocumentWithPassword(kAgeLatin1);
458 VerifySavedHelloWorldDocumentWithPassword(kAgeUTF8);
459 VerifySavedHelloWorldDocumentWithPassword(kHotelLatin1);
460 VerifySavedHelloWorldDocumentWithPassword(kHotelUTF8);
461
462 ClearString();
463 RemoveGoodbyeObject();
464 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
465 VerifySavedModifiedHelloWorldDocumentWithPassword(kAgeLatin1);
466 VerifySavedModifiedHelloWorldDocumentWithPassword(kAgeUTF8);
467 VerifySavedModifiedHelloWorldDocumentWithPassword(kHotelLatin1);
468 VerifySavedModifiedHelloWorldDocumentWithPassword(kHotelUTF8);
469 }
470
TEST_F(CPDFSecurityHandlerEmbedderTest,UserPasswordVersion2Latin1)471 TEST_F(CPDFSecurityHandlerEmbedderTest, UserPasswordVersion2Latin1) {
472 // The same password encoded as Latin-1 also works at revision 2.
473 OpenAndVerifyHelloWorldDocumentWithPassword("encrypted_hello_world_r2.pdf",
474 kHotelLatin1);
475 EXPECT_EQ(2, FPDF_GetSecurityHandlerRevision(document()));
476 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
477 VerifySavedHelloWorldDocumentWithPassword(kAgeLatin1);
478 VerifySavedHelloWorldDocumentWithPassword(kAgeUTF8);
479 VerifySavedHelloWorldDocumentWithPassword(kHotelLatin1);
480 VerifySavedHelloWorldDocumentWithPassword(kHotelUTF8);
481
482 ClearString();
483 RemoveTrailerIdFromDocument();
484 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
485 VerifySavedHelloWorldDocumentWithPassword(kAgeLatin1);
486 VerifySavedHelloWorldDocumentWithPassword(kAgeUTF8);
487 VerifySavedHelloWorldDocumentWithPassword(kHotelLatin1);
488 VerifySavedHelloWorldDocumentWithPassword(kHotelUTF8);
489
490 ClearString();
491 RemoveGoodbyeObject();
492 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
493 VerifySavedModifiedHelloWorldDocumentWithPassword(kAgeLatin1);
494 VerifySavedModifiedHelloWorldDocumentWithPassword(kAgeUTF8);
495 VerifySavedModifiedHelloWorldDocumentWithPassword(kHotelLatin1);
496 VerifySavedModifiedHelloWorldDocumentWithPassword(kHotelUTF8);
497 }
498
TEST_F(CPDFSecurityHandlerEmbedderTest,UserPasswordVersion3UTF8)499 TEST_F(CPDFSecurityHandlerEmbedderTest, UserPasswordVersion3UTF8) {
500 // Same as UserPasswordVersion2UTF8 test above.
501 OpenAndVerifyHelloWorldDocumentWithPassword("encrypted_hello_world_r3.pdf",
502 kHotelUTF8);
503 EXPECT_EQ(3, FPDF_GetSecurityHandlerRevision(document()));
504 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
505 VerifySavedHelloWorldDocumentWithPassword(kAgeLatin1);
506 VerifySavedHelloWorldDocumentWithPassword(kAgeUTF8);
507 VerifySavedHelloWorldDocumentWithPassword(kHotelLatin1);
508 VerifySavedHelloWorldDocumentWithPassword(kHotelUTF8);
509
510 ClearString();
511 RemoveTrailerIdFromDocument();
512 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
513 VerifySavedHelloWorldDocumentWithPassword(kAgeLatin1);
514 VerifySavedHelloWorldDocumentWithPassword(kAgeUTF8);
515 VerifySavedHelloWorldDocumentWithPassword(kHotelLatin1);
516 VerifySavedHelloWorldDocumentWithPassword(kHotelUTF8);
517
518 ClearString();
519 RemoveGoodbyeObject();
520 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
521 VerifySavedModifiedHelloWorldDocumentWithPassword(kAgeLatin1);
522 VerifySavedModifiedHelloWorldDocumentWithPassword(kAgeUTF8);
523 VerifySavedModifiedHelloWorldDocumentWithPassword(kHotelLatin1);
524 VerifySavedModifiedHelloWorldDocumentWithPassword(kHotelUTF8);
525 }
526
TEST_F(CPDFSecurityHandlerEmbedderTest,UserPasswordVersion3Latin1)527 TEST_F(CPDFSecurityHandlerEmbedderTest, UserPasswordVersion3Latin1) {
528 // Same as UserPasswordVersion2Latin1 test above.
529 OpenAndVerifyHelloWorldDocumentWithPassword("encrypted_hello_world_r3.pdf",
530 kHotelLatin1);
531 EXPECT_EQ(3, FPDF_GetSecurityHandlerRevision(document()));
532 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
533 VerifySavedHelloWorldDocumentWithPassword(kAgeLatin1);
534 VerifySavedHelloWorldDocumentWithPassword(kAgeUTF8);
535 VerifySavedHelloWorldDocumentWithPassword(kHotelLatin1);
536 VerifySavedHelloWorldDocumentWithPassword(kHotelUTF8);
537
538 ClearString();
539 RemoveTrailerIdFromDocument();
540 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
541 VerifySavedHelloWorldDocumentWithPassword(kAgeLatin1);
542 VerifySavedHelloWorldDocumentWithPassword(kAgeUTF8);
543 VerifySavedHelloWorldDocumentWithPassword(kHotelLatin1);
544 VerifySavedHelloWorldDocumentWithPassword(kHotelUTF8);
545
546 ClearString();
547 RemoveGoodbyeObject();
548 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
549 VerifySavedModifiedHelloWorldDocumentWithPassword(kAgeLatin1);
550 VerifySavedModifiedHelloWorldDocumentWithPassword(kAgeUTF8);
551 VerifySavedModifiedHelloWorldDocumentWithPassword(kHotelLatin1);
552 VerifySavedModifiedHelloWorldDocumentWithPassword(kHotelUTF8);
553 }
554
TEST_F(CPDFSecurityHandlerEmbedderTest,UserPasswordVersion5UTF8)555 TEST_F(CPDFSecurityHandlerEmbedderTest, UserPasswordVersion5UTF8) {
556 // Same as UserPasswordVersion2UTF8 test above.
557 OpenAndVerifyHelloWorldDocumentWithPassword("encrypted_hello_world_r5.pdf",
558 kHotelUTF8);
559 EXPECT_EQ(5, FPDF_GetSecurityHandlerRevision(document()));
560 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
561 VerifySavedHelloWorldDocumentWithPassword(kAgeLatin1);
562 VerifySavedHelloWorldDocumentWithPassword(kAgeUTF8);
563 VerifySavedHelloWorldDocumentWithPassword(kHotelLatin1);
564 VerifySavedHelloWorldDocumentWithPassword(kHotelUTF8);
565
566 ClearString();
567 RemoveTrailerIdFromDocument();
568 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
569 VerifySavedHelloWorldDocumentWithPassword(kAgeLatin1);
570 VerifySavedHelloWorldDocumentWithPassword(kAgeUTF8);
571 VerifySavedHelloWorldDocumentWithPassword(kHotelLatin1);
572 VerifySavedHelloWorldDocumentWithPassword(kHotelUTF8);
573
574 ClearString();
575 RemoveGoodbyeObject();
576 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
577 VerifySavedModifiedHelloWorldDocumentWithPassword(kAgeLatin1);
578 VerifySavedModifiedHelloWorldDocumentWithPassword(kAgeUTF8);
579 VerifySavedModifiedHelloWorldDocumentWithPassword(kHotelLatin1);
580 VerifySavedModifiedHelloWorldDocumentWithPassword(kHotelUTF8);
581 }
582
TEST_F(CPDFSecurityHandlerEmbedderTest,UserPasswordVersion5Latin1)583 TEST_F(CPDFSecurityHandlerEmbedderTest, UserPasswordVersion5Latin1) {
584 // Same as UserPasswordVersion2Latin1 test above.
585 OpenAndVerifyHelloWorldDocumentWithPassword("encrypted_hello_world_r5.pdf",
586 kHotelLatin1);
587 EXPECT_EQ(5, FPDF_GetSecurityHandlerRevision(document()));
588 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
589 VerifySavedHelloWorldDocumentWithPassword(kAgeLatin1);
590 VerifySavedHelloWorldDocumentWithPassword(kAgeUTF8);
591 VerifySavedHelloWorldDocumentWithPassword(kHotelLatin1);
592 VerifySavedHelloWorldDocumentWithPassword(kHotelUTF8);
593
594 ClearString();
595 RemoveTrailerIdFromDocument();
596 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
597 VerifySavedHelloWorldDocumentWithPassword(kAgeLatin1);
598 VerifySavedHelloWorldDocumentWithPassword(kAgeUTF8);
599 VerifySavedHelloWorldDocumentWithPassword(kHotelLatin1);
600 VerifySavedHelloWorldDocumentWithPassword(kHotelUTF8);
601
602 ClearString();
603 RemoveGoodbyeObject();
604 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
605 VerifySavedModifiedHelloWorldDocumentWithPassword(kAgeLatin1);
606 VerifySavedModifiedHelloWorldDocumentWithPassword(kAgeUTF8);
607 VerifySavedModifiedHelloWorldDocumentWithPassword(kHotelLatin1);
608 VerifySavedModifiedHelloWorldDocumentWithPassword(kHotelUTF8);
609 }
610
TEST_F(CPDFSecurityHandlerEmbedderTest,UserPasswordVersion6UTF8)611 TEST_F(CPDFSecurityHandlerEmbedderTest, UserPasswordVersion6UTF8) {
612 // Same as UserPasswordVersion2UTF8 test above.
613 OpenAndVerifyHelloWorldDocumentWithPassword("encrypted_hello_world_r6.pdf",
614 kHotelUTF8);
615 EXPECT_EQ(6, FPDF_GetSecurityHandlerRevision(document()));
616 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
617 VerifySavedHelloWorldDocumentWithPassword(kAgeLatin1);
618 VerifySavedHelloWorldDocumentWithPassword(kAgeUTF8);
619 VerifySavedHelloWorldDocumentWithPassword(kHotelLatin1);
620 VerifySavedHelloWorldDocumentWithPassword(kHotelUTF8);
621
622 ClearString();
623 RemoveTrailerIdFromDocument();
624 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
625 VerifySavedHelloWorldDocumentWithPassword(kAgeLatin1);
626 VerifySavedHelloWorldDocumentWithPassword(kAgeUTF8);
627 VerifySavedHelloWorldDocumentWithPassword(kHotelLatin1);
628 VerifySavedHelloWorldDocumentWithPassword(kHotelUTF8);
629
630 ClearString();
631 RemoveGoodbyeObject();
632 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
633 VerifySavedModifiedHelloWorldDocumentWithPassword(kAgeLatin1);
634 VerifySavedModifiedHelloWorldDocumentWithPassword(kAgeUTF8);
635 VerifySavedModifiedHelloWorldDocumentWithPassword(kHotelLatin1);
636 VerifySavedModifiedHelloWorldDocumentWithPassword(kHotelUTF8);
637 }
638
TEST_F(CPDFSecurityHandlerEmbedderTest,UserPasswordVersion6Latin1)639 TEST_F(CPDFSecurityHandlerEmbedderTest, UserPasswordVersion6Latin1) {
640 // Same as UserPasswordVersion2Latin1 test above.
641 OpenAndVerifyHelloWorldDocumentWithPassword("encrypted_hello_world_r6.pdf",
642 kHotelLatin1);
643 EXPECT_EQ(6, FPDF_GetSecurityHandlerRevision(document()));
644 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
645 VerifySavedHelloWorldDocumentWithPassword(kAgeLatin1);
646 VerifySavedHelloWorldDocumentWithPassword(kAgeUTF8);
647 VerifySavedHelloWorldDocumentWithPassword(kHotelLatin1);
648 VerifySavedHelloWorldDocumentWithPassword(kHotelUTF8);
649
650 ClearString();
651 RemoveTrailerIdFromDocument();
652 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
653 VerifySavedHelloWorldDocumentWithPassword(kAgeLatin1);
654 VerifySavedHelloWorldDocumentWithPassword(kAgeUTF8);
655 VerifySavedHelloWorldDocumentWithPassword(kHotelLatin1);
656 VerifySavedHelloWorldDocumentWithPassword(kHotelUTF8);
657
658 ClearString();
659 RemoveGoodbyeObject();
660 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
661 VerifySavedModifiedHelloWorldDocumentWithPassword(kAgeLatin1);
662 VerifySavedModifiedHelloWorldDocumentWithPassword(kAgeUTF8);
663 VerifySavedModifiedHelloWorldDocumentWithPassword(kHotelLatin1);
664 VerifySavedModifiedHelloWorldDocumentWithPassword(kHotelUTF8);
665 }
666
TEST_F(CPDFSecurityHandlerEmbedderTest,Bug1124998)667 TEST_F(CPDFSecurityHandlerEmbedderTest, Bug1124998) {
668 OpenAndVerifyHelloWorldDocumentWithPassword("bug_1124998.pdf", "test");
669 }
670