summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2014-06-07 18:31:22 +0200
committerJay Berkenbilt <ejb@ql.org>2014-06-07 22:31:03 +0200
commit9f8aba1db7f101e424cbc2c742abe92868cc4bff (patch)
tree11422a749e425f1f890694bebde3f7d9291c0040
parentb0a96ce6aa95c4d23e40eed3cede2f46e935bba7 (diff)
downloadqpdf-9f8aba1db7f101e424cbc2c742abe92868cc4bff.tar.zst
Handle indirect stream filter/decode parameters
QPDFWriter was trying to make /Filter and /DecodeParms direct in all cases, but there are some cases where /DecodeParms may refer to a stream, which can't be direct. QPDFWriter doesn't actually need /DecodeParms to be direct in that case because it won't be able to filter the stream. Until we can handle this type of stream, just don't make /Filter and /DecodeParms direct if we can't filter the stream anyway. Fixes #34
-rw-r--r--ChangeLog7
-rw-r--r--libqpdf/QPDFWriter.cc8
-rw-r--r--qpdf/qtest/qpdf.test10
-rw-r--r--qpdf/qtest/qpdf/indirect-decode-parms-out.pdfbin0 -> 1067 bytes
-rw-r--r--qpdf/qtest/qpdf/indirect-decode-parms.pdf128
5 files changed, 150 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index d722e3c0..a83108cb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2014-06-07 Jay Berkenbilt <ejb@ql.org>
+
+ * Bug fix: don't fail on files that contain streams where /Filter
+ or /DecodeParms references a stream. Before, qpdf would try to
+ convert these to direct objects, which would fail because of the
+ stream.
+
2014-02-22 Jay Berkenbilt <ejb@ql.org>
* Bug fix: if the last object in the first part of a linearized
diff --git a/libqpdf/QPDFWriter.cc b/libqpdf/QPDFWriter.cc
index 0f299a45..08647e37 100644
--- a/libqpdf/QPDFWriter.cc
+++ b/libqpdf/QPDFWriter.cc
@@ -2051,11 +2051,14 @@ QPDFWriter::prepareFileForWrite()
{
bool is_stream = false;
bool is_root = false;
+ bool filterable = false;
QPDFObjectHandle dict = node;
if (node.isStream())
{
is_stream = true;
dict = node.getDict();
+ // See whether we are able to filter this stream.
+ filterable = node.pipeStreamData(0, true, false, false);
}
else if (pdf.getRoot().getObjectID() == node.getObjectID())
{
@@ -2073,8 +2076,9 @@ QPDFWriter::prepareFileForWrite()
{
if (oh.isIndirect() &&
((key == "/Length") ||
- (key == "/Filter") ||
- (key == "/DecodeParms")))
+ (filterable &&
+ ((key == "/Filter") ||
+ (key == "/DecodeParms")))))
{
QTC::TC("qpdf", "QPDFWriter make stream key direct");
add_to_queue = false;
diff --git a/qpdf/qtest/qpdf.test b/qpdf/qtest/qpdf.test
index d54adc7e..8e697844 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 += 70;
+$n_tests += 72;
$td->runtest("qpdf version",
{$td->COMMAND => "qpdf --version"},
@@ -546,6 +546,14 @@ $td->runtest("sanity check array size",
$td->EXIT_STATUS => 2},
$td->NORMALIZE_NEWLINES);
+$td->runtest("stream with indirect decode parms",
+ {$td->COMMAND =>
+ "qpdf --static-id indirect-decode-parms.pdf a.pdf"},
+ {$td->STRING => "", $td->EXIT_STATUS => 0});
+$td->runtest("check file",
+ {$td->FILE => "a.pdf"},
+ {$td->FILE => "indirect-decode-parms-out.pdf"});
+
show_ntests();
# ----------
$td->notify("--- Numeric range parsing tests ---");
diff --git a/qpdf/qtest/qpdf/indirect-decode-parms-out.pdf b/qpdf/qtest/qpdf/indirect-decode-parms-out.pdf
new file mode 100644
index 00000000..4f6bd357
--- /dev/null
+++ b/qpdf/qtest/qpdf/indirect-decode-parms-out.pdf
Binary files differ
diff --git a/qpdf/qtest/qpdf/indirect-decode-parms.pdf b/qpdf/qtest/qpdf/indirect-decode-parms.pdf
new file mode 100644
index 00000000..25f4f01d
--- /dev/null
+++ b/qpdf/qtest/qpdf/indirect-decode-parms.pdf
@@ -0,0 +1,128 @@
+%PDF-1.3
+%¿÷¢þ
+%QDF-1.0
+
+1 0 obj
+<<
+ /Pages 2 0 R
+ /Type /Catalog
+>>
+endobj
+
+2 0 obj
+<<
+ /Count 1
+ /Kids [
+ 3 0 R
+ ]
+ /Type /Pages
+>>
+endobj
+
+%% Page 1
+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
+4 0 obj
+<<
+ /Length 5 0 R
+>>
+stream
+BT
+ /F1 24 Tf
+ 72 720 Td
+ (Potato) Tj
+ET
+endstream
+endobj
+
+5 0 obj
+44
+endobj
+
+6 0 obj
+<<
+ /BaseFont /Helvetica
+ /Encoding /WinAnsiEncoding
+ /Name /F1
+ /Subtype /Type1
+ /Type /Font
+>>
+endobj
+
+7 0 obj
+[
+ /PDF
+ /Text
+]
+endobj
+
+8 0 obj
+<<
+ /Length 9 0 R
+ /Filter /Something
+ /DecodeParms 10 0 R
+>>
+stream
+here is some stream data
+endstream
+endobj
+
+9 0 obj
+25
+endobj
+
+10 0 obj
+<<
+ /Length 11 0 R
+>>
+stream
+here is some stream data
+endstream
+endobj
+
+11 0 obj
+25
+endobj
+
+xref
+0 12
+0000000000 65535 f
+0000000025 00000 n
+0000000079 00000 n
+0000000161 00000 n
+0000000376 00000 n
+0000000475 00000 n
+0000000494 00000 n
+0000000612 00000 n
+0000000647 00000 n
+0000000770 00000 n
+0000000789 00000 n
+0000000871 00000 n
+trailer <<
+ /Root 1 0 R
+ /Size 12
+ /QTest 8 0 R
+ /ID [<3e1b045415cfe83fea12b9817e205ef6><3e1b045415cfe83fea12b9817e205ef6>]
+>>
+startxref
+891
+%%EOF