mirror of
https://github.com/qpdf/qpdf.git
synced 2024-12-22 19:08:59 +00:00
Merge pull request #1258 from m-holger/fuzz
Adjust fuzzer memory limits and refactor Pl_RunLength::decode
This commit is contained in:
commit
2856b288e4
@ -100,6 +100,7 @@ set(CORPUS_OTHER
|
|||||||
16953.fuzz
|
16953.fuzz
|
||||||
17630.fuzz
|
17630.fuzz
|
||||||
17630a.fuzz
|
17630a.fuzz
|
||||||
|
17630b.fuzz
|
||||||
18241.fuzz
|
18241.fuzz
|
||||||
18247.fuzz
|
18247.fuzz
|
||||||
23172.fuzz
|
23172.fuzz
|
||||||
@ -128,6 +129,7 @@ set(CORPUS_OTHER
|
|||||||
69977b.fuzz
|
69977b.fuzz
|
||||||
69977c.fuzz
|
69977c.fuzz
|
||||||
69977d.fuzz
|
69977d.fuzz
|
||||||
|
69977e.fuzz
|
||||||
70055.fuzz
|
70055.fuzz
|
||||||
70245.fuzz
|
70245.fuzz
|
||||||
70306.fuzz
|
70306.fuzz
|
||||||
|
@ -30,7 +30,7 @@ FuzzHelper::doChecks()
|
|||||||
// fuzzing is due to corrupt JPEG data which sometimes cannot be detected before
|
// fuzzing is due to corrupt JPEG data which sometimes cannot be detected before
|
||||||
// jpeg_start_decompress is called. During normal use of qpdf very large JPEGs can occasionally
|
// jpeg_start_decompress is called. During normal use of qpdf very large JPEGs can occasionally
|
||||||
// occur legitimately and therefore must be allowed during normal operations.
|
// occur legitimately and therefore must be allowed during normal operations.
|
||||||
Pl_DCT::setMemoryLimit(1'000'000'000);
|
Pl_DCT::setMemoryLimit(200'000'000);
|
||||||
|
|
||||||
// Do not decompress corrupt data. This may cause extended runtime within jpeglib without
|
// Do not decompress corrupt data. This may cause extended runtime within jpeglib without
|
||||||
// exercising additional code paths in qpdf.
|
// exercising additional code paths in qpdf.
|
||||||
|
BIN
fuzz/qpdf_extra/17630b.fuzz
Normal file
BIN
fuzz/qpdf_extra/17630b.fuzz
Normal file
Binary file not shown.
BIN
fuzz/qpdf_extra/69977e.fuzz
Normal file
BIN
fuzz/qpdf_extra/69977e.fuzz
Normal file
Binary file not shown.
@ -180,11 +180,11 @@ FuzzHelper::doChecks()
|
|||||||
// fuzzing is due to corrupt JPEG data which sometimes cannot be detected before
|
// fuzzing is due to corrupt JPEG data which sometimes cannot be detected before
|
||||||
// jpeg_start_decompress is called. During normal use of qpdf very large JPEGs can occasionally
|
// jpeg_start_decompress is called. During normal use of qpdf very large JPEGs can occasionally
|
||||||
// occur legitimately and therefore must be allowed during normal operations.
|
// occur legitimately and therefore must be allowed during normal operations.
|
||||||
Pl_DCT::setMemoryLimit(1'000'000'000);
|
Pl_DCT::setMemoryLimit(100'000'000);
|
||||||
|
|
||||||
Pl_PNGFilter::setMemoryLimit(1'000'000);
|
Pl_PNGFilter::setMemoryLimit(1'000'000);
|
||||||
Pl_TIFFPredictor::setMemoryLimit(1'000'000);
|
Pl_TIFFPredictor::setMemoryLimit(1'000'000);
|
||||||
Pl_Flate::setMemoryLimit(10'000'000);
|
Pl_Flate::setMemoryLimit(1'000'000);
|
||||||
|
|
||||||
// Do not decompress corrupt data. This may cause extended runtime within jpeglib without
|
// Do not decompress corrupt data. This may cause extended runtime within jpeglib without
|
||||||
// exercising additional code paths in qpdf, and potentially causing counterproductive timeouts.
|
// exercising additional code paths in qpdf, and potentially causing counterproductive timeouts.
|
||||||
|
@ -21,7 +21,7 @@ my @fuzzers = (
|
|||||||
['pngpredictor' => 1],
|
['pngpredictor' => 1],
|
||||||
['runlength' => 6],
|
['runlength' => 6],
|
||||||
['tiffpredictor' => 2],
|
['tiffpredictor' => 2],
|
||||||
['qpdf' => 73], # increment when adding new files
|
['qpdf' => 75], # increment when adding new files
|
||||||
);
|
);
|
||||||
|
|
||||||
my $n_tests = 0;
|
my $n_tests = 0;
|
||||||
|
@ -62,6 +62,7 @@ class QPDF_DLL_CLASS Pl_RunLength: public Pipeline
|
|||||||
state_e state;
|
state_e state;
|
||||||
unsigned char buf[128];
|
unsigned char buf[128];
|
||||||
unsigned int length;
|
unsigned int length;
|
||||||
|
std::string out;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::shared_ptr<Members> m;
|
std::shared_ptr<Members> m;
|
||||||
|
@ -66,8 +66,9 @@ Pl_RunLength::encode(unsigned char const* data, size_t len)
|
|||||||
void
|
void
|
||||||
Pl_RunLength::decode(unsigned char const* data, size_t len)
|
Pl_RunLength::decode(unsigned char const* data, size_t len)
|
||||||
{
|
{
|
||||||
|
m->out.reserve(len);
|
||||||
for (size_t i = 0; i < len; ++i) {
|
for (size_t i = 0; i < len; ++i) {
|
||||||
unsigned char ch = data[i];
|
unsigned char const& ch = data[i];
|
||||||
switch (m->state) {
|
switch (m->state) {
|
||||||
case st_top:
|
case st_top:
|
||||||
if (ch < 128) {
|
if (ch < 128) {
|
||||||
@ -85,16 +86,14 @@ Pl_RunLength::decode(unsigned char const* data, size_t len)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case st_copying:
|
case st_copying:
|
||||||
this->getNext()->write(&ch, 1);
|
m->out.append(1, static_cast<char>(ch));
|
||||||
if (--m->length == 0) {
|
if (--m->length == 0) {
|
||||||
m->state = st_top;
|
m->state = st_top;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case st_run:
|
case st_run:
|
||||||
for (unsigned int j = 0; j < m->length; ++j) {
|
m->out.append(m->length, static_cast<char>(ch));
|
||||||
this->getNext()->write(&ch, 1);
|
|
||||||
}
|
|
||||||
m->state = st_top;
|
m->state = st_top;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -137,10 +136,13 @@ Pl_RunLength::finish()
|
|||||||
// When decoding, we might have read a length byte not followed by data, which means the stream
|
// When decoding, we might have read a length byte not followed by data, which means the stream
|
||||||
// was terminated early, but we will just ignore this case since this is the only sensible thing
|
// was terminated early, but we will just ignore this case since this is the only sensible thing
|
||||||
// to do.
|
// to do.
|
||||||
|
auto next = getNext();
|
||||||
if (m->action == a_encode) {
|
if (m->action == a_encode) {
|
||||||
flush_encode();
|
flush_encode();
|
||||||
unsigned char ch = 128;
|
unsigned char ch = 128;
|
||||||
this->getNext()->write(&ch, 1);
|
next->write(&ch, 1);
|
||||||
|
} else {
|
||||||
|
next->writeString(m->out);
|
||||||
}
|
}
|
||||||
this->getNext()->finish();
|
next->finish();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user