Commit af2a71aa2c0ab7a441cb4210295e3912800df9d0

Authored by Jay Berkenbilt
1 parent 1c62c2a3

Handle bitstream overflow errors more gracefully (fixes #581)

* Make it a runtime error, not a logic error
* Include additional information
* Capture it properly in checkLinearization
ChangeLog
1 2021-12-10 Jay Berkenbilt <ejb@ql.org> 1 2021-12-10 Jay Berkenbilt <ejb@ql.org>
2 2
  3 + * Handle bitstream overflow errors more gracefully. Fixes #581.
  4 +
3 * C API: add qpdf_get_object_by_id, qpdf_make_indirect_object, and 5 * C API: add qpdf_get_object_by_id, qpdf_make_indirect_object, and
4 qpdf_replace_object, exposing the corresponding methods in QPDF 6 qpdf_replace_object, exposing the corresponding methods in QPDF
5 and QPDFObjectHandle. Fixes #588. 7 and QPDFObjectHandle. Fixes #588.
libqpdf/QPDF_linearization.cc
@@ -71,9 +71,11 @@ QPDF::checkLinearization() @@ -71,9 +71,11 @@ QPDF::checkLinearization()
71 readLinearizationData(); 71 readLinearizationData();
72 result = checkLinearizationInternal(); 72 result = checkLinearizationInternal();
73 } 73 }
74 - catch (QPDFExc& e) 74 + catch (std::runtime_error& e)
75 { 75 {
76 - *this->m->err_stream << e.what() << std::endl; 76 + *this->m->err_stream
  77 + << "WARNING: error encountered while checking linearization data: "
  78 + << e.what() << std::endl;
77 } 79 }
78 return result; 80 return result;
79 } 81 }
libqpdf/bits.icc
@@ -6,6 +6,7 @@ @@ -6,6 +6,7 @@
6 #include <stdexcept> 6 #include <stdexcept>
7 #include <qpdf/QTC.hh> 7 #include <qpdf/QTC.hh>
8 #include <qpdf/Pipeline.hh> 8 #include <qpdf/Pipeline.hh>
  9 +#include <qpdf/QUtil.hh>
