aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/qpdf/QPDFWriter.hh1
-rw-r--r--libqpdf/QPDFWriter.cc47
-rw-r--r--qpdf/qtest/qpdf.test22
-rw-r--r--qpdf/qtest/qpdf/long-id-linearized-check.out6
-rw-r--r--qpdf/qtest/qpdf/long-id-linearized.pdfbin0 -> 1338 bytes
-rw-r--r--qpdf/qtest/qpdf/short-id-linearized-check.out6
-rw-r--r--qpdf/qtest/qpdf/short-id-linearized.pdfbin0 -> 1294 bytes
7 files changed, 72 insertions, 10 deletions
diff --git a/include/qpdf/QPDFWriter.hh b/include/qpdf/QPDFWriter.hh
index ebd833db..c831c2ca 100644
--- a/include/qpdf/QPDFWriter.hh
+++ b/include/qpdf/QPDFWriter.hh
@@ -414,6 +414,7 @@ class QPDFWriter
void initializeSpecialStreams();
void preserveObjectStreams();
void generateObjectStreams();
+ std::string getOriginalID1();
void generateID();
void interpretR3EncryptionParameters(
std::set<int>& bits_to_clear,
diff --git a/libqpdf/QPDFWriter.cc b/libqpdf/QPDFWriter.cc
index d34b095c..05446400 100644
--- a/libqpdf/QPDFWriter.cc
+++ b/libqpdf/QPDFWriter.cc
@@ -1246,8 +1246,28 @@ QPDFWriter::writeTrailer(trailer_e which, int size, bool xref_stream,
writeString(" /ID [");
if (linearization_pass == 1)
{
- writeString("<00000000000000000000000000000000>"
- "<00000000000000000000000000000000>");
+ std::string original_id1 = getOriginalID1();
+ if (original_id1.empty())
+ {
+ writeString("<00000000000000000000000000000000>");
+ }
+ else
+ {
+ // Write a string of zeroes equal in length to the
+ // representation of the original ID. While writing the
+ // original ID would have the same number of bytes, it
+ // would cause a change to the deterministic ID generated
+ // by older versions of the software that hard-coded the
+ // length of the ID to 16 bytes.
+ writeString("<");
+ size_t len = QPDF_String(original_id1).unparse(true).length() - 2;
+ for (size_t i = 0; i < len; ++i)
+ {
+ writeString("0");
+ }
+ writeString(">");
+ }
+ writeString("<00000000000000000000000000000000>");
}
else
{
@@ -1952,6 +1972,20 @@ QPDFWriter::writeObject(QPDFObjectHandle object, int object_stream_index)
}
}
+std::string
+QPDFWriter::getOriginalID1()
+{
+ QPDFObjectHandle trailer = this->m->pdf.getTrailer();
+ if (trailer.hasKey("/ID"))
+ {
+ return trailer.getKey("/ID").getArrayItem(0).getStringValue();
+ }
+ else
+ {
+ return "";
+ }
+}
+
void
QPDFWriter::generateID()
{
@@ -2042,12 +2076,9 @@ QPDFWriter::generateID()
// generated ID for both.
this->m->id2 = result;
- if (trailer.hasKey("/ID"))
- {
- // Note: keep /ID from old file even if --static-id was given.
- this->m->id1 = trailer.getKey("/ID").getArrayItem(0).getStringValue();
- }
- else
+ // Note: keep /ID from old file even if --static-id was given.
+ this->m->id1 = getOriginalID1();
+ if (this->m->id1.empty())
{
this->m->id1 = this->m->id2;
}
diff --git a/qpdf/qtest/qpdf.test b/qpdf/qtest/qpdf.test
index ae070735..b4d926e2 100644
--- a/qpdf/qtest/qpdf.test
+++ b/qpdf/qtest/qpdf.test
@@ -240,7 +240,7 @@ foreach my $d (@bug_tests)
show_ntests();
# ----------
$td->notify("--- Miscellaneous Tests ---");
-$n_tests += 87;
+$n_tests += 93;
$td->runtest("qpdf version",
{$td->COMMAND => "qpdf --version"},
@@ -303,7 +303,8 @@ $td->runtest("check output",
{$td->FILE => "unreferenced-indirect-scalar.out"});
# Encrypt files whose /ID strings are other than 32 bytes long (bug
-# 2991412).
+# 2991412). Also linearize these files, which was reported in a
+# separate bug by email.
foreach my $file (qw(short-id long-id))
{
$td->runtest("encrypt $file.pdf",
@@ -318,6 +319,23 @@ foreach my $file (qw(short-id long-id))
{$td->FILE => "$file-check.out",
$td->EXIT_STATUS => 0},
$td->NORMALIZE_NEWLINES);
+
+ $td->runtest("linearize $file.pdf",
+ {$td->COMMAND =>
+ "qpdf --deterministic-id --linearize $file.pdf a.pdf"},
+ {$td->STRING => "",
+ $td->EXIT_STATUS => 0},
+ $td->NORMALIZE_NEWLINES);
+
+ $td->runtest("check output",
+ {$td->FILE => "a.pdf"},
+ {$td->FILE => "$file-linearized.pdf"});
+
+ $td->runtest("check $file.pdf",
+ {$td->COMMAND => "qpdf --check a.pdf"},
+ {$td->FILE => "$file-linearized-check.out",
+ $td->EXIT_STATUS => 0},
+ $td->NORMALIZE_NEWLINES);
}
# Handle file with invalid xref table and object 0 as a regular object
diff --git a/qpdf/qtest/qpdf/long-id-linearized-check.out b/qpdf/qtest/qpdf/long-id-linearized-check.out
new file mode 100644
index 00000000..af887be9
--- /dev/null
+++ b/qpdf/qtest/qpdf/long-id-linearized-check.out
@@ -0,0 +1,6 @@
+checking a.pdf
+PDF Version: 1.3
+File is not encrypted
+File is linearized
+No syntax or stream encoding errors found; the file may still contain
+errors that qpdf cannot detect
diff --git a/qpdf/qtest/qpdf/long-id-linearized.pdf b/qpdf/qtest/qpdf/long-id-linearized.pdf
new file mode 100644
index 00000000..2993fd30
--- /dev/null
+++ b/qpdf/qtest/qpdf/long-id-linearized.pdf
Binary files differ
diff --git a/qpdf/qtest/qpdf/short-id-linearized-check.out b/qpdf/qtest/qpdf/short-id-linearized-check.out
new file mode 100644
index 00000000..af887be9
--- /dev/null
+++ b/qpdf/qtest/qpdf/short-id-linearized-check.out
@@ -0,0 +1,6 @@
+checking a.pdf
+PDF Version: 1.3
+File is not encrypted
+File is linearized
+No syntax or stream encoding errors found; the file may still contain
+errors that qpdf cannot detect
diff --git a/qpdf/qtest/qpdf/short-id-linearized.pdf b/qpdf/qtest/qpdf/short-id-linearized.pdf
new file mode 100644
index 00000000..ec8829d7
--- /dev/null
+++ b/qpdf/qtest/qpdf/short-id-linearized.pdf
Binary files differ