Commit 2856b288e4d2fff3d181e367cfd9a6ef7b555efb

Authored by m-holger
Committed by GitHub
2 parents 34f557a8 3bab4cf3

Merge pull request #1258 from m-holger/fuzz

Adjust fuzzer memory limits and refactor Pl_RunLength::decode
fuzz/CMakeLists.txt
... ... @@ -100,6 +100,7 @@ set(CORPUS_OTHER
100 100 16953.fuzz
101 101 17630.fuzz
102 102 17630a.fuzz
  103 + 17630b.fuzz
103 104 18241.fuzz
104 105 18247.fuzz
105 106 23172.fuzz
... ... @@ -128,6 +129,7 @@ set(CORPUS_OTHER
128 129 69977b.fuzz
129 130 69977c.fuzz
130 131 69977d.fuzz
  132 + 69977e.fuzz
131 133 70055.fuzz
132 134 70245.fuzz
133 135 70306.fuzz
... ...
fuzz/dct_fuzzer.cc
... ... @@ -30,7 +30,7 @@ FuzzHelper::doChecks()
30 30 // fuzzing is due to corrupt JPEG data which sometimes cannot be detected before
31 31 // jpeg_start_decompress is called. During normal use of qpdf very large JPEGs can occasionally
32 32 // occur legitimately and therefore must be allowed during normal operations.
33   - Pl_DCT::setMemoryLimit(1'000'000'000);
  33 + Pl_DCT::setMemoryLimit(200'000'000);
34 34  
35 35 // Do not decompress corrupt data. This may cause extended runtime within jpeglib without
36 36 // exercising additional code paths in qpdf.
... ...
fuzz/qpdf_extra/17630b.fuzz 0 → 100644
No preview for this file type
fuzz/qpdf_extra/69977e.fuzz 0 → 100644
No preview for this file type
fuzz/qpdf_fuzzer.cc
... ... @@ -180,11 +180,11 @@ FuzzHelper::doChecks()
180 180 // fuzzing is due to corrupt JPEG data which sometimes cannot be detected before
181 181 // jpeg_start_decompress is called. During normal use of qpdf very large JPEGs can occasionally
182 182 // occur legitimately and therefore must be allowed during normal operations.
183   - Pl_DCT::setMemoryLimit(1'000'000'000);
  183 + Pl_DCT::setMemoryLimit(100'000'000);
184 184  
185 185 Pl_PNGFilter::setMemoryLimit(1'000'000);
186 186 Pl_TIFFPredictor::setMemoryLimit(1'000'000);
187   - Pl_Flate::setMemoryLimit(10'000'000);
  187 + Pl_Flate::setMemoryLimit(1'000'000);
188 188  
189 189 // Do not decompress corrupt data. This may cause extended runtime within jpeglib without
190 190 // exercising additional code paths in qpdf, and potentially causing counterproductive timeouts.
... ...
fuzz/qtest/fuzz.test
... ... @@ -21,7 +21,7 @@ my @fuzzers = (
21 21 ['pngpredictor' => 1],
22 22 ['runlength' => 6],
23 23 ['tiffpredictor' => 2],
24   - ['qpdf' => 73], # increment when adding new files
  24 + ['qpdf' => 75], # increment when adding new files
25 25 );
26 26  
27 27 my $n_tests = 0;
... ...
include/qpdf/Pl_RunLength.hh
... ... @@ -62,6 +62,7 @@ class QPDF_DLL_CLASS Pl_RunLength: public Pipeline
62 62 state_e state;
63 63 unsigned char buf[128];
64 64 unsigned int length;
  65 + std::string out;
65 66 };
66 67  
67 68 std::shared_ptr<Members> m;
... ...
libqpdf/Pl_RunLength.cc
... ... @@ -66,8 +66,9 @@ Pl_RunLength::encode(unsigned char const* data, size_t len)
66 66 void
67 67 Pl_RunLength::decode(unsigned char const* data, size_t len)
68 68 {
  69 + m->out.reserve(len);
69 70 for (size_t i = 0; i < len; ++i) {
70   - unsigned char ch = data[i];
  71 + unsigned char const& ch = data[i];
71 72 switch (m->state) {
72 73 case st_top:
73 74 if (ch < 128) {
... ... @@ -85,16 +86,14 @@ Pl_RunLength::decode(unsigned char const* data, size_t len)
85 86 break;
86 87  
87 88 case st_copying:
88   - this->getNext()->write(&ch, 1);
  89 + m->out.append(1, static_cast<char>(ch));
89 90 if (--m->length == 0) {
90 91 m->state = st_top;
91 92 }
92 93 break;
93 94  
94 95 case st_run:
95   - for (unsigned int j = 0; j < m->length; ++j) {
96   - this->getNext()->write(&ch, 1);
97   - }
  96 + m->out.append(m->length, static_cast<char>(ch));
98 97 m->state = st_top;
99 98 break;
100 99 }
... ... @@ -137,10 +136,13 @@ Pl_RunLength::finish()
137 136 // When decoding, we might have read a length byte not followed by data, which means the stream
138 137 // was terminated early, but we will just ignore this case since this is the only sensible thing
139 138 // to do.
  139 + auto next = getNext();
140 140 if (m->action == a_encode) {
141 141 flush_encode();
142 142 unsigned char ch = 128;
143   - this->getNext()->write(&ch, 1);
  143 + next->write(&ch, 1);
  144 + } else {
  145 + next->writeString(m->out);
144 146 }
145   - this->getNext()->finish();
  147 + next->finish();
146 148 }
... ...