mirror of
https://github.com/qpdf/qpdf.git
synced 2024-11-09 23:00:57 +00:00
In qpdf_fuzzer and dct_fuzzer add a scan limit for Pl_DCT
This commit is contained in:
parent
ef49291682
commit
8ed10d71ea
@ -31,6 +31,7 @@ FuzzHelper::doChecks()
|
|||||||
// 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(200'000'000);
|
Pl_DCT::setMemoryLimit(200'000'000);
|
||||||
|
Pl_DCT::setScanLimit(50);
|
||||||
|
|
||||||
// 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.
|
||||||
|
@ -181,6 +181,7 @@ FuzzHelper::doChecks()
|
|||||||
// 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(100'000'000);
|
Pl_DCT::setMemoryLimit(100'000'000);
|
||||||
|
Pl_DCT::setScanLimit(50);
|
||||||
|
|
||||||
Pl_PNGFilter::setMemoryLimit(1'000'000);
|
Pl_PNGFilter::setMemoryLimit(1'000'000);
|
||||||
Pl_TIFFPredictor::setMemoryLimit(1'000'000);
|
Pl_TIFFPredictor::setMemoryLimit(1'000'000);
|
||||||
|
@ -39,6 +39,11 @@ class QPDF_DLL_CLASS Pl_DCT: public Pipeline
|
|||||||
QPDF_DLL
|
QPDF_DLL
|
||||||
static void setMemoryLimit(long limit);
|
static void setMemoryLimit(long limit);
|
||||||
|
|
||||||
|
// Limit the number of scans used by jpeglib when decompressing progressive jpegs.
|
||||||
|
// NB This is a static option affecting all Pl_DCT instances.
|
||||||
|
QPDF_DLL
|
||||||
|
static void setScanLimit(int limit);
|
||||||
|
|
||||||
// Treat corrupt data as a runtime error rather than attempting to decompress regardless. This
|
// Treat corrupt data as a runtime error rather than attempting to decompress regardless. This
|
||||||
// is the qpdf default behaviour. To attempt to decompress corrupt data set 'treat_as_error' to
|
// is the qpdf default behaviour. To attempt to decompress corrupt data set 'treat_as_error' to
|
||||||
// false.
|
// false.
|
||||||
|
@ -22,6 +22,7 @@ namespace
|
|||||||
};
|
};
|
||||||
|
|
||||||
long memory_limit{0};
|
long memory_limit{0};
|
||||||
|
int scan_limit{0};
|
||||||
bool throw_on_corrupt_data{true};
|
bool throw_on_corrupt_data{true};
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
@ -45,6 +46,17 @@ emit_message(j_common_ptr cinfo, int msg_level)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
progress_monitor(j_common_ptr cinfo)
|
||||||
|
{
|
||||||
|
if (cinfo->is_decompressor &&
|
||||||
|
reinterpret_cast<jpeg_decompress_struct*>(cinfo)->input_scan_number > scan_limit) {
|
||||||
|
auto* jerr = reinterpret_cast<qpdf_jpeg_error_mgr*>(cinfo->err);
|
||||||
|
jerr->msg = "Pl_DCT::decompress: JPEG data has too many scans";
|
||||||
|
longjmp(jerr->jmpbuf, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Pl_DCT::Members::Members() :
|
Pl_DCT::Members::Members() :
|
||||||
action(a_decompress),
|
action(a_decompress),
|
||||||
buf("DCT compressed image")
|
buf("DCT compressed image")
|
||||||
@ -74,6 +86,12 @@ Pl_DCT::setMemoryLimit(long limit)
|
|||||||
memory_limit = limit;
|
memory_limit = limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Pl_DCT::setScanLimit(int limit)
|
||||||
|
{
|
||||||
|
scan_limit = limit;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Pl_DCT::setThrowOnCorruptData(bool treat_as_error)
|
Pl_DCT::setThrowOnCorruptData(bool treat_as_error)
|
||||||
{
|
{
|
||||||
@ -341,6 +359,11 @@ Pl_DCT::decompress(void* cinfo_p, Buffer* b)
|
|||||||
// first warning is encountered causing a timeout in oss-fuzz.
|
// first warning is encountered causing a timeout in oss-fuzz.
|
||||||
throw std::runtime_error("Pl_DCT::decompress: JPEG data large - may be too slow");
|
throw std::runtime_error("Pl_DCT::decompress: JPEG data large - may be too slow");
|
||||||
}
|
}
|
||||||
|
jpeg_progress_mgr progress_mgr;
|
||||||
|
if (scan_limit > 0) {
|
||||||
|
progress_mgr.progress_monitor = &progress_monitor;
|
||||||
|
cinfo->progress = &progress_mgr;
|
||||||
|
}
|
||||||
JSAMPARRAY buffer =
|
JSAMPARRAY buffer =
|
||||||
(*cinfo->mem->alloc_sarray)(reinterpret_cast<j_common_ptr>(cinfo), JPOOL_IMAGE, width, 1);
|
(*cinfo->mem->alloc_sarray)(reinterpret_cast<j_common_ptr>(cinfo), JPOOL_IMAGE, width, 1);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user