| @@ -1,31 +1,79 @@ | | | @@ -1,31 +1,79 @@ |
1 | $NetBSD: patch-src_glyphs-eimage.c,v 1.1 2011/04/01 13:00:32 wiz Exp $ | | 1 | $NetBSD: patch-src_glyphs-eimage.c,v 1.2 2012/04/27 14:37:37 hauke Exp $ |
2 | | | 2 | |
3 | Fix build with png-1.5. | | 3 | Fix CVE-2009-2688, via <https://bugzilla.redhat.com/show_bug.cgi?id=511994> |
| | | 4 | |
| | | 5 | Adapt to new libpng 1.5 interfaces |
4 | | | 6 | |
5 | --- src/glyphs-eimage.c.orig 2005-11-26 11:46:08.000000000 +0000 | | 7 | --- src/glyphs-eimage.c.orig 2005-11-26 11:46:08.000000000 +0000 |
6 | +++ src/glyphs-eimage.c | | 8 | +++ src/glyphs-eimage.c |
7 | @@ -929,8 +929,8 @@ png_instantiate (Lisp_Object image_insta | | 9 | @@ -401,6 +401,7 @@ jpeg_instantiate (Lisp_Object image_inst |
| | | 10 | */ |
| | | 11 | |
| | | 12 | { |
| | | 13 | + UINT_64_BIT pixels_sq; |
| | | 14 | int jpeg_gray = 0; /* if we're dealing with a grayscale */ |
| | | 15 | /* Step 4: set parameters for decompression. */ |
| | | 16 | |
| | | 17 | @@ -423,7 +424,10 @@ jpeg_instantiate (Lisp_Object image_inst |
| | | 18 | jpeg_start_decompress (&cinfo); |
| | | 19 | |
| | | 20 | /* Step 6: Read in the data and put into EImage format (8bit RGB triples)*/ |
| | | 21 | - |
| | | 22 | + pixels_sq = |
| | | 23 | + (UINT_64_BIT) cinfo.output_width * (UINT_64_BIT) cinfo.output_height; |
| | | 24 | + if (pixels_sq > ((size_t) -1) / 3) |
| | | 25 | + signal_image_error ("JPEG image too large to instantiate", instantiator); |
| | | 26 | unwind.eimage = |
| | | 27 | xnew_binbytes (cinfo.output_width * cinfo.output_height * 3); |
| | | 28 | if (!unwind.eimage) |
| | | 29 | @@ -669,6 +673,7 @@ gif_instantiate (Lisp_Object image_insta |
| | | 30 | { |
| | | 31 | ColorMapObject *cmo = unwind.giffile->SColorMap; |
| | | 32 | int i, j, row, pass, interlace, slice; |
| | | 33 | + UINT_64_BIT pixels_sq; |
| | | 34 | Binbyte *eip; |
| | | 35 | /* interlaced gifs have rows in this order: |
| | | 36 | 0, 8, 16, ..., 4, 12, 20, ..., 2, 6, 10, ..., 1, 3, 5, ... */ |
| | | 37 | @@ -677,6 +682,9 @@ gif_instantiate (Lisp_Object image_insta |
| | | 38 | |
| | | 39 | height = unwind.giffile->SHeight; |
| | | 40 | width = unwind.giffile->SWidth; |
| | | 41 | + pixels_sq = (UINT_64_BIT) width * (UINT_64_BIT) height; |
| | | 42 | + if (pixels_sq > ((size_t) -1) / (3 * unwind.giffile->ImageCount)) |
| | | 43 | + signal_image_error ("GIF image too large to instantiate", instantiator); |
| | | 44 | unwind.eimage = |
| | | 45 | xnew_binbytes (width * height * 3 * unwind.giffile->ImageCount); |
| | | 46 | if (!unwind.eimage) |
| | | 47 | @@ -929,11 +937,15 @@ png_instantiate (Lisp_Object image_insta |
8 | { | | 48 | { |
9 | int y; | | 49 | int y; |
10 | Binbyte **row_pointers; | | 50 | Binbyte **row_pointers; |
11 | - height = info_ptr->height; | | 51 | - height = info_ptr->height; |
12 | - width = info_ptr->width; | | 52 | - width = info_ptr->width; |
| | | 53 | + UINT_64_BIT pixels_sq; |
13 | + height = png_get_image_height(png_ptr, info_ptr); | | 54 | + height = png_get_image_height(png_ptr, info_ptr); |
14 | + width = png_get_image_width(png_ptr, info_ptr); | | 55 | + width = png_get_image_width(png_ptr, info_ptr); |
| | | 56 | + pixels_sq = (UINT_64_BIT) width * (UINT_64_BIT) height; |
| | | 57 | + if (pixels_sq > ((size_t) -1) / 3) |
| | | 58 | + signal_image_error ("PNG image too large to instantiate", instantiator); |
15 | | | 59 | |
16 | /* Wow, allocate all the memory. Truly, exciting. */ | | 60 | /* Wow, allocate all the memory. Truly, exciting. */ |
17 | unwind.eimage = xnew_array_and_zero (Binbyte, width * height * 3); | | 61 | - unwind.eimage = xnew_array_and_zero (Binbyte, width * height * 3); |
18 | @@ -982,22 +982,22 @@ png_instantiate (Lisp_Object image_insta | | 62 | + unwind.eimage = xnew_array_and_zero (Binbyte, (size_t) (pixels_sq * 3)); |
| | | 63 | /* libpng expects that the image buffer passed in contains a |
| | | 64 | picture to draw on top of if the png has any transparencies. |
| | | 65 | This could be a good place to pass that in... */ |
| | | 66 | @@ -982,22 +994,22 @@ png_instantiate (Lisp_Object image_insta |
19 | /* Now that we're using EImage, ask for 8bit RGB triples for any type | | 67 | /* Now that we're using EImage, ask for 8bit RGB triples for any type |
20 | of image*/ | | 68 | of image*/ |
21 | /* convert palette images to full RGB */ | | 69 | /* convert palette images to full RGB */ |
22 | - if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) | | 70 | - if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) |
23 | + if (png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_PALETTE) | | 71 | + if (png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_PALETTE) |
24 | png_set_expand (png_ptr); | | 72 | png_set_expand (png_ptr); |
25 | /* send grayscale images to RGB too */ | | 73 | /* send grayscale images to RGB too */ |
26 | - if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY || | | 74 | - if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY || |
27 | - info_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) | | 75 | - info_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) |
28 | + if (png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_GRAY || | | 76 | + if (png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_GRAY || |
29 | + png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_GRAY_ALPHA) | | 77 | + png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_GRAY_ALPHA) |
30 | png_set_gray_to_rgb (png_ptr); | | 78 | png_set_gray_to_rgb (png_ptr); |
31 | /* we can't handle alpha values */ | | 79 | /* we can't handle alpha values */ |
| @@ -35,38 +83,64 @@ Fix build with png-1.5. | | | @@ -35,38 +83,64 @@ Fix build with png-1.5. |
35 | /* tell libpng to strip 16 bit depth files down to 8 bits */ | | 83 | /* tell libpng to strip 16 bit depth files down to 8 bits */ |
36 | - if (info_ptr->bit_depth == 16) | | 84 | - if (info_ptr->bit_depth == 16) |
37 | + if (png_get_bit_depth(png_ptr, info_ptr) == 16) | | 85 | + if (png_get_bit_depth(png_ptr, info_ptr) == 16) |
38 | png_set_strip_16 (png_ptr); | | 86 | png_set_strip_16 (png_ptr); |
39 | /* if the image is < 8 bits, pad it out */ | | 87 | /* if the image is < 8 bits, pad it out */ |
40 | - if (info_ptr->bit_depth < 8) | | 88 | - if (info_ptr->bit_depth < 8) |
41 | + if (png_get_bit_depth(png_ptr, info_ptr) < 8) | | 89 | + if (png_get_bit_depth(png_ptr, info_ptr) < 8) |
42 | { | | 90 | { |
43 | - if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY) | | 91 | - if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY) |
44 | + if (png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_GRAY) | | 92 | + if (png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_GRAY) |
45 | png_set_expand (png_ptr); | | 93 | png_set_expand (png_ptr); |
46 | else | | 94 | else |
47 | png_set_packing (png_ptr); | | 95 | png_set_packing (png_ptr); |
48 | @@ -1018,16 +1018,20 @@ png_instantiate (Lisp_Object image_insta | | 96 | @@ -1018,16 +1030,20 @@ png_instantiate (Lisp_Object image_insta |
49 | unobtrusive. */ | | 97 | unobtrusive. */ |
50 | { | | 98 | { |
51 | int i; | | 99 | int i; |
52 | + png_textp text_ptr; | | 100 | + png_textp text_ptr; |
53 | + int num_text; | | 101 | + int num_text; |
| | | 102 | + |
| | | 103 | + png_get_text(png_ptr, info_ptr, &text_ptr, &num_text); |
54 | | | 104 | |
55 | - for (i = 0 ; i < info_ptr->num_text ; i++) | | 105 | - for (i = 0 ; i < info_ptr->num_text ; i++) |
56 | + png_get_text(png_ptr, info_ptr, &text_ptr, &num_text); | | | |
57 | + | | | |
58 | + for (i = 0 ; i < num_text ; i++) | | 106 | + for (i = 0 ; i < num_text ; i++) |
59 | { | | 107 | { |
60 | /* How paranoid do I have to be about no trailing NULLs, and | | 108 | /* How paranoid do I have to be about no trailing NULLs, and |
61 | - using (int)info_ptr->text[i].text_length, and strncpy and a temp | | 109 | - using (int)info_ptr->text[i].text_length, and strncpy and a temp |
62 | + using (int)text_ptr[i].text_length, and strncpy and a temp | | 110 | + using (int)text_ptr[i].text_length, and strncpy and a temp |
63 | string somewhere? */ | | 111 | string somewhere? */ |
64 | | | 112 | |
65 | warn_when_safe (Qpng, Qinfo, "%s - %s", | | 113 | warn_when_safe (Qpng, Qinfo, "%s - %s", |
66 | - info_ptr->text[i].key, | | 114 | - info_ptr->text[i].key, |
67 | - info_ptr->text[i].text); | | 115 | - info_ptr->text[i].text); |
68 | + text_ptr[i].key, | | 116 | + text_ptr[i].key, |
69 | + text_ptr[i].text); | | 117 | + text_ptr[i].text); |
70 | } | | 118 | } |
71 | } | | 119 | } |
72 | #endif | | 120 | #endif |
| | | 121 | @@ -1268,6 +1284,7 @@ tiff_instantiate (Lisp_Object image_inst |
| | | 122 | |
| | | 123 | uint32 *raster; |
| | | 124 | Binbyte *ep; |
| | | 125 | + UINT_64_BIT pixels_sq; |
| | | 126 | |
| | | 127 | assert (!NILP (data)); |
| | | 128 | |
| | | 129 | @@ -1290,12 +1307,15 @@ tiff_instantiate (Lisp_Object image_inst |
| | | 130 | |
| | | 131 | TIFFGetField (unwind.tiff, TIFFTAG_IMAGEWIDTH, &width); |
| | | 132 | TIFFGetField (unwind.tiff, TIFFTAG_IMAGELENGTH, &height); |
| | | 133 | - unwind.eimage = xnew_binbytes (width * height * 3); |
| | | 134 | + pixels_sq = (UINT_64_BIT) width * (UINT_64_BIT) height; |
| | | 135 | + if (pixels_sq >= 1 << 29) |
| | | 136 | + signal_image_error ("TIFF image too large to instantiate", instantiator); |
| | | 137 | + unwind.eimage = xnew_binbytes (pixels_sq * 3); |
| | | 138 | |
| | | 139 | /* #### This is little more than proof-of-concept/function testing. |
| | | 140 | It needs to be reimplemented via scanline reads for both memory |
| | | 141 | compactness. */ |
| | | 142 | - raster = (uint32*) _TIFFmalloc (width * height * sizeof (uint32)); |
| | | 143 | + raster = (uint32*) _TIFFmalloc ((tsize_t) (pixels_sq * sizeof (uint32))); |
| | | 144 | if (raster != NULL) |
| | | 145 | { |
| | | 146 | int i, j; |