From b84f57e56d87691d6e592d1ff0b42d186cc70b98 Mon Sep 17 00:00:00 2001 From: Jay Berkenbilt Date: Sun, 7 Jul 2013 17:26:03 -0400 Subject: [PATCH] Ignore broken DecodeParms for stream with no filters --- ChangeLog | 3 + TODO | 4 + libqpdf/QPDF_Stream.cc | 7 +- qpdf/qtest/qpdf.test | 7 +- .../qpdf/broken-decode-parms-no-filter.out | 6 ++ .../qpdf/broken-decode-parms-no-filter.pdf | 102 ++++++++++++++++++ 6 files changed, 127 insertions(+), 2 deletions(-) create mode 100644 qpdf/qtest/qpdf/broken-decode-parms-no-filter.out create mode 100644 qpdf/qtest/qpdf/broken-decode-parms-no-filter.pdf diff --git a/ChangeLog b/ChangeLog index 1a460344..02b21570 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2013-07-07 Jay Berkenbilt + * Ignore error case of a stream's decode parameters having invalid + length when there are no stream filters. + * qpdf: add --show-npages command-line option, which causes the number of pages in the input file to be printed on a line by itself. diff --git a/TODO b/TODO index 9b3d8138..f19c0b6f 100644 --- a/TODO +++ b/TODO @@ -17,6 +17,10 @@ * Provide an option for QPDFWriter to preserve unreferenced objects when writing out a file. + * Look at all the exceptions and error conditions in QPDF_stream and + figure out which ones should be converted to warnings and treating + the stream as not filterable. + * If possible, support user-pluggable stream filters. This would enable external code to provide interpretation for filters that are missing from qpdf. diff --git a/libqpdf/QPDF_Stream.cc b/libqpdf/QPDF_Stream.cc index 6ca88caf..0a82f22b 100644 --- a/libqpdf/QPDF_Stream.cc +++ b/libqpdf/QPDF_Stream.cc @@ -295,8 +295,13 @@ QPDF_Stream::filterable(std::vector& filters, } } - if (decode_parms.size() != filters.size()) + // Ignore /DecodeParms entirely if /Filters is empty. At least + // one case of a file whose /DecodeParms was [ << >> ] when + // /Filters was empty has been seen in the wild. + if ((filters.size() != 0) && (decode_parms.size() != filters.size())) { + // We should just issue a warning and treat this as not + // filterable. throw QPDFExc(qpdf_e_damaged_pdf, qpdf->getFilename(), "", this->offset, "stream /DecodeParms length is" diff --git a/qpdf/qtest/qpdf.test b/qpdf/qtest/qpdf.test index 1a6e44ad..a30dd7b4 100644 --- a/qpdf/qtest/qpdf.test +++ b/qpdf/qtest/qpdf.test @@ -199,7 +199,7 @@ $td->runtest("remove page we don't have", show_ntests(); # ---------- $td->notify("--- Miscellaneous Tests ---"); -$n_tests += 66; +$n_tests += 67; $td->runtest("qpdf version", {$td->COMMAND => "qpdf --version"}, @@ -522,6 +522,11 @@ $td->runtest("show number of pages", "qpdf --show-npages 20-pages.pdf --password=user"}, {$td->STRING => "20\n", $td->EXIT_STATUS => 0}, $td->NORMALIZE_NEWLINES); +$td->runtest("ignore broken decode parms with no filters", + {$td->COMMAND => "qpdf --check broken-decode-parms-no-filter.pdf"}, + {$td->FILE => "broken-decode-parms-no-filter.out", + $td->EXIT_STATUS => 0}, + $td->NORMALIZE_NEWLINES); show_ntests(); # ---------- diff --git a/qpdf/qtest/qpdf/broken-decode-parms-no-filter.out b/qpdf/qtest/qpdf/broken-decode-parms-no-filter.out new file mode 100644 index 00000000..c5ec39bd --- /dev/null +++ b/qpdf/qtest/qpdf/broken-decode-parms-no-filter.out @@ -0,0 +1,6 @@ +checking broken-decode-parms-no-filter.pdf +PDF Version: 1.3 +File is not encrypted +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/broken-decode-parms-no-filter.pdf b/qpdf/qtest/qpdf/broken-decode-parms-no-filter.pdf new file mode 100644 index 00000000..34795bb3 --- /dev/null +++ b/qpdf/qtest/qpdf/broken-decode-parms-no-filter.pdf @@ -0,0 +1,102 @@ +%PDF-1.3 +%¿÷¢þ +%QDF-1.0 + +%% Original object ID: 1 0 +1 0 obj +<< + /Pages 2 0 R + /Type /Catalog +>> +endobj + +%% Original object ID: 2 0 +2 0 obj +<< + /Count 1 + /Kids [ + 3 0 R + ] + /Type /Pages +>> +endobj + +%% Page 1 +%% Original object ID: 3 0 +3 0 obj +<< + /Contents 4 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 2 0 R + /Resources << + /Font << + /F1 6 0 R + >> + /ProcSet 7 0 R + >> + /Type /Page +>> +endobj + +%% Contents for page 1 +%% Original object ID: 4 0 +4 0 obj +<< + /Length 5 0 R + /DecodeParms [ << >> ] +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Potato) Tj +ET +endstream +endobj + +5 0 obj +44 +endobj + +%% Original object ID: 6 0 +6 0 obj +<< + /BaseFont /Helvetica + /Encoding /WinAnsiEncoding + /Name /F1 + /Subtype /Type1 + /Type /Font +>> +endobj + +%% Original object ID: 5 0 +7 0 obj +[ + /PDF + /Text +] +endobj + +xref +0 8 +0000000000 65535 f +0000000052 00000 n +0000000133 00000 n +0000000242 00000 n +0000000484 00000 n +0000000608 00000 n +0000000654 00000 n +0000000799 00000 n +trailer << + /Root 1 0 R + /Size 8 + /ID [<3ed0e583ae70f9665d727ef9c2780a19><3ed0e583ae70f9665d727ef9c2780a19>] +>> +startxref +834 +%%EOF