297 lines
6.4 KiB
Diff
297 lines
6.4 KiB
Diff
|
|
HuffmanDecodeImage(): Fix signed overflow on range check which leads to heap overflow in 32-bit applications. Ascii85Tuple(): Fix thread safety issue.
|
|||
|
|
(CVE-2020-10938)
|
|||
|
|
|
|||
|
|
refers to http://hg.code.sf.net/p/graphicsmagick/code/rev/95abc2b694ce
|
|||
|
|
|
|||
|
|
diff -r 751e9e822b09 -r 95abc2b694ce magick/compress.c
|
|||
|
|
--- a/magick/compress.c Sun Nov 10 13:33:34 2019 -0600
|
|||
|
|
+++ b/magick/compress.c Sat Nov 16 10:31:37 2019 -0600
|
|||
|
|
@@ -1,5 +1,5 @@
|
|||
|
|
/*
|
|||
|
|
-% Copyright (C) 2003 - 2015 GraphicsMagick Group
|
|||
|
|
+% Copyright (C) 2003-2019 GraphicsMagick Group
|
|||
|
|
% Copyright (C) 2002 ImageMagick Studio
|
|||
|
|
% Copyright 1991-1999 E. I. du Pont de Nemours and Company
|
|||
|
|
%
|
|||
|
|
@@ -53,21 +53,26 @@
|
|||
|
|
*/
|
|||
|
|
typedef struct HuffmanTable
|
|||
|
|
{
|
|||
|
|
+ unsigned int
|
|||
|
|
+ id;
|
|||
|
|
+
|
|||
|
|
int
|
|||
|
|
- id,
|
|||
|
|
- code,
|
|||
|
|
+ code;
|
|||
|
|
+
|
|||
|
|
+ unsigned int
|
|||
|
|
length,
|
|||
|
|
count;
|
|||
|
|
+
|
|||
|
|
} HuffmanTable;
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
Huffman coding declarations.
|
|||
|
|
*/
|
|||
|
|
-#define TWId 23
|
|||
|
|
-#define MWId 24
|
|||
|
|
-#define TBId 25
|
|||
|
|
-#define MBId 26
|
|||
|
|
-#define EXId 27
|
|||
|
|
+#define TWId 23U
|
|||
|
|
+#define MWId 24U
|
|||
|
|
+#define TBId 25U
|
|||
|
|
+#define MBId 26U
|
|||
|
|
+#define EXId 27U
|
|||
|
|
|
|||
|
|
static const HuffmanTable
|
|||
|
|
MBTable[]=
|
|||
|
|
@@ -202,37 +207,38 @@
|
|||
|
|
*/
|
|||
|
|
#define MaxLineExtent 36
|
|||
|
|
|
|||
|
|
-static char *Ascii85Tuple(unsigned char *data)
|
|||
|
|
+static char *Ascii85Tuple(char tuple[6], const unsigned char * restrict data)
|
|||
|
|
{
|
|||
|
|
- static char
|
|||
|
|
- tuple[6];
|
|||
|
|
+ magick_uint32_t
|
|||
|
|
+ code;
|
|||
|
|
|
|||
|
|
- register long
|
|||
|
|
- i,
|
|||
|
|
- x;
|
|||
|
|
-
|
|||
|
|
- unsigned long
|
|||
|
|
- code,
|
|||
|
|
- quantum;
|
|||
|
|
-
|
|||
|
|
- code=((((unsigned long) data[0] << 8) | (unsigned long) data[1]) << 16) |
|
|||
|
|
- ((unsigned long) data[2] << 8) | (unsigned long) data[3];
|
|||
|
|
- if (code == 0L)
|
|||
|
|
+ code=((((magick_uint32_t) data[0] << 8) | (magick_uint32_t) data[1]) << 16) |
|
|||
|
|
+ ((magick_uint32_t) data[2] << 8) | (magick_uint32_t) data[3];
|
|||
|
|
+ if (code == 0)
|
|||
|
|
{
|
|||
|
|
tuple[0]='z';
|
|||
|
|
tuple[1]='\0';
|
|||
|
|
- return(tuple);
|
|||
|
|
}
|
|||
|
|
- quantum=85UL*85UL*85UL*85UL;
|
|||
|
|
- for (i=0; i < 4; i++)
|
|||
|
|
- {
|
|||
|
|
- x=(long) (code/quantum);
|
|||
|
|
- code-=quantum*x;
|
|||
|
|
- tuple[i]=(char) (x+(int) '!');
|
|||
|
|
- quantum/=85L;
|
|||
|
|
- }
|
|||
|
|
- tuple[4]=(char) ((code % 85L)+(int) '!');
|
|||
|
|
- tuple[5]='\0';
|
|||
|
|
+ else
|
|||
|
|
+ {
|
|||
|
|
+ register magick_int32_t
|
|||
|
|
+ i,
|
|||
|
|
+ x;
|
|||
|
|
+
|
|||
|
|
+ magick_uint32_t
|
|||
|
|
+ quantum;
|
|||
|
|
+
|
|||
|
|
+ quantum=85U*85U*85U*85U;
|
|||
|
|
+ for (i=0; i < 4; i++)
|
|||
|
|
+ {
|
|||
|
|
+ x=(magick_int32_t) (code/quantum);
|
|||
|
|
+ code-=quantum*x;
|
|||
|
|
+ tuple[i]=(char) (x+(int) '!');
|
|||
|
|
+ quantum/=85;
|
|||
|
|
+ }
|
|||
|
|
+ tuple[4]=(char) ((code % 85)+(int) '!');
|
|||
|
|
+ tuple[5]='\0';
|
|||
|
|
+ }
|
|||
|
|
return(tuple);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@@ -255,6 +261,9 @@
|
|||
|
|
|
|||
|
|
MagickExport void Ascii85Flush(Image *image)
|
|||
|
|
{
|
|||
|
|
+ char
|
|||
|
|
+ tuple_buff[6];
|
|||
|
|
+
|
|||
|
|
register char
|
|||
|
|
*tuple;
|
|||
|
|
|
|||
|
|
@@ -266,7 +275,7 @@
|
|||
|
|
image->ascii85->buffer[image->ascii85->offset]=0;
|
|||
|
|
image->ascii85->buffer[image->ascii85->offset+1]=0;
|
|||
|
|
image->ascii85->buffer[image->ascii85->offset+2]=0;
|
|||
|
|
- tuple=Ascii85Tuple(image->ascii85->buffer);
|
|||
|
|
+ tuple=Ascii85Tuple(tuple_buff, image->ascii85->buffer);
|
|||
|
|
(void) WriteBlob(image,image->ascii85->offset+1,
|
|||
|
|
*tuple == 'z' ? "!!!!" : tuple);
|
|||
|
|
}
|
|||
|
|
@@ -286,6 +295,9 @@
|
|||
|
|
register unsigned char
|
|||
|
|
*p;
|
|||
|
|
|
|||
|
|
+ char
|
|||
|
|
+ tuple_buff[6];
|
|||
|
|
+
|
|||
|
|
assert(image != (Image *) NULL);
|
|||
|
|
assert(image->signature == MagickSignature);
|
|||
|
|
assert(image->ascii85 != (Ascii85Info *) NULL);
|
|||
|
|
@@ -296,7 +308,7 @@
|
|||
|
|
p=image->ascii85->buffer;
|
|||
|
|
for (n=image->ascii85->offset; n >= 4; n-=4)
|
|||
|
|
{
|
|||
|
|
- for (q=Ascii85Tuple(p); *q; q++)
|
|||
|
|
+ for (q=Ascii85Tuple(tuple_buff,p); *q; q++)
|
|||
|
|
{
|
|||
|
|
image->ascii85->line_break--;
|
|||
|
|
if ((image->ascii85->line_break < 0) && (*q != '%'))
|
|||
|
|
@@ -355,11 +367,11 @@
|
|||
|
|
%
|
|||
|
|
%
|
|||
|
|
*/
|
|||
|
|
-#define HashSize 1021
|
|||
|
|
-#define MBHashA 293
|
|||
|
|
-#define MBHashB 2695
|
|||
|
|
-#define MWHashA 3510
|
|||
|
|
-#define MWHashB 1178
|
|||
|
|
+#define HashSize 1021U
|
|||
|
|
+#define MBHashA 293U
|
|||
|
|
+#define MBHashB 2695U
|
|||
|
|
+#define MWHashA 3510U
|
|||
|
|
+#define MWHashB 1178U
|
|||
|
|
|
|||
|
|
#define InitializeHashTable(hash,table,a,b) \
|
|||
|
|
{ \
|
|||
|
|
@@ -401,26 +413,30 @@
|
|||
|
|
byte,
|
|||
|
|
code,
|
|||
|
|
color,
|
|||
|
|
- length,
|
|||
|
|
null_lines,
|
|||
|
|
runlength;
|
|||
|
|
|
|||
|
|
unsigned int
|
|||
|
|
bit,
|
|||
|
|
index,
|
|||
|
|
+ length,
|
|||
|
|
mask;
|
|||
|
|
|
|||
|
|
long
|
|||
|
|
- count,
|
|||
|
|
+ count;
|
|||
|
|
+
|
|||
|
|
+ unsigned long
|
|||
|
|
y;
|
|||
|
|
|
|||
|
|
register IndexPacket
|
|||
|
|
*indexes;
|
|||
|
|
|
|||
|
|
- register long
|
|||
|
|
- i,
|
|||
|
|
+ register unsigned long
|
|||
|
|
x;
|
|||
|
|
|
|||
|
|
+ unsigned int
|
|||
|
|
+ i;
|
|||
|
|
+
|
|||
|
|
register PixelPacket
|
|||
|
|
*q;
|
|||
|
|
|
|||
|
|
@@ -481,13 +497,13 @@
|
|||
|
|
image->x_resolution=204.0;
|
|||
|
|
image->y_resolution=196.0;
|
|||
|
|
image->units=PixelsPerInchResolution;
|
|||
|
|
- for (y=0; ((y < (long) image->rows) && (null_lines < 3)); )
|
|||
|
|
+ for (y=0; ((y < image->rows) && (null_lines < 3)); )
|
|||
|
|
{
|
|||
|
|
/*
|
|||
|
|
Initialize scanline to white.
|
|||
|
|
*/
|
|||
|
|
p=scanline;
|
|||
|
|
- for (x=0; x < (long) image->columns; x++)
|
|||
|
|
+ for (x=0; x < image->columns; x++)
|
|||
|
|
*p++=0;
|
|||
|
|
/*
|
|||
|
|
Decode Huffman encoded scanline.
|
|||
|
|
@@ -502,7 +518,7 @@
|
|||
|
|
{
|
|||
|
|
if (byte == EOF)
|
|||
|
|
break;
|
|||
|
|
- if (x >= (long) image->columns)
|
|||
|
|
+ if (x >= image->columns)
|
|||
|
|
{
|
|||
|
|
while (runlength < 11)
|
|||
|
|
InputBit(bit);
|
|||
|
|
@@ -563,7 +579,7 @@
|
|||
|
|
case TBId:
|
|||
|
|
{
|
|||
|
|
count+=entry->count;
|
|||
|
|
- if ((x+count) > (long) image->columns)
|
|||
|
|
+ if ((x+(unsigned long) count) > image->columns)
|
|||
|
|
count=(long) image->columns-x;
|
|||
|
|
if (count > 0)
|
|||
|
|
{
|
|||
|
|
@@ -603,7 +619,7 @@
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
indexes=AccessMutableIndexes(image);
|
|||
|
|
- for (x=0; x < (long) image->columns; x++)
|
|||
|
|
+ for (x=0; x < image->columns; x++)
|
|||
|
|
{
|
|||
|
|
index=(unsigned int) (*p++);
|
|||
|
|
indexes[x]=index;
|
|||
|
|
@@ -695,7 +711,9 @@
|
|||
|
|
runlength;
|
|||
|
|
|
|||
|
|
long
|
|||
|
|
- n,
|
|||
|
|
+ n;
|
|||
|
|
+
|
|||
|
|
+ unsigned long
|
|||
|
|
y;
|
|||
|
|
|
|||
|
|
Image
|
|||
|
|
@@ -704,8 +722,10 @@
|
|||
|
|
register const IndexPacket
|
|||
|
|
*indexes;
|
|||
|
|
|
|||
|
|
- register long
|
|||
|
|
- i,
|
|||
|
|
+ unsigned long
|
|||
|
|
+ i;
|
|||
|
|
+
|
|||
|
|
+ register unsigned long
|
|||
|
|
x;
|
|||
|
|
|
|||
|
|
register const PixelPacket
|
|||
|
|
@@ -772,10 +792,10 @@
|
|||
|
|
polarity=(PixelIntensityToQuantum(&huffman_image->colormap[0]) <
|
|||
|
|
PixelIntensityToQuantum(&huffman_image->colormap[1]) ? 0x00 : 0x01);
|
|||
|
|
q=scanline;
|
|||
|
|
- for (i=(long) width; i > 0; i--)
|
|||
|
|
+ for (i=0; i < width; i++) /* was: for (i=(long) width; i > 0; i--) */
|
|||
|
|
*q++=(unsigned char) polarity;
|
|||
|
|
q=scanline;
|
|||
|
|
- for (y=0; y < (long) huffman_image->rows; y++)
|
|||
|
|
+ for (y=0; y < huffman_image->rows; y++)
|
|||
|
|
{
|
|||
|
|
p=AcquireImagePixels(huffman_image,0,y,huffman_image->columns,1,
|
|||
|
|
&huffman_image->exception);
|
|||
|
|
@@ -785,7 +805,7 @@
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
indexes=AccessImmutableIndexes(huffman_image);
|
|||
|
|
- for (x=0; x < (long) huffman_image->columns; x++)
|
|||
|
|
+ for (x=0; x < huffman_image->columns; x++)
|
|||
|
|
{
|
|||
|
|
*q=(unsigned char) (indexes[x] == polarity ? !polarity : polarity);
|
|||
|
|
q++;
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|