9 10
10 // These functions may be run at places where the function call 11 // These functions may be run at places where the function call
11 // overhead from test coverage testing would be too high. Therefore, 12 // overhead from test coverage testing would be too high. Therefore,
@@ -28,7 +29,10 @@ read_bits(unsigned char const*&amp; p, size_t&amp; bit_offset, @@ -28,7 +29,10 @@ read_bits(unsigned char const*&amp; p, size_t&amp; bit_offset,
28 29
29 if (bits_wanted > bits_available) 30 if (bits_wanted > bits_available)
30 { 31 {
31 - throw std::length_error("overflow reading bit stream"); 32 + throw std::runtime_error(
  33 + "overflow reading bit stream: wanted = " +
  34 + QUtil::uint_to_string(bits_wanted) + "; available = " +
  35 + QUtil::uint_to_string(bits_available));
32 } 36 }
33 if (bits_wanted > 32) 37 if (bits_wanted > 32)
34 { 38 {
libtests/qtest/bits/bits.out
@@ -17,7 +17,7 @@ bits read: 0, result = 0 @@ -17,7 +17,7 @@ bits read: 0, result = 0
17 byte offset = 4, bit offset = 3, bits available = 28 17 byte offset = 4, bit offset = 3, bits available = 28
18 bits read: 25, result = 5320361 18 bits read: 25, result = 5320361
19 byte offset = 7, bit offset = 2, bits available = 3 19 byte offset = 7, bit offset = 2, bits available = 3
20 -exception: overflow reading bit stream 20 +exception: overflow reading bit stream: wanted = 4; available = 3
21 byte offset = 7, bit offset = 2, bits available = 3 21 byte offset = 7, bit offset = 2, bits available = 3
22 bits read: 3, result = 3 22 bits read: 3, result = 3
23 byte offset = 8, bit offset = 7, bits available = 0 23 byte offset = 8, bit offset = 7, bits available = 0
qpdf/qtest/qpdf.test
@@ -1788,12 +1788,12 @@ $td-&gt;runtest(&quot;bounds check linearization data 2&quot;, @@ -1788,12 +1788,12 @@ $td-&gt;runtest(&quot;bounds check linearization data 2&quot;,
1788 {$td->FILE => "linearization-bounds-2.out", 1788 {$td->FILE => "linearization-bounds-2.out",
1789 $td->EXIT_STATUS => 3}, 1789 $td->EXIT_STATUS => 3},
1790 $td->NORMALIZE_NEWLINES); 1790 $td->NORMALIZE_NEWLINES);
1791 -# Throws logic error, not bad_alloc 1791 +# Throws runtime error, not bad_alloc
1792 $td->runtest("sanity check array size", 1792 $td->runtest("sanity check array size",
1793 {$td->COMMAND => 1793 {$td->COMMAND =>
1794 "qpdf --check linearization-large-vector-alloc.pdf"}, 1794 "qpdf --check linearization-large-vector-alloc.pdf"},
1795 {$td->FILE => "linearization-large-vector-alloc.out", 1795 {$td->FILE => "linearization-large-vector-alloc.out",
1796 - $td->EXIT_STATUS => 2}, 1796 + $td->EXIT_STATUS => 3},
1797 $td->NORMALIZE_NEWLINES); 1797 $td->NORMALIZE_NEWLINES);
1798 1798
1799 show_ntests(); 1799 show_ntests();
qpdf/qtest/qpdf/linearization-bounds-1.out
@@ -5,4 +5,4 @@ File is linearized @@ -5,4 +5,4 @@ File is linearized
5 WARNING: linearization-bounds-1.pdf (linearization hint stream: object 62 0, offset 12302): expected endstream 5 WARNING: linearization-bounds-1.pdf (linearization hint stream: object 62 0, offset 12302): expected endstream
6 WARNING: linearization-bounds-1.pdf (linearization hint stream: object 62 0, offset 1183): attempting to recover stream length 6 WARNING: linearization-bounds-1.pdf (linearization hint stream: object 62 0, offset 1183): attempting to recover stream length
7 WARNING: linearization-bounds-1.pdf (linearization hint stream: object 62 0, offset 1183): recovered stream length: 106 7 WARNING: linearization-bounds-1.pdf (linearization hint stream: object 62 0, offset 1183): recovered stream length: 106
8 -linearization-bounds-1.pdf (linearization hint table, offset 1183): /S (shared object) offset is out of bounds 8 +WARNING: error encountered while checking linearization data: linearization-bounds-1.pdf (linearization hint table, offset 1183): /S (shared object) offset is out of bounds
qpdf/qtest/qpdf/linearization-bounds-2.out
@@ -5,4 +5,4 @@ File is linearized @@ -5,4 +5,4 @@ File is linearized
5 WARNING: linearization-bounds-2.pdf (linearization hint stream: object 62 0, offset 1282): expected endstream 5 WARNING: linearization-bounds-2.pdf (linearization hint stream: object 62 0, offset 1282): expected endstream
6 WARNING: linearization-bounds-2.pdf (linearization hint stream: object 62 0, offset 1183): attempting to recover stream length 6 WARNING: linearization-bounds-2.pdf (linearization hint stream: object 62 0, offset 1183): attempting to recover stream length
7 WARNING: linearization-bounds-2.pdf (linearization hint stream: object 62 0, offset 1183): recovered stream length: 106 7 WARNING: linearization-bounds-2.pdf (linearization hint stream: object 62 0, offset 1183): recovered stream length: 106
8 -linearization-bounds-2.pdf (linearization hint table, offset 1183): /S (shared object) offset is out of bounds 8 +WARNING: error encountered while checking linearization data: linearization-bounds-2.pdf (linearization hint table, offset 1183): /S (shared object) offset is out of bounds
qpdf/qtest/qpdf/linearization-large-vector-alloc.out
@@ -5,4 +5,4 @@ File is linearized @@ -5,4 +5,4 @@ File is linearized
5 WARNING: linearization-large-vector-alloc.pdf (linearization hint stream: object 62 0, offset 1282): expected endstream 5 WARNING: linearization-large-vector-alloc.pdf (linearization hint stream: object 62 0, offset 1282): expected endstream
6 WARNING: linearization-large-vector-alloc.pdf (linearization hint stream: object 62 0, offset 1183): attempting to recover stream length 6 WARNING: linearization-large-vector-alloc.pdf (linearization hint stream: object 62 0, offset 1183): attempting to recover stream length
7 WARNING: linearization-large-vector-alloc.pdf (linearization hint stream: object 62 0, offset 1183): recovered stream length: 106 7 WARNING: linearization-large-vector-alloc.pdf (linearization hint stream: object 62 0, offset 1183): recovered stream length: 106
8 -ERROR: overflow reading bit stream 8 +WARNING: error encountered while checking linearization data: overflow reading bit stream: wanted = 12556; available = 968