aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2020-01-26 22:43:55 +0100
committerJay Berkenbilt <ejb@ql.org>2020-01-26 22:50:57 +0100
commit57c01ef81ff11b208188bbdedc98b6ce20c786b3 (patch)
tree164cd1ba4e8e5f911f7ef860068d68b39831231f
parentbbc2f8ffae939eab598f583514fb132d23c11705 (diff)
downloadqpdf-57c01ef81ff11b208188bbdedc98b6ce20c786b3.tar.zst
In qdf mode, don't write extra XRef streams (fixes #386)
fix-qdf assumes there is exactly one XRef stream and that it is at the end of the file.
-rw-r--r--ChangeLog7
-rw-r--r--libqpdf/QPDFWriter.cc15
-rw-r--r--qpdf/qpdf.testcov1
-rw-r--r--qpdf/qtest/qpdf.test12
-rw-r--r--qpdf/qtest/qpdf/compress-objstm-xref-qdf.pdfbin0 -> 1249 bytes
5 files changed, 34 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index 38749752..b65581ba 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
2020-01-26 Jay Berkenbilt <ejb@ql.org>
+ * Bug fix: in qdf mode, do not write out any XRef streams that may
+ have appeared in the original file. These are usually
+ unreferenced, but with --preserve-unreferenced, they could be
+ written out, which breaks fix-qdf's assumption that there is at
+ most one XRef stream and that it appears at the end of the file.
+ Fixes #386.
+
* Bug fix: when externalizing inline images, a colorspace value
that was a lookup key in the page's /Resource -> /ColorSpace
dictionary was not properly handled. Fixes #392.
diff --git a/libqpdf/QPDFWriter.cc b/libqpdf/QPDFWriter.cc
index 7b769ae4..5f97117d 100644
--- a/libqpdf/QPDFWriter.cc
+++ b/libqpdf/QPDFWriter.cc
@@ -1241,6 +1241,21 @@ QPDFWriter::enqueueObject(QPDFObjectHandle object)
" another file.");
}
+ if (this->m->qdf_mode &&
+ object.isStream() && object.getDict().getKey("/Type").isName() &&
+ (object.getDict().getKey("/Type").getName() == "/XRef"))
+ {
+ // As a special case, do not output any extraneous XRef
+ // streams in QDF mode. Doing so will confuse fix-qdf,
+ // which expects to see only one XRef stream at the end of
+ // the file. This case can occur when creating a QDF from
+ // a file with object streams when preserving unreferenced
+ // objects since the old cross reference streams are not
+ // actually referenced by object number.
+ QTC::TC("qpdf", "QPDFWriter ignore XRef in qdf mode");
+ return;
+ }
+
QPDFObjGen og = object.getObjGen();
if (this->m->obj_renumber.count(og) == 0)
diff --git a/qpdf/qpdf.testcov b/qpdf/qpdf.testcov
index db3de950..f16f0364 100644
--- a/qpdf/qpdf.testcov
+++ b/qpdf/qpdf.testcov
@@ -448,3 +448,4 @@ QPDFWriter stream in ostream 0
QPDFObjectHandle duplicate dict key 0
QPDFWriter no encryption sig contents 0
QPDFPageObjectHelper colorspace lookup 0
+QPDFWriter ignore XRef in qdf mode 0
diff --git a/qpdf/qtest/qpdf.test b/qpdf/qtest/qpdf.test
index f9bab01f..e42e204a 100644
--- a/qpdf/qtest/qpdf.test
+++ b/qpdf/qtest/qpdf.test
@@ -2779,7 +2779,7 @@ for (my $n = 16; $n <= 19; ++$n)
show_ntests();
# ----------
$td->notify("--- Specific File Tests ---");
-$n_tests += 4;
+$n_tests += 7;
# Special PDF files that caused problems at some point
@@ -2800,6 +2800,16 @@ $td->runtest("compress objstm and xref",
$td->runtest("check output",
{$td->FILE => "a.pdf"},
{$td->FILE => "compress-objstm-xref.pdf"});
+$td->runtest("qdf + preserved-unreferenced + xref streams",
+ {$td->COMMAND => "qpdf --qdf --preserve-unreferenced" .
+ " --static-id compress-objstm-xref.pdf a.pdf"},
+ {$td->STRING => "", $td->EXIT_STATUS => 0});
+$td->runtest("check output",
+ {$td->FILE => "a.pdf"},
+ {$td->FILE => "compress-objstm-xref-qdf.pdf"});
+$td->runtest("check fix-qdf idempotency",
+ {$td->COMMAND => "fix-qdf a.pdf"},
+ {$td->FILE => "a.pdf", $td->EXIT_STATUS => 0});
show_ntests();
# ----------
diff --git a/qpdf/qtest/qpdf/compress-objstm-xref-qdf.pdf b/qpdf/qtest/qpdf/compress-objstm-xref-qdf.pdf
new file mode 100644
index 00000000..d6b78a05
--- /dev/null
+++ b/qpdf/qtest/qpdf/compress-objstm-xref-qdf.pdf
Binary files differ