summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2012-12-31 12:47:11 +0100
committerJay Berkenbilt <ejb@ql.org>2012-12-31 16:32:32 +0100
commitf8306913ba6eb751cd7f408d04f2d65d8cd3b341 (patch)
treec4d978d832aeeb0cbd82368694335b5d3046c9fa
parent9eb5982fa334a2db42a278fce853bd7ebd2a61a7 (diff)
downloadqpdf-f8306913ba6eb751cd7f408d04f2d65d8cd3b341.tar.zst
Update "C" API with functions for new features
-rw-r--r--ChangeLog9
-rw-r--r--include/qpdf/qpdf-c.h26
-rw-r--r--libqpdf/qpdf-c.cc48
-rw-r--r--qpdf/qpdf-ctest.c40
-rw-r--r--qpdf/qpdf.testcov3
-rw-r--r--qpdf/qtest/qpdf.test47
-rw-r--r--qpdf/qtest/qpdf/c-decrypt-R5-with-user.pdfbin0 -> 9731 bytes
-rw-r--r--qpdf/qtest/qpdf/c-decrypt-R6-with-owner.pdfbin0 -> 9731 bytes
-rw-r--r--qpdf/qtest/qpdf/c-min-version.out4
-rw-r--r--qpdf/qtest/qpdf/c-r5-in.pdfbin0 -> 11195 bytes
-rw-r--r--qpdf/qtest/qpdf/c-r5.out20
-rw-r--r--qpdf/qtest/qpdf/c-r6-in.pdfbin0 -> 11195 bytes
-rw-r--r--qpdf/qtest/qpdf/c-r6.out20
13 files changed, 202 insertions, 15 deletions
diff --git a/ChangeLog b/ChangeLog
index c85b27a5..c68c4ceb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2012-12-31 Jay Berkenbilt <ejb@ql.org>
+
+ * Add new methods qpdf_get_pdf_extension_level,
+ qpdf_set_r5_encryption_parameters,
+ qpdf_set_r6_encryption_parameters,
+ qpdf_set_minimum_pdf_version_and_extension, and
+ qpdf_force_pdf_version_and_extension to support new functionality
+ from the C API.
+
2012-12-30 Jay Berkenbilt <ejb@ql.org>
* Fix long-standing bug that could theoretically have resulted in
diff --git a/include/qpdf/qpdf-c.h b/include/qpdf/qpdf-c.h
index 57100839..ee4fa58c 100644
--- a/include/qpdf/qpdf-c.h
+++ b/include/qpdf/qpdf-c.h
@@ -213,6 +213,10 @@ extern "C" {
QPDF_DLL
char const* qpdf_get_pdf_version(qpdf_data qpdf);
+ /* Return the extension level of the PDF file. */
+ QPDF_DLL
+ int qpdf_get_pdf_extension_level(qpdf_data qpdf);
+
/* Return the user password. If the file is opened using the
* owner password, the user password may be retrieved using this
* function. If the file is opened using the user password, this
@@ -359,14 +363,36 @@ extern "C" {
QPDF_BOOL encrypt_metadata, QPDF_BOOL use_aes);
QPDF_DLL
+ void qpdf_set_r5_encryption_parameters(
+ qpdf_data qpdf, char const* user_password, char const* owner_password,
+ QPDF_BOOL allow_accessibility, QPDF_BOOL allow_extract,
+ enum qpdf_r3_print_e print, enum qpdf_r3_modify_e modify,
+ QPDF_BOOL encrypt_metadata);
+
+ QPDF_DLL
+ void qpdf_set_r6_encryption_parameters(
+ qpdf_data qpdf, char const* user_password, char const* owner_password,
+ QPDF_BOOL allow_accessibility, QPDF_BOOL allow_extract,
+ enum qpdf_r3_print_e print, enum qpdf_r3_modify_e modify,
+ QPDF_BOOL encrypt_metadata);
+
+ QPDF_DLL
void qpdf_set_linearization(qpdf_data qpdf, QPDF_BOOL value);
QPDF_DLL
void qpdf_set_minimum_pdf_version(qpdf_data qpdf, char const* version);
QPDF_DLL
+ void qpdf_set_minimum_pdf_version_and_extension(
+ qpdf_data qpdf, char const* version, int extension_level);
+
+ QPDF_DLL
void qpdf_force_pdf_version(qpdf_data qpdf, char const* version);
+ QPDF_DLL
+ void qpdf_force_pdf_version_and_extension(
+ qpdf_data qpdf, char const* version, int extension_level);
+
/* Do actual write operation. */
QPDF_DLL
QPDF_ERROR_CODE qpdf_write(qpdf_data qpdf);
diff --git a/libqpdf/qpdf-c.cc b/libqpdf/qpdf-c.cc
index 0312ae50..a46df63e 100644
--- a/libqpdf/qpdf-c.cc
+++ b/libqpdf/qpdf-c.cc
@@ -288,6 +288,12 @@ char const* qpdf_get_pdf_version(qpdf_data qpdf)
return qpdf->tmp_string.c_str();
}
+int qpdf_get_pdf_extension_level(qpdf_data qpdf)
+{
+ QTC::TC("qpdf", "qpdf-c called qpdf_get_pdf_extension_level");
+ return qpdf->qpdf->getExtensionLevel();
+}
+
char const* qpdf_get_user_password(qpdf_data qpdf)
{
QTC::TC("qpdf", "qpdf-c called qpdf_get_user_password");
@@ -566,6 +572,32 @@ void qpdf_set_r4_encryption_parameters(
encrypt_metadata, use_aes);
}
+void qpdf_set_r5_encryption_parameters(
+ qpdf_data qpdf, char const* user_password, char const* owner_password,
+ QPDF_BOOL allow_accessibility, QPDF_BOOL allow_extract,
+ qpdf_r3_print_e print, qpdf_r3_modify_e modify,
+ QPDF_BOOL encrypt_metadata)
+{
+ QTC::TC("qpdf", "qpdf-c called qpdf_set_r5_encryption_parameters");
+ qpdf->qpdf_writer->setR5EncryptionParameters(
+ user_password, owner_password,
+ allow_accessibility, allow_extract, print, modify,
+ encrypt_metadata);
+}
+
+void qpdf_set_r6_encryption_parameters(
+ qpdf_data qpdf, char const* user_password, char const* owner_password,
+ QPDF_BOOL allow_accessibility, QPDF_BOOL allow_extract,
+ qpdf_r3_print_e print, qpdf_r3_modify_e modify,
+ QPDF_BOOL encrypt_metadata)
+{
+ QTC::TC("qpdf", "qpdf-c called qpdf_set_r6_encryption_parameters");
+ qpdf->qpdf_writer->setR6EncryptionParameters(
+ user_password, owner_password,
+ allow_accessibility, allow_extract, print, modify,
+ encrypt_metadata);
+}
+
void qpdf_set_linearization(qpdf_data qpdf, QPDF_BOOL value)
{
QTC::TC("qpdf", "qpdf-c called qpdf_set_linearization");
@@ -574,14 +606,26 @@ void qpdf_set_linearization(qpdf_data qpdf, QPDF_BOOL value)
void qpdf_set_minimum_pdf_version(qpdf_data qpdf, char const* version)
{
+ qpdf_set_minimum_pdf_version_and_extension(qpdf, version, 0);
+}
+
+void qpdf_set_minimum_pdf_version_and_extension(
+ qpdf_data qpdf, char const* version, int extension_level)
+{
QTC::TC("qpdf", "qpdf-c called qpdf_set_minimum_pdf_version");
- qpdf->qpdf_writer->setMinimumPDFVersion(version);
+ qpdf->qpdf_writer->setMinimumPDFVersion(version, extension_level);
}
void qpdf_force_pdf_version(qpdf_data qpdf, char const* version)
{
+ qpdf_force_pdf_version_and_extension(qpdf, version, 0);
+}
+
+void qpdf_force_pdf_version_and_extension(
+ qpdf_data qpdf, char const* version, int extension_level)
+{
QTC::TC("qpdf", "qpdf-c called qpdf_force_pdf_version");
- qpdf->qpdf_writer->forcePDFVersion(version);
+ qpdf->qpdf_writer->forcePDFVersion(version, extension_level);
}
QPDF_ERROR_CODE qpdf_write(qpdf_data qpdf)
diff --git a/qpdf/qpdf-ctest.c b/qpdf/qpdf-ctest.c
index 072e5a7c..58fcb002 100644
--- a/qpdf/qpdf-ctest.c
+++ b/qpdf/qpdf-ctest.c
@@ -106,6 +106,10 @@ static void test01(char const* infile,
{
qpdf_read(qpdf, infile, password);
printf("version: %s\n", qpdf_get_pdf_version(qpdf));
+ if (qpdf_get_pdf_extension_level(qpdf) > 0)
+ {
+ printf("extension level: %d\n", qpdf_get_pdf_extension_level(qpdf));
+ }
printf("linearized: %d\n", qpdf_is_linearized(qpdf));
printf("encrypted: %d\n", qpdf_is_encrypted(qpdf));
if (qpdf_is_encrypted(qpdf))
@@ -304,7 +308,7 @@ static void test14(char const* infile,
qpdf_read(qpdf, infile, password);
qpdf_init_write(qpdf, outfile);
qpdf_set_static_ID(qpdf, QPDF_TRUE);
- qpdf_set_minimum_pdf_version(qpdf, "1.6");
+ qpdf_set_minimum_pdf_version_and_extension(qpdf, "1.7", 8);
qpdf_write(qpdf);
qpdf_init_write(qpdf, outfile2);
qpdf_set_static_ID(qpdf, QPDF_TRUE);
@@ -374,6 +378,38 @@ static void test16(char const* infile,
report_errors();
}
+static void test17(char const* infile,
+ char const* password,
+ char const* outfile,
+ char const* outfile2)
+{
+ qpdf_read(qpdf, infile, password);
+ qpdf_init_write(qpdf, outfile);
+ qpdf_set_static_ID(qpdf, QPDF_TRUE);
+ qpdf_set_static_aes_IV(qpdf, QPDF_TRUE);
+ qpdf_set_r5_encryption_parameters(
+ qpdf, "user3", "owner3", QPDF_TRUE, QPDF_TRUE,
+ qpdf_r3p_low, qpdf_r3m_all, QPDF_TRUE);
+ qpdf_write(qpdf);
+ report_errors();
+}
+
+static void test18(char const* infile,
+ char const* password,
+ char const* outfile,
+ char const* outfile2)
+{
+ qpdf_read(qpdf, infile, password);
+ qpdf_init_write(qpdf, outfile);
+ qpdf_set_static_ID(qpdf, QPDF_TRUE);
+ qpdf_set_static_aes_IV(qpdf, QPDF_TRUE);
+ qpdf_set_r6_encryption_parameters(
+ qpdf, "user4", "owner4", QPDF_TRUE, QPDF_TRUE,
+ qpdf_r3p_low, qpdf_r3m_all, QPDF_TRUE);
+ qpdf_write(qpdf);
+ report_errors();
+}
+
int main(int argc, char* argv[])
{
char* p = 0;
@@ -430,6 +466,8 @@ int main(int argc, char* argv[])
(n == 14) ? test14 :
(n == 15) ? test15 :
(n == 16) ? test16 :
+ (n == 17) ? test17 :
+ (n == 18) ? test18 :
0);
if (fn == 0)
diff --git a/qpdf/qpdf.testcov b/qpdf/qpdf.testcov
index 0263f312..a0578f28 100644
--- a/qpdf/qpdf.testcov
+++ b/qpdf/qpdf.testcov
@@ -256,3 +256,6 @@ QPDF_encryption skip 0x28 0
QPDF_encrypt crypt array 0
QPDF_encryption CFM AESV3 0
QPDFWriter remove Crypt 0
+qpdf-c called qpdf_get_pdf_extension_level 0
+qpdf-c called qpdf_set_r5_encryption_parameters 0
+qpdf-c called qpdf_set_r6_encryption_parameters 0
diff --git a/qpdf/qtest/qpdf.test b/qpdf/qtest/qpdf.test
index 0e164be7..bf62ceea 100644
--- a/qpdf/qtest/qpdf.test
+++ b/qpdf/qtest/qpdf.test
@@ -315,8 +315,8 @@ $td->runtest("C API: min/force versions",
$td->EXIT_STATUS => 0},
$td->NORMALIZE_NEWLINES);
$td->runtest("C check version 1",
- {$td->COMMAND => "qpdf --check a.pdf"},
- {$td->FILE => "min-version.out",
+ {$td->COMMAND => "qpdf-ctest 1 a.pdf '' ''"},
+ {$td->FILE => "c-min-version.out",
$td->EXIT_STATUS => 0},
$td->NORMALIZE_NEWLINES);
$td->runtest("C check version 2",
@@ -1472,29 +1472,52 @@ $td->runtest("C API: invalid password",
$td->NORMALIZE_NEWLINES);
my @cenc = (
- [11, 'hybrid-xref.pdf', "''", 'r2', ""],
- [12, 'hybrid-xref.pdf', "''", 'r3', ""],
- [15, 'hybrid-xref.pdf', "''", 'r4', ""],
+ [11, 'hybrid-xref.pdf', "''", 'r2', "", ""],
+ [12, 'hybrid-xref.pdf', "''", 'r3', "", ""],
+ [15, 'hybrid-xref.pdf', "''", 'r4', "", ""],
+ [17, 'hybrid-xref.pdf', "''", 'r5', "", "owner3"],
+ [18, 'hybrid-xref.pdf', "''", 'r6', "", "user4"],
[13, 'c-r2.pdf', 'user1', 'decrypt with user',
- "user password: user1\n"],
+ "user password: user1\n", ""],
[13, 'c-r3.pdf', 'owner2', 'decrypt with owner',
- "user password: user2\n"],
+ "user password: user2\n", ""],
+ [13, 'c-r5-in.pdf', 'user3', 'decrypt R5 with user',
+ "user password: user3\n", ""],
+ [13, 'c-r6-in.pdf', 'owner4', 'decrypt R6 with owner',
+ "user password: \n", ""],
);
$n_tests += 2 * @cenc;
foreach my $d (@cenc)
{
- my ($n, $infile, $pass, $description, $output) = @$d;
+ my ($n, $infile, $pass, $description, $output, $checkpass) = @$d;
my $outfile = $description;
$outfile =~ s/ /-/g;
- $outfile = "c-$outfile.pdf";
+ my $pdf_outfile = "c-$outfile.pdf";
+ my $check_outfile = "c-$outfile.out";
$td->runtest("C API encryption: $description",
{$td->COMMAND => "qpdf-ctest $n $infile $pass a.pdf"},
{$td->STRING => $output, $td->EXIT_STATUS => 0},
$td->NORMALIZE_NEWLINES);
- $td->runtest("check $description",
- {$td->FILE => "a.pdf"},
- {$td->FILE => $outfile});
+ if (-f $pdf_outfile)
+ {
+ $td->runtest("check $description content",
+ {$td->FILE => "a.pdf"},
+ {$td->FILE => $pdf_outfile});
+ }
+ else
+ {
+ # QPDF doesn't provide any way to make the random bits in
+ # /Perms static, so we have no way to predictably create a
+ # /V=5 encrypted file. It's not worth adding this...the test
+ # suite is adequate without having a statically predictable
+ # file.
+ $td->runtest("check $description",
+ {$td->COMMAND =>
+ "qpdf --check a.pdf --password=$checkpass"},
+ {$td->FILE => $check_outfile, $td->EXIT_STATUS => 0},
+ $td->NORMALIZE_NEWLINES);
+ }
}
# Test combinations of linearization and encryption. Note that we do
diff --git a/qpdf/qtest/qpdf/c-decrypt-R5-with-user.pdf b/qpdf/qtest/qpdf/c-decrypt-R5-with-user.pdf
new file mode 100644
index 00000000..e3ff67ee
--- /dev/null
+++ b/qpdf/qtest/qpdf/c-decrypt-R5-with-user.pdf
Binary files differ
diff --git a/qpdf/qtest/qpdf/c-decrypt-R6-with-owner.pdf b/qpdf/qtest/qpdf/c-decrypt-R6-with-owner.pdf
new file mode 100644
index 00000000..8e5d9b81
--- /dev/null
+++ b/qpdf/qtest/qpdf/c-decrypt-R6-with-owner.pdf
Binary files differ
diff --git a/qpdf/qtest/qpdf/c-min-version.out b/qpdf/qtest/qpdf/c-min-version.out
new file mode 100644
index 00000000..94558ace
--- /dev/null
+++ b/qpdf/qtest/qpdf/c-min-version.out
@@ -0,0 +1,4 @@
+version: 1.7
+extension level: 8
+linearized: 0
+encrypted: 0
diff --git a/qpdf/qtest/qpdf/c-r5-in.pdf b/qpdf/qtest/qpdf/c-r5-in.pdf
new file mode 100644
index 00000000..19c67a30
--- /dev/null
+++ b/qpdf/qtest/qpdf/c-r5-in.pdf
Binary files differ
diff --git a/qpdf/qtest/qpdf/c-r5.out b/qpdf/qtest/qpdf/c-r5.out
new file mode 100644
index 00000000..b8789e22
--- /dev/null
+++ b/qpdf/qtest/qpdf/c-r5.out
@@ -0,0 +1,20 @@
+checking a.pdf
+PDF Version: 1.7 extension level 3
+R = 5
+P = -2052
+User password =
+extract for accessibility: allowed
+extract for any purpose: allowed
+print low resolution: allowed
+print high resolution: not allowed
+modify document assembly: allowed
+modify forms: allowed
+modify annotations: allowed
+modify other: allowed
+modify anything: allowed
+stream encryption method: AESv3
+string encryption method: AESv3
+file encryption method: AESv3
+File is not linearized
+No syntax or stream encoding errors found; the file may still contain
+errors that qpdf cannot detect
diff --git a/qpdf/qtest/qpdf/c-r6-in.pdf b/qpdf/qtest/qpdf/c-r6-in.pdf
new file mode 100644
index 00000000..d8aa5d67
--- /dev/null
+++ b/qpdf/qtest/qpdf/c-r6-in.pdf
Binary files differ
diff --git a/qpdf/qtest/qpdf/c-r6.out b/qpdf/qtest/qpdf/c-r6.out
new file mode 100644
index 00000000..1f99b975
--- /dev/null
+++ b/qpdf/qtest/qpdf/c-r6.out
@@ -0,0 +1,20 @@
+checking a.pdf
+PDF Version: 1.7 extension level 8
+R = 6
+P = -2052
+User password = user4
+extract for accessibility: allowed
+extract for any purpose: allowed
+print low resolution: allowed
+print high resolution: not allowed
+modify document assembly: allowed
+modify forms: allowed
+modify annotations: allowed
+modify other: allowed
+modify anything: allowed
+stream encryption method: AESv3
+string encryption method: AESv3
+file encryption method: AESv3
+File is not linearized
+No syntax or stream encoding errors found; the file may still contain
+errors that qpdf cannot detect