From c1e53f148096c329650068694fbde82f018560bf Mon Sep 17 00:00:00 2001 From: Jay Berkenbilt Date: Sun, 4 Oct 2009 23:56:56 +0000 Subject: [PATCH] bug fix: more gracefully handle xref stream with too many entries git-svn-id: svn+q:///qpdf/trunk@747 71b93d88-0707-0410-a8cf-f5a4172ac649 --- ChangeLog | 6 ++++++ libqpdf/QPDF.cc | 16 +++++++++++---- qpdf/qtest/qpdf.test | 19 +++++++++++++++++- qpdf/qtest/qpdf/xref-with-short-size-new.out | 13 ++++++++++++ .../qpdf/xref-with-short-size-recover.out | 2 ++ qpdf/qtest/qpdf/xref-with-short-size.out | 14 +++++++++++++ qpdf/qtest/qpdf/xref-with-short-size.pdf | Bin 0 -> 16527 bytes 7 files changed, 65 insertions(+), 5 deletions(-) create mode 100644 qpdf/qtest/qpdf/xref-with-short-size-new.out create mode 100644 qpdf/qtest/qpdf/xref-with-short-size-recover.out create mode 100644 qpdf/qtest/qpdf/xref-with-short-size.out create mode 100644 qpdf/qtest/qpdf/xref-with-short-size.pdf diff --git a/ChangeLog b/ChangeLog index afe1f628..e21ad6b8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2009-10-04 Jay Berkenbilt + + * 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 * 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 0000000000000000000000000000000000000000..3ef4dcdf74eaf6bd3cd7d737950561e337074b77 GIT binary patch literal 16527 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 literal 0 HcmV?d00001