Mercurial > hg > xemacs-beta
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; |