aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--include/qpdf/qpdf-c.h8
-rw-r--r--libqpdf/qpdf-c.cc17
-rw-r--r--qpdf/qpdf-ctest.c13
-rw-r--r--qpdf/qpdf.testcov1
-rw-r--r--qpdf/qtest/qpdf.test15
-rw-r--r--qpdf/qtest/qpdf/c-check-clear-in.pdf79
-rw-r--r--qpdf/qtest/qpdf/c-check-clear.out1
-rw-r--r--qpdf/qtest/qpdf/c-check-warn-in.pdf79
-rw-r--r--qpdf/qtest/qpdf/c-check-warn.out19
10 files changed, 236 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 1d551461..6c9e581e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
2018-02-17 Jay Berkenbilt <ejb@ql.org>
+ * Add qpdf_check_pdf to the "C" API. This method just attempts to
+ read the entire file and produce no output, making possible to
+ assess whether the file has any errors that qpdf can detect.
+
* Major enhancements to handling of type errors within the qpdf
library. This fix is intended to eliminate those annoying cases
where qpdf would exit with a message like "operation for
diff --git a/include/qpdf/qpdf-c.h b/include/qpdf/qpdf-c.h
index 4773809e..a6002a92 100644
--- a/include/qpdf/qpdf-c.h
+++ b/include/qpdf/qpdf-c.h
@@ -180,6 +180,14 @@ extern "C" {
QPDF_DLL
void qpdf_set_suppress_warnings(qpdf_data qpdf, QPDF_BOOL value);
+ /* CHECK FUNCTIONS */
+
+ /* Attempt to read the entire PDF file to see if there are any
+ * errors qpdf can detect.
+ */
+ QPDF_DLL
+ QPDF_ERROR_CODE qpdf_check_pdf(qpdf_data qpdf);
+
/* READ FUNCTIONS */
/* READ PARAMETER FUNCTIONS -- must be called before qpdf_read */
diff --git a/libqpdf/qpdf-c.cc b/libqpdf/qpdf-c.cc
index a9883d32..1cc1e2b1 100644
--- a/libqpdf/qpdf-c.cc
+++ b/libqpdf/qpdf-c.cc
@@ -4,6 +4,7 @@
#include <qpdf/QPDFWriter.hh>
#include <qpdf/QTC.hh>
#include <qpdf/QPDFExc.hh>
+#include <qpdf/Pl_Discard.hh>
#include <list>
#include <string>
@@ -82,6 +83,15 @@ static void call_write(qpdf_data qpdf)
qpdf->qpdf_writer->write();
}
+static void call_check(qpdf_data qpdf)
+{
+ QPDFWriter w(*qpdf->qpdf);
+ Pl_Discard discard;
+ w.setOutputPipeline(&discard);
+ w.setDecodeLevel(qpdf_dl_all);
+ w.write();
+}
+
static QPDF_ERROR_CODE trap_errors(qpdf_data qpdf, void (*fn)(qpdf_data))
{
QPDF_ERROR_CODE status = QPDF_SUCCESS;
@@ -236,6 +246,13 @@ char const* qpdf_get_error_message_detail(qpdf_data qpdf, qpdf_error e)
return e->exc->getMessageDetail().c_str();
}
+QPDF_ERROR_CODE qpdf_check_pdf(qpdf_data qpdf)
+{
+ QPDF_ERROR_CODE status = trap_errors(qpdf, &call_check);
+ QTC::TC("qpdf", "qpdf-c called qpdf_check_pdf");
+ return status;
+}
+
void qpdf_set_suppress_warnings(qpdf_data qpdf, QPDF_BOOL value)
{
QTC::TC("qpdf", "qpdf-c called qpdf_set_suppress_warnings");
diff --git a/qpdf/qpdf-ctest.c b/qpdf/qpdf-ctest.c
index f7bfb5c4..8b9c36ce 100644
--- a/qpdf/qpdf-ctest.c
+++ b/qpdf/qpdf-ctest.c
@@ -484,6 +484,18 @@ static void test22(char const* infile,
report_errors();
}
+static void test23(char const* infile,
+ char const* password,
+ char const* outfile,
+ char const* outfile2)
+{
+ QPDF_ERROR_CODE status = 0;
+ qpdf_read(qpdf, infile, password);
+ status = qpdf_check_pdf(qpdf);
+ printf("status: %d\n", status);
+ report_errors();
+}
+
int main(int argc, char* argv[])
{
char* p = 0;
@@ -546,6 +558,7 @@ int main(int argc, char* argv[])
(n == 20) ? test20 :
(n == 21) ? test21 :
(n == 22) ? test22 :
+ (n == 23) ? test23 :
0);
if (fn == 0)
diff --git a/qpdf/qpdf.testcov b/qpdf/qpdf.testcov
index 67cbfe7f..7e60953e 100644
--- a/qpdf/qpdf.testcov
+++ b/qpdf/qpdf.testcov
@@ -333,3 +333,4 @@ QPDFObjectHandle dictionary ignoring removeKey 0
QPDFObjectHandle dictionary ignoring removereplace 0
QPDFObjectHandle numeric non-numeric 0
QPDFObjectHandle erase array bounds 0
+qpdf-c called qpdf_check_pdf 0
diff --git a/qpdf/qtest/qpdf.test b/qpdf/qtest/qpdf.test
index bd341079..6854e651 100644
--- a/qpdf/qtest/qpdf.test
+++ b/qpdf/qtest/qpdf.test
@@ -2495,6 +2495,21 @@ foreach my $d (@enc_key)
show_ntests();
# ----------
+$td->notify("--- Check from C API ---");
+my @c_check_types = qw(warn clear);
+$n_tests += scalar(@c_check_types);
+
+foreach my $i (@c_check_types)
+{
+ $td->runtest("C check $i",
+ {$td->COMMAND => "qpdf-ctest 23 c-check-$i-in.pdf '' -"},
+ {$td->FILE => "c-check-$i.out",
+ $td->EXIT_STATUS => 0},
+ $td->NORMALIZE_NEWLINES);
+}
+
+show_ntests();
+# ----------
$td->notify("--- Content Preservation Tests ---");
# $n_tests incremented below
diff --git a/qpdf/qtest/qpdf/c-check-clear-in.pdf b/qpdf/qtest/qpdf/c-check-clear-in.pdf
new file mode 100644
index 00000000..a7e01f91
--- /dev/null
+++ b/qpdf/qtest/qpdf/c-check-clear-in.pdf
@@ -0,0 +1,79 @@
+%PDF-1.3
+1 0 obj
+<<
+ /Type /Catalog
+ /Pages 2 0 R
+>>
+endobj
+
+2 0 obj
+<<
+ /Type /Pages
+ /Kids [
+ 3 0 R
+ ]
+ /Count 1
+>>
+endobj
+
+3 0 obj
+<<
+ /Type /Page
+ /Parent 2 0 R
+ /MediaBox [0 0 612 792]
+ /Contents 4 0 R
+ /Resources <<
+ /ProcSet 5 0 R
+ /Font <<
+ /F1 6 0 R
+ >>
+ >>
+>>
+endobj
+
+4 0 obj
+<<
+ /Length 44
+>>
+stream
+BT
+ /F1 24 Tf
+ 72 720 Td
+ (Potato) Tj
+ET
+endstream
+endobj
+
+5 0 obj
+[
+ /PDF
+ /Text
+]
+endobj
+
+6 0 obj
+<<
+ /Type /Font
+ /Subtype /Type1
+ /Name /F1
+ /BaseFont /Helvetica
+ /Encoding /WinAnsiEncoding
+>>
+endobj
+
+xref
+0 7
+0000000000 65535 f
+0000000009 00000 n
+0000000063 00000 n
+0000000135 00000 n
+0000000307 00000 n
+0000000403 00000 n
+0000000438 00000 n
+trailer <<
+ /Size 7
+ /Root 1 0 R
+>>
+startxref
+556
+%%EOF
diff --git a/qpdf/qtest/qpdf/c-check-clear.out b/qpdf/qtest/qpdf/c-check-clear.out
new file mode 100644
index 00000000..934014b3
--- /dev/null
+++ b/qpdf/qtest/qpdf/c-check-clear.out
@@ -0,0 +1 @@
+status: 0
diff --git a/qpdf/qtest/qpdf/c-check-warn-in.pdf b/qpdf/qtest/qpdf/c-check-warn-in.pdf
new file mode 100644
index 00000000..e8a7042c
--- /dev/null
+++ b/qpdf/qtest/qpdf/c-check-warn-in.pdf
@@ -0,0 +1,79 @@
+%PDF-1.3
+1 0 obj
+<<
+ /Type /Catalog
+ /Pages 2 0 R
+>>
+endobj
+
+2 0 obj
+<<
+ /Type /Pages
+ /Kids [
+ 3 0 R
+ ]
+ /Count 1
+>>
+endobj
+
+3 0 obj
+<<
+ /Type /Page
+ /Parent 2 0 R
+ /MediaBox [0 0 612 792]
+ /Contents 4 0 R
+ /Resources <<
+ /ProcSet 5 0 R
+ /Font <<
+ /F1 6 0 R
+ >>
+ >>
+>>
+endobj
+
+4 0 obj
+<<
+ /Length 44
+>>
+stream
+BT
+ /F1 24 Tf
+ 72 720 Td
+ (Potato) Tj
+ET
+endstream
+endobj
+
+5 0 obj
+[
+ /PDF
+ /Text
+]
+endobj
+
+6 0 obj
+<<
+ /Type /Font
+ /Subtype /Type1
+ /Name /F1
+ /BaseFont /Helvetica
+ /Encoding /WinAnsiEncoding
+>>
+endobj
+
+xref
+0 7
+0000000000 65535 f
+0000000009 00000 n
+0000000063 00000 n
+0000000135 00000 n
+0000000307 00000 n
+0000000403 00000 n
+0000000438 00000 n
+trailer <<
+ /Size 7
+ /Root 1 0 R
+>>
+startxref
+1556
+%%EOF
diff --git a/qpdf/qtest/qpdf/c-check-warn.out b/qpdf/qtest/qpdf/c-check-warn.out
new file mode 100644
index 00000000..40e8eb35
--- /dev/null
+++ b/qpdf/qtest/qpdf/c-check-warn.out
@@ -0,0 +1,19 @@
+WARNING: c-check-warn-in.pdf: file is damaged
+WARNING: c-check-warn-in.pdf (offset 1556): xref not found
+WARNING: c-check-warn-in.pdf: Attempting to reconstruct cross-reference table
+status: 1
+warning: c-check-warn-in.pdf: file is damaged
+ code: 5
+ file: c-check-warn-in.pdf
+ pos : 0
+ text: file is damaged
+warning: c-check-warn-in.pdf (offset 1556): xref not found
+ code: 5
+ file: c-check-warn-in.pdf
+ pos : 1556
+ text: xref not found
+warning: c-check-warn-in.pdf: Attempting to reconstruct cross-reference table
+ code: 5
+ file: c-check-warn-in.pdf
+ pos : 0
+ text: Attempting to reconstruct cross-reference table