summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--libqpdf/QPDF.cc16
-rw-r--r--qpdf/qtest/qpdf.test19
-rw-r--r--qpdf/qtest/qpdf/xref-with-short-size-new.out13
-rw-r--r--qpdf/qtest/qpdf/xref-with-short-size-recover.out2
-rw-r--r--qpdf/qtest/qpdf/xref-with-short-size.out14
-rw-r--r--qpdf/qtest/qpdf/xref-with-short-size.pdfbin0 -> 16527 bytes
7 files changed, 65 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog
index afe1f628..e21ad6b8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2009-10-04 Jay Berkenbilt <ejb@ql.org>
+
+ * libqpdf/QPDF.cc (processXRefStream): warn and ignore extra xref
+ stream entries when stream is larger than reported size. This
+ used to be a fatal error. (Fixes qpdf-Bugs-2872265.)
+
2009-09-27 Jay Berkenbilt <ejb@ql.org>
* Add several methods to query permissions controlled by the
diff --git a/libqpdf/QPDF.cc b/libqpdf/QPDF.cc
index 8f275b74..dbbd5517 100644
--- a/libqpdf/QPDF.cc
+++ b/libqpdf/QPDF.cc
@@ -787,10 +787,18 @@ QPDF::processXRefStream(off_t xref_offset, QPDFObjectHandle& xref_obj)
if (expected_size != actual_size)
{
- throw QPDFExc(this->file.getName(), xref_offset,
- "Cross-reference stream data has the wrong size;"
- " expected = " + QUtil::int_to_string(expected_size) +
- "; actual = " + QUtil::int_to_string(actual_size));
+ QPDFExc x(this->file.getName(), xref_offset,
+ "Cross-reference stream data has the wrong size;"
+ " expected = " + QUtil::int_to_string(expected_size) +
+ "; actual = " + QUtil::int_to_string(actual_size));
+ if (expected_size > actual_size)
+ {
+ throw x;
+ }
+ else
+ {
+ warn(x);
+ }
}
int cur_chunk = 0;
diff --git a/qpdf/qtest/qpdf.test b/qpdf/qtest/qpdf.test
index 8cf355b0..1c724ec3 100644
--- a/qpdf/qtest/qpdf.test
+++ b/qpdf/qtest/qpdf.test
@@ -81,7 +81,7 @@ flush_tiff_cache();
show_ntests();
# ----------
$td->notify("--- Miscellaneous Tests ---");
-$n_tests += 4;
+$n_tests += 7;
foreach (my $i = 1; $i <= 3; ++$i)
{
@@ -98,6 +98,23 @@ $td->runtest("unknown decode parameters",
$td->EXIT_STATUS => 0},
$td->NORMALIZE_NEWLINES);
+# Handle xref stream with more entries than reported (bug 2872265)
+$td->runtest("xref with short size",
+ {$td->COMMAND => "qpdf --show-xref xref-with-short-size.pdf"},
+ {$td->FILE => "xref-with-short-size.out",
+ $td->EXIT_STATUS => 3},
+ $td->NORMALIZE_NEWLINES);
+$td->runtest("recover xref with short size",
+ {$td->COMMAND => "qpdf xref-with-short-size.pdf a.pdf"},
+ {$td->FILE => "xref-with-short-size-recover.out",
+ $td->EXIT_STATUS => 3},
+ $td->NORMALIZE_NEWLINES);
+$td->runtest("show new xref stream",
+ {$td->COMMAND => "qpdf --show-xref a.pdf"},
+ {$td->FILE => "xref-with-short-size-new.out",
+ $td->EXIT_STATUS => 0},
+ $td->NORMALIZE_NEWLINES);
+
show_ntests();
# ----------
$td->notify("--- Error Condition Tests ---");
diff --git a/qpdf/qtest/qpdf/xref-with-short-size-new.out b/qpdf/qtest/qpdf/xref-with-short-size-new.out
new file mode 100644
index 00000000..9396e6c6
--- /dev/null
+++ b/qpdf/qtest/qpdf/xref-with-short-size-new.out
@@ -0,0 +1,13 @@
+1/0: uncompressed; offset = 15
+2/0: compressed; stream = 1, index = 0
+3/0: compressed; stream = 1, index = 1
+4/0: compressed; stream = 1, index = 2
+5/0: compressed; stream = 1, index = 3
+6/0: compressed; stream = 1, index = 4
+7/0: compressed; stream = 1, index = 5
+8/0: compressed; stream = 1, index = 6
+9/0: compressed; stream = 1, index = 7
+10/0: compressed; stream = 1, index = 8
+11/0: uncompressed; offset = 674
+12/0: uncompressed; offset = 801
+13/0: uncompressed; offset = 16194
diff --git a/qpdf/qtest/qpdf/xref-with-short-size-recover.out b/qpdf/qtest/qpdf/xref-with-short-size-recover.out
new file mode 100644
index 00000000..52c58986
--- /dev/null
+++ b/qpdf/qtest/qpdf/xref-with-short-size-recover.out
@@ -0,0 +1,2 @@
+WARNING: xref-with-short-size.pdf: offset 16227: Cross-reference stream data has the wrong size; expected = 52; actual = 56
+qpdf: operation succeeded with warnings; resulting file may have some problems
diff --git a/qpdf/qtest/qpdf/xref-with-short-size.out b/qpdf/qtest/qpdf/xref-with-short-size.out
new file mode 100644
index 00000000..19f9963e
--- /dev/null
+++ b/qpdf/qtest/qpdf/xref-with-short-size.out
@@ -0,0 +1,14 @@
+WARNING: xref-with-short-size.pdf: offset 16227: Cross-reference stream data has the wrong size; expected = 52; actual = 56
+1/0: compressed; stream = 5, index = 1
+2/0: compressed; stream = 5, index = 0
+3/0: uncompressed; offset = 15
+4/0: compressed; stream = 5, index = 5
+5/0: uncompressed; offset = 15548
+6/0: compressed; stream = 5, index = 6
+7/0: compressed; stream = 5, index = 4
+8/0: compressed; stream = 5, index = 2
+9/0: uncompressed; offset = 150
+10/0: compressed; stream = 5, index = 3
+11/0: compressed; stream = 5, index = 7
+12/0: compressed; stream = 5, index = 8
+qpdf: operation succeeded with warnings; resulting file may have some problems
diff --git a/qpdf/qtest/qpdf/xref-with-short-size.pdf b/qpdf/qtest/qpdf/xref-with-short-size.pdf
new file mode 100644
index 00000000..3ef4dcdf
--- /dev/null
+++ b/qpdf/qtest/qpdf/xref-with-short-size.pdf
Binary files differ