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 \ No newline at end of file 2 \ No newline at end of file
libqpdf/OffsetInputSource.cc
1 #include <qpdf/OffsetInputSource.hh> 1 #include <qpdf/OffsetInputSource.hh>
  2 +#include <limits>
  3 +#include <sstream>
  4 +#include <stdexcept>
2 5
3 OffsetInputSource::OffsetInputSource(PointerHolder<InputSource> proxied, 6 OffsetInputSource::OffsetInputSource(PointerHolder<InputSource> proxied,
4 qpdf_offset_t global_offset) : 7 qpdf_offset_t global_offset) :
5 proxied(proxied), 8 proxied(proxied),
6 global_offset(global_offset) 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 OffsetInputSource::~OffsetInputSource() 20 OffsetInputSource::~OffsetInputSource()
@@ -34,12 +44,25 @@ OffsetInputSource::seek(qpdf_offset_t offset, int whence) @@ -34,12 +44,25 @@ OffsetInputSource::seek(qpdf_offset_t offset, int whence)
34 { 44 {
35 if (whence == SEEK_SET) 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 this->proxied->seek(offset + global_offset, whence); 55 this->proxied->seek(offset + global_offset, whence);
38 } 56 }
39 else 57 else
40 { 58 {
41 this->proxied->seek(offset, whence); 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 void 68 void
libqpdf/qpdf/OffsetInputSource.hh
@@ -24,6 +24,7 @@ class OffsetInputSource: public InputSource @@ -24,6 +24,7 @@ class OffsetInputSource: public InputSource
24 private: 24 private:
25 PointerHolder<InputSource> proxied; 25 PointerHolder<InputSource> proxied;
26 qpdf_offset_t global_offset; 26 qpdf_offset_t global_offset;
  27 + qpdf_offset_t max_safe_offset;
27 }; 28 };
28 29
29 #endif // QPDF_OFFSETINPUTSOURCE_HH 30 #endif // QPDF_OFFSETINPUTSOURCE_HH