@@ -141,6 +141,21 @@ uint8* UncompressLow(const void* srcdata, FewerArgsForCompiler* argball) {
141141
142142 jpeg_start_decompress (&cinfo);
143143
144+ int64 total_size = static_cast <int64>(cinfo.output_height ) *
145+ static_cast <int64>(cinfo.output_width );
146+ // Some of the internal routines do not gracefully handle ridiculously
147+ // large images, so fail fast.
148+ if (cinfo.output_width <= 0 || cinfo.output_height <= 0 ) {
149+ LOG (ERROR) << " Invalid image size: " << cinfo.output_width << " x "
150+ << cinfo.output_height ;
151+ return nullptr ;
152+ }
153+ if (total_size >= (1LL << 29 )) {
154+ LOG (ERROR) << " Image too large: " << total_size;
155+ jpeg_destroy_decompress (&cinfo);
156+ return nullptr ;
157+ }
158+
144159 // check for compatible stride
145160 const int min_stride = cinfo.output_width * components * sizeof (JSAMPLE);
146161 if (stride == 0 ) {
@@ -405,6 +420,19 @@ bool CompressInternal(const uint8* srcdata, int width, int height,
405420 const CompressFlags& flags, string* output) {
406421 output->clear ();
407422 const int components = (static_cast <int >(flags.format ) & 0xff );
423+
424+ int64 total_size = static_cast <int64>(width) * static_cast <int64>(height);
425+ // Some of the internal routines do not gracefully handle ridiculously
426+ // large images, so fail fast.
427+ if (width <= 0 || height <= 0 ) {
428+ LOG (ERROR) << " Invalid image size: " << width << " x " << height;
429+ return false ;
430+ }
431+ if (total_size >= (1LL << 29 )) {
432+ LOG (ERROR) << " Image too large: " << total_size;
433+ return false ;
434+ }
435+
408436 int in_stride = flags.stride ;
409437 if (in_stride == 0 ) {
410438 in_stride = width * (static_cast <int >(flags.format ) & 0xff );
0 commit comments