Skip to content

Commit 9b34037

Browse files
authored
bug: pdfs might have padded us. didnt consider that wonderful option (#306)
1 parent 7a9ea7c commit 9b34037

File tree

5 files changed

+89
-1
lines changed

5 files changed

+89
-1
lines changed

PDFWriter/DecryptionHelper.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,13 +150,21 @@ EStatusCode DecryptionHelper::Setup(PDFParser* inParser, const string& inPasswor
150150
mRevision = (unsigned int)revisionHelper.GetAsInteger();
151151
}
152152

153+
size_t ouLength = mRevision <= 4 ? 32 : 48; // R <= 4 is 32 bytes, R >= 5 is 48 bytes
154+
size_t oEuELength = 32;
155+
153156
RefCountPtr<PDFObject> o(inParser->QueryDictionaryObject(encryptionDictionary.GetPtr(), "O"));
154157
if (!o) {
155158
break;
156159
}
157160
else {
158161
ParsedPrimitiveHelper oHelper(o.GetPtr());
159162
mO = stringToByteList(oHelper.ToString());
163+
if(mO.size() > ouLength) {
164+
// some wiseasses might use longer value then expected and this causes trouble with auth. trim.
165+
mO = substr(mO, 0, ouLength);
166+
}
167+
160168
}
161169

162170
RefCountPtr<PDFObject> u(inParser->QueryDictionaryObject(encryptionDictionary.GetPtr(), "U"));
@@ -166,6 +174,10 @@ EStatusCode DecryptionHelper::Setup(PDFParser* inParser, const string& inPasswor
166174
else {
167175
ParsedPrimitiveHelper uHelper(u.GetPtr());
168176
mU = stringToByteList(uHelper.ToString());
177+
if(mU.size() > ouLength) {
178+
mU = substr(mU, 0, ouLength);
179+
}
180+
169181
}
170182

171183
RefCountPtr<PDFObject> oE(inParser->QueryDictionaryObject(encryptionDictionary.GetPtr(), "OE"));
@@ -178,6 +190,9 @@ EStatusCode DecryptionHelper::Setup(PDFParser* inParser, const string& inPasswor
178190
else {
179191
ParsedPrimitiveHelper oEHelper(oE.GetPtr());
180192
mOE = stringToByteList(oEHelper.ToString());
193+
if(mOE.size() > oEuELength) {
194+
mOE = substr(mOE, 0, oEuELength);
195+
}
181196
}
182197

183198
RefCountPtr<PDFObject> uE(inParser->QueryDictionaryObject(encryptionDictionary.GetPtr(), "UE"));
@@ -189,6 +204,9 @@ EStatusCode DecryptionHelper::Setup(PDFParser* inParser, const string& inPasswor
189204
} else {
190205
ParsedPrimitiveHelper uEHelper(uE.GetPtr());
191206
mUE = stringToByteList(uEHelper.ToString());
207+
if(mUE.size() > oEuELength) {
208+
mUE = substr(mUE, 0, oEuELength);
209+
}
192210
}
193211

194212
RefCountPtr<PDFObject> perms(inParser->QueryDictionaryObject(encryptionDictionary.GetPtr(), "Perms"));

PDFWriterTesting/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ create_test_sourcelist (Tests
4545
OutputFileStreamTest.cpp
4646
PageModifierTest.cpp
4747
PageOrderModification.cpp
48+
ParsePDFWithOwner.cpp
4849
ParsingBadXref.cpp
4950
ParsingFaulty.cpp
5051
PDFCopyingContextTest.cpp
5.4 KB
Binary file not shown.
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#include "PDFParser.h"
2+
#include "EStatusCode.h"
3+
#include "InputFile.h"
4+
#include "RefCountPtr.h"
5+
#include "PDFDictionary.h"
6+
7+
#include <iostream>
8+
9+
#include "testing/TestIO.h"
10+
11+
using namespace PDFHummus;
12+
13+
int ParsePDFWithOwner(int argc, char* argv[])
14+
{
15+
int pIndex = 0;
16+
EStatusCode status;
17+
PDFParser parser;
18+
19+
do
20+
{
21+
InputFile pdfFile;
22+
status = pdfFile.OpenFile(BuildRelativeInputPath(argv, "password.pdf"));
23+
if(status != eSuccess)
24+
{
25+
cout<<"unable to open file for reading. should be in TestMaterials/password.pdf\n";
26+
break;
27+
}
28+
29+
status = parser.StartPDFParsing(pdfFile.GetInputStream(), PDFParsingOptions("000000"));
30+
if(status != PDFHummus::eSuccess)
31+
{
32+
cout<<"unable to parse input file";
33+
break;
34+
}
35+
36+
if(!parser.IsEncryptionSupported()) {
37+
cout<<"PDFParser does not support encryption, cannot continue\n";
38+
status = PDFHummus::eFailure;
39+
break;
40+
}
41+
42+
RefCountPtr<PDFDictionary> pageDict(parser.ParsePage(pIndex));
43+
if(pageDict.GetPtr() == NULL)
44+
{
45+
cout<<"unable to parse page "<<pIndex<<"\n";
46+
status = PDFHummus::eFailure;
47+
break;
48+
}
49+
}while(false);
50+
51+
52+
return status == eSuccess ? 0:1;
53+
54+
55+
}

PDFWriterTesting/RecryptPDF.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,21 @@ int RecryptPDF(int argc, char* argv[])
7070
{
7171
cout << "failed to decrypt PDF2.0\n";
7272
break;
73-
}
73+
}
74+
75+
// again with the owner password
76+
status = PDFWriter::RecryptPDF(
77+
BuildRelativeInputPath(argv,"PDFWithPassword20.pdf"),
78+
"owner",
79+
BuildRelativeOutputPath(argv,"RecryptPDFWithPasswordToNothingOwnerPDF20.pdf"),
80+
LogConfiguration::DefaultLogConfiguration(),
81+
PDFCreationSettings(true, true),
82+
ePDFVersion20);
83+
if (status != PDFHummus::eSuccess)
84+
{
85+
cout << "failed to decrypt PDF2.0 with owner password\n";
86+
break;
87+
}
7488
#endif
7589

7690
// recrypt an encrypted document with new password

0 commit comments

Comments
 (0)