Commit 456c285b0277315537c0a402a8d35dff3bec3c10

Authored by Jay Berkenbilt
1 parent ad8081da

Fix fuzz issue 16172 (overflow checking in OffsetInputSource)

fuzz/qpdf_extra/16172.fuzz 0 → 100644
  1 + ÿ%PDF-1.4startxref 9223372036854775805
0 2 \ No newline at end of file
... ...
libqpdf/OffsetInputSource.cc
1 1 #include <qpdf/OffsetInputSource.hh>
  2 +#include <limits>
  3 +#include <sstream>
  4 +#include <stdexcept>
2 5  
3 6 OffsetInputSource::OffsetInputSource(PointerHolder<InputSource> proxied,
4 7 qpdf_offset_t global_offset) :
5 8 proxied(proxied),
6 9 global_offset(global_offset)
7 10 {
  11 + if (global_offset < 0)
  12 + {
  13 + throw std::logic_error(
  14 + "OffsetInputSource constructed with negative offset");
  15 + }
  16 + this->max_safe_offset =
  17 + std::numeric_limits<qpdf_offset_t>::max() - global_offset;
8 18 }
9 19  
10 20 OffsetInputSource::~OffsetInputSource()
... ... @@ -34,12 +44,25 @@ OffsetInputSource::seek(qpdf_offset_t offset, int whence)
34 44 {
35 45 if (whence == SEEK_SET)
36 46 {
  47 + if (offset > this->max_safe_offset)
  48 + {
  49 + std::ostringstream msg;
  50 + msg << "seeking to " << offset
  51 + << " offset by " << global_offset
  52 + << " would cause an overflow of the offset type";
  53 + throw std::range_error(msg.str());
  54 + }
37 55 this->proxied->seek(offset + global_offset, whence);
38 56 }
39 57 else
40 58 {
41 59 this->proxied->seek(offset, whence);
42 60 }
  61 + if (tell() < 0)
  62 + {
  63 + throw std::runtime_error(
  64 + "offset input source: seek before beginning of file");
  65 + }
43 66 }
44 67  
45 68 void
... ...
libqpdf/qpdf/OffsetInputSource.hh
... ... @@ -24,6 +24,7 @@ class OffsetInputSource: public InputSource
24 24 private:
25 25 PointerHolder<InputSource> proxied;
26 26 qpdf_offset_t global_offset;
  27 + qpdf_offset_t max_safe_offset;
27 28 };
28 29  
29 30 #endif // QPDF_OFFSETINPUTSOURCE_HH
... ...