• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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