comparison src/glyphs-eimage.c @ 4646:6c6bfdb80a0c

Prevent integer overflow and subsequent crashes when attempting to load large images. See <870180fe0907011540m7509f371h97d336477145166a@mail.gmail.com> in xemacs-patches.
author Jerry James <james@xemacs.org>
date Wed, 01 Jul 2009 16:42:11 -0600
parents a5ff7e67ac1b
children 648f4a0dac3e
comparison
equal deleted inserted replaced
4645:f2a991ff6db0 4646:6c6bfdb80a0c
407 * (b) we passed TRUE to reject a tables-only JPEG file as an error. 407 * (b) we passed TRUE to reject a tables-only JPEG file as an error.
408 * See libjpeg.doc for more info. 408 * See libjpeg.doc for more info.
409 */ 409 */
410 410
411 { 411 {
412 UINT_64_BIT pixels_sq;
412 int jpeg_gray = 0; /* if we're dealing with a grayscale */ 413 int jpeg_gray = 0; /* if we're dealing with a grayscale */
413 /* Step 4: set parameters for decompression. */ 414 /* Step 4: set parameters for decompression. */
414 415
415 /* Now that we're using EImages, send all data as 24bit color. 416 /* Now that we're using EImages, send all data as 24bit color.
416 The backend routine will take care of any necessary reductions. 417 The backend routine will take care of any necessary reductions.
429 430
430 /* Step 5: Start decompressor */ 431 /* Step 5: Start decompressor */
431 jpeg_start_decompress (&cinfo); 432 jpeg_start_decompress (&cinfo);
432 433
433 /* Step 6: Read in the data and put into EImage format (8bit RGB triples)*/ 434 /* Step 6: Read in the data and put into EImage format (8bit RGB triples)*/
434 435 pixels_sq =
436 (UINT_64_BIT) cinfo.output_width * (UINT_64_BIT) cinfo.output_height;
437 if (pixels_sq > ((size_t) -1) / 3)
438 signal_image_error ("JPEG image too large to instantiate", instantiator);
435 unwind.eimage = 439 unwind.eimage =
436 xnew_binbytes (cinfo.output_width * cinfo.output_height * 3); 440 xnew_binbytes (cinfo.output_width * cinfo.output_height * 3);
437 if (!unwind.eimage) 441 if (!unwind.eimage)
438 signal_image_error("Unable to allocate enough memory for image", instantiator); 442 signal_image_error("Unable to allocate enough memory for image", instantiator);
439 443
675 679
676 /* 3. Now create the EImage(s) */ 680 /* 3. Now create the EImage(s) */
677 { 681 {
678 ColorMapObject *cmo = unwind.giffile->SColorMap; 682 ColorMapObject *cmo = unwind.giffile->SColorMap;
679 int i, j, row, pass, interlace, slice; 683 int i, j, row, pass, interlace, slice;
684 UINT_64_BIT pixels_sq;
680 Binbyte *eip; 685 Binbyte *eip;
681 /* interlaced gifs have rows in this order: 686 /* interlaced gifs have rows in this order:
682 0, 8, 16, ..., 4, 12, 20, ..., 2, 6, 10, ..., 1, 3, 5, ... */ 687 0, 8, 16, ..., 4, 12, 20, ..., 2, 6, 10, ..., 1, 3, 5, ... */
683 static int InterlacedOffset[] = { 0, 4, 2, 1 }; 688 static int InterlacedOffset[] = { 0, 4, 2, 1 };
684 static int InterlacedJumps[] = { 8, 8, 4, 2 }; 689 static int InterlacedJumps[] = { 8, 8, 4, 2 };
685 690
686 height = unwind.giffile->SHeight; 691 height = unwind.giffile->SHeight;
687 width = unwind.giffile->SWidth; 692 width = unwind.giffile->SWidth;
693 pixels_sq = (UINT_64_BIT) width * (UINT_64_BIT) height;
694 if (pixels_sq > ((size_t) -1) / (3 * unwind.giffile->ImageCount))
695 signal_image_error ("GIF image too large to instantiate", instantiator);
688 unwind.eimage = 696 unwind.eimage =
689 xnew_binbytes (width * height * 3 * unwind.giffile->ImageCount); 697 xnew_binbytes (width * height * 3 * unwind.giffile->ImageCount);
690 if (!unwind.eimage) 698 if (!unwind.eimage)
691 signal_image_error("Unable to allocate enough memory for image", instantiator); 699 signal_image_error("Unable to allocate enough memory for image", instantiator);
692 700
946 png_read_info (png_ptr, info_ptr); 954 png_read_info (png_ptr, info_ptr);
947 955
948 { 956 {
949 int y; 957 int y;
950 Binbyte **row_pointers; 958 Binbyte **row_pointers;
959 UINT_64_BIT pixels_sq;
951 height = info_ptr->height; 960 height = info_ptr->height;
952 width = info_ptr->width; 961 width = info_ptr->width;
962 pixels_sq = (UINT_64_BIT) width * (UINT_64_BIT) height;
963 if (pixels_sq > ((size_t) -1) / 3)
964 signal_image_error ("PNG image too large to instantiate", instantiator);
953 965
954 /* Wow, allocate all the memory. Truly, exciting. */ 966 /* Wow, allocate all the memory. Truly, exciting. */
955 unwind.eimage = xnew_array_and_zero (Binbyte, width * height * 3); 967 unwind.eimage = xnew_array_and_zero (Binbyte, (size_t) (pixels_sq * 3));
956 /* libpng expects that the image buffer passed in contains a 968 /* libpng expects that the image buffer passed in contains a
957 picture to draw on top of if the png has any transparencies. 969 picture to draw on top of if the png has any transparencies.
958 This could be a good place to pass that in... */ 970 This could be a good place to pass that in... */
959 971
960 row_pointers = xnew_array (png_byte *, height); 972 row_pointers = xnew_array (png_byte *, height);
1297 Binbyte *bytes; 1309 Binbyte *bytes;
1298 Bytecount len; 1310 Bytecount len;
1299 1311
1300 uint32 *raster; 1312 uint32 *raster;
1301 Binbyte *ep; 1313 Binbyte *ep;
1314 UINT_64_BIT pixels_sq;
1302 1315
1303 assert (!NILP (data)); 1316 assert (!NILP (data));
1304 1317
1305 /* #### This is a definite problem under Mule due to the amount of 1318 /* #### This is a definite problem under Mule due to the amount of
1306 stack data it might allocate. Think about Lstreams... */ 1319 stack data it might allocate. Think about Lstreams... */
1319 if (!unwind.tiff) 1332 if (!unwind.tiff)
1320 signal_image_error ("Insufficient memory to instantiate TIFF image", instantiator); 1333 signal_image_error ("Insufficient memory to instantiate TIFF image", instantiator);
1321 1334
1322 TIFFGetField (unwind.tiff, TIFFTAG_IMAGEWIDTH, &width); 1335 TIFFGetField (unwind.tiff, TIFFTAG_IMAGEWIDTH, &width);
1323 TIFFGetField (unwind.tiff, TIFFTAG_IMAGELENGTH, &height); 1336 TIFFGetField (unwind.tiff, TIFFTAG_IMAGELENGTH, &height);
1324 unwind.eimage = xnew_binbytes (width * height * 3); 1337 pixels_sq = (UINT_64_BIT) width * (UINT_64_BIT) height;
1338 if (pixels_sq >= 1 << 29)
1339 signal_image_error ("TIFF image too large to instantiate", instantiator);
1340 unwind.eimage = xnew_binbytes (pixels_sq * 3);
1325 1341
1326 /* #### This is little more than proof-of-concept/function testing. 1342 /* #### This is little more than proof-of-concept/function testing.
1327 It needs to be reimplemented via scanline reads for both memory 1343 It needs to be reimplemented via scanline reads for both memory
1328 compactness. */ 1344 compactness. */
1329 raster = (uint32*) _TIFFmalloc (width * height * sizeof (uint32)); 1345 raster = (uint32*) _TIFFmalloc ((tsize_t) (pixels_sq * sizeof (uint32)));
1330 if (raster != NULL) 1346 if (raster != NULL)
1331 { 1347 {
1332 int i, j; 1348 int i, j;
1333 uint32 *rp; 1349 uint32 *rp;
1334 ep = unwind.eimage; 1350 ep = unwind.eimage;