mirror of
https://github.com/qpdf/qpdf.git
synced 2024-06-03 19:00:51 +00:00
Allow /P in encryption dictionary to be positive (fixes #382)
Even though this is disallowed by the spec, files like this have been encountered in the wild.
This commit is contained in:
parent
b997fa5343
commit
5508f74603
11
ChangeLog
11
ChangeLog
|
@ -1,3 +1,14 @@
|
||||||
|
2019-11-09 Jay Berkenbilt <ejb@ql.org>
|
||||||
|
|
||||||
|
* When reading /P from the encryption dictionary, use static_cast
|
||||||
|
instead of QIntC to convert the value to a signed integer. The
|
||||||
|
value of /P is a bit field, and PDF files have been found in the
|
||||||
|
wild where /P is represented as an unsigned integer even though
|
||||||
|
the spec states that it is a signed 32-bit value. By using
|
||||||
|
static_cast, we allow qpdf to compensate for writers that
|
||||||
|
incorrectly represent the correct bit field as an unsigned value.
|
||||||
|
Fixes #382.
|
||||||
|
|
||||||
2019-11-05 Jay Berkenbilt <ejb@ql.org>
|
2019-11-05 Jay Berkenbilt <ejb@ql.org>
|
||||||
|
|
||||||
* Add support for pluggable crypto providers, enabling multiple
|
* Add support for pluggable crypto providers, enabling multiple
|
||||||
|
|
|
@ -661,6 +661,7 @@ QPDFPageObjectHelper::getFormXObjectForPage(bool handle_transformations)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ABI: name should be std:string const&
|
||||||
std::string
|
std::string
|
||||||
QPDFPageObjectHelper::placeFormXObject(
|
QPDFPageObjectHelper::placeFormXObject(
|
||||||
QPDFObjectHandle fo, std::string name,
|
QPDFObjectHandle fo, std::string name,
|
||||||
|
|
|
@ -762,7 +762,7 @@ QPDFWriter::copyEncryptionParameters(QPDF& qpdf)
|
||||||
V,
|
V,
|
||||||
encrypt.getKey("/R").getIntValueAsInt(),
|
encrypt.getKey("/R").getIntValueAsInt(),
|
||||||
key_len,
|
key_len,
|
||||||
encrypt.getKey("/P").getIntValueAsInt(),
|
static_cast<int>(encrypt.getKey("/P").getIntValue()),
|
||||||
encrypt.getKey("/O").getStringValue(),
|
encrypt.getKey("/O").getStringValue(),
|
||||||
encrypt.getKey("/U").getStringValue(),
|
encrypt.getKey("/U").getStringValue(),
|
||||||
OE,
|
OE,
|
||||||
|
|
|
@ -877,7 +877,7 @@ QPDF::initializeEncryption()
|
||||||
int R = encryption_dict.getKey("/R").getIntValueAsInt();
|
int R = encryption_dict.getKey("/R").getIntValueAsInt();
|
||||||
std::string O = encryption_dict.getKey("/O").getStringValue();
|
std::string O = encryption_dict.getKey("/O").getStringValue();
|
||||||
std::string U = encryption_dict.getKey("/U").getStringValue();
|
std::string U = encryption_dict.getKey("/U").getStringValue();
|
||||||
int P = encryption_dict.getKey("/P").getIntValueAsInt();
|
int P = static_cast<int>(encryption_dict.getKey("/P").getIntValue());
|
||||||
|
|
||||||
// If supporting new encryption R/V values, remember to update
|
// If supporting new encryption R/V values, remember to update
|
||||||
// error message inside this if statement.
|
// error message inside this if statement.
|
||||||
|
@ -1448,7 +1448,7 @@ QPDF::isEncrypted(int& R, int& P, int& V,
|
||||||
QPDFObjectHandle Pkey = encrypt.getKey("/P");
|
QPDFObjectHandle Pkey = encrypt.getKey("/P");
|
||||||
QPDFObjectHandle Rkey = encrypt.getKey("/R");
|
QPDFObjectHandle Rkey = encrypt.getKey("/R");
|
||||||
QPDFObjectHandle Vkey = encrypt.getKey("/V");
|
QPDFObjectHandle Vkey = encrypt.getKey("/V");
|
||||||
P = Pkey.getIntValueAsInt();
|
P = static_cast<int>(Pkey.getIntValue());
|
||||||
R = Rkey.getIntValueAsInt();
|
R = Rkey.getIntValueAsInt();
|
||||||
V = Vkey.getIntValueAsInt();
|
V = Vkey.getIntValueAsInt();
|
||||||
stream_method = this->m->encp->cf_stream;
|
stream_method = this->m->encp->cf_stream;
|
||||||
|
|
|
@ -719,6 +719,32 @@ foreach my $d (@bug_tests)
|
||||||
$td->NORMALIZE_NEWLINES);
|
$td->NORMALIZE_NEWLINES);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
show_ntests();
|
||||||
|
# ----------
|
||||||
|
$td->notify("--- Positive /P in encryption dictionary ---");
|
||||||
|
$n_tests += 4;
|
||||||
|
|
||||||
|
# Files have been seen where /P in the encryption dictionary was an
|
||||||
|
# unsigned rather than a signed integer. To create
|
||||||
|
# encrypted-positive-P.pdf, I temporarily modified QPDFWriter.cc to
|
||||||
|
# introduce this error.
|
||||||
|
|
||||||
|
$td->runtest("decrypt positive P",
|
||||||
|
{$td->COMMAND =>
|
||||||
|
"qpdf --decrypt --static-id encrypted-positive-P.pdf a.pdf"},
|
||||||
|
{$td->STRING => "", $td->EXIT_STATUS => 0});
|
||||||
|
$td->runtest("check output",
|
||||||
|
{$td->FILE => "a.pdf"},
|
||||||
|
{$td->FILE => "decrypted-positive-P.pdf"});
|
||||||
|
$td->runtest("copy encryption positive P",
|
||||||
|
{$td->COMMAND =>
|
||||||
|
"qpdf --static-id --static-aes-iv" .
|
||||||
|
" encrypted-positive-P.pdf a.pdf"},
|
||||||
|
{$td->STRING => "", $td->EXIT_STATUS => 0});
|
||||||
|
$td->runtest("check output",
|
||||||
|
{$td->FILE => "a.pdf"},
|
||||||
|
{$td->FILE => "copied-positive-P.pdf"});
|
||||||
|
|
||||||
show_ntests();
|
show_ntests();
|
||||||
# ----------
|
# ----------
|
||||||
$td->notify("--- Library version ---");
|
$td->notify("--- Library version ---");
|
||||||
|
|
BIN
qpdf/qtest/qpdf/copied-positive-P.pdf
Normal file
BIN
qpdf/qtest/qpdf/copied-positive-P.pdf
Normal file
Binary file not shown.
BIN
qpdf/qtest/qpdf/decrypted-positive-P.pdf
Normal file
BIN
qpdf/qtest/qpdf/decrypted-positive-P.pdf
Normal file
Binary file not shown.
39
qpdf/qtest/qpdf/encrypted-positive-P.pdf
Normal file
39
qpdf/qtest/qpdf/encrypted-positive-P.pdf
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
%PDF-1.7
|
||||||
|
%¿÷¢þ
|
||||||
|
1 0 obj
|
||||||
|
<< /Extensions << /ADBE << /BaseVersion /1.7 /ExtensionLevel 8 >> >> /Pages 2 0 R /Type /Catalog >>
|
||||||
|
endobj
|
||||||
|
2 0 obj
|
||||||
|
<< /Count 1 /Kids [ 3 0 R ] /Type /Pages >>
|
||||||
|
endobj
|
||||||
|
3 0 obj
|
||||||
|
<< /Contents 4 0 R /MediaBox [ 0 0 612 792 ] /Parent 2 0 R /Resources << /Font << /F1 5 0 R >> /ProcSet 6 0 R >> /Type /Page >>
|
||||||
|
endobj
|
||||||
|
4 0 obj
|
||||||
|
<< /Length 80 /Filter /FlateDecode >>
|
||||||
|
stream
|
||||||
|
P옃©ƒÐŸuÊ@BÆL$Üõ:je^~[Èj};C„ñÊ5<>Ì£¬\̉×.¯Ôú(<28>”do¤ÕFá
´G“çï±*C5{‘ÖkÓxQ±endstream
|
||||||
|
endobj
|
||||||
|
5 0 obj
|
||||||
|
<< /BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font >>
|
||||||
|
endobj
|
||||||
|
6 0 obj
|
||||||
|
[ /PDF /Text ]
|
||||||
|
endobj
|
||||||
|
7 0 obj
|
||||||
|
<< /CF << /StdCF << /AuthEvent /DocOpen /CFM /AESV3 /Length 32 >> >> /Filter /Standard /Length 256 /O <1b7cc50a8bd7d4220be2b990df3a3f82bf54a9596ea0d3f0fe308a62a496d7f2853cb41fd7e8f2adfee08f045f4579b0> /OE <968299e6df135ce14da318e851103f18c263082e6ae1380fcbf26e910cef551b> /P 4294967292 /Perms <afb6ec9c6b9c3e8c2fbdcb9c4f391a1d> /R 6 /StmF /StdCF /StrF /StdCF /U <16d19f98d4d5144f6e68ec10294e3789d8eab6a8eb6de68231d749c198904a004b8a16d4ceb3553204d16feae9d1b819> /UE <80044f0bc684a6675f129a0cb8a6ed6efa33d890a6195963a75e8b3876ded541> /V 5 >>
|
||||||
|
endobj
|
||||||
|
xref
|
||||||
|
0 8
|
||||||
|
0000000000 65535 f
|
||||||
|
0000000015 00000 n
|
||||||
|
0000000130 00000 n
|
||||||
|
0000000189 00000 n
|
||||||
|
0000000332 00000 n
|
||||||
|
0000000482 00000 n
|
||||||
|
0000000589 00000 n
|
||||||
|
0000000619 00000 n
|
||||||
|
trailer << /Root 1 0 R /Size 8 /ID [<7aed6705f40de848cd4f3ea12c672f33><7aed6705f40de848cd4f3ea12c672f33>] /Encrypt 7 0 R >>
|
||||||
|
startxref
|
||||||
|
1174
|
||||||
|
%%EOF
|
Loading…
Reference in New Issue
Block a user