!39 Fix CVE-2020-21427,CVE-2020-21428,CVE-2020-22524
From: @wk333 Reviewed-by: @caodongxia Signed-off-by: @caodongxia
This commit is contained in:
commit
cf34c228cf
@ -0,0 +1,445 @@
|
|||||||
|
Origin: upstream, r1832
|
||||||
|
Index: Source/FreeImage/PluginBMP.cpp
|
||||||
|
---
|
||||||
|
diff --git a/Source/FreeImage/PluginBMP.cpp b/Source/FreeImage/PluginBMP.cpp
|
||||||
|
--- a/Source/FreeImage/PluginBMP.cpp (revision 1831)
|
||||||
|
+++ b/Source/FreeImage/PluginBMP.cpp (revision 1832)
|
||||||
|
@@ -181,6 +181,7 @@
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
+
|
||||||
|
#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_RGB
|
||||||
|
if (bit_count == 24 || bit_count == 32) {
|
||||||
|
for(unsigned y = 0; y < FreeImage_GetHeight(dib); y++) {
|
||||||
|
@@ -202,7 +203,7 @@
|
||||||
|
@param handle FreeImage IO handle
|
||||||
|
@param width Image width
|
||||||
|
@param height Image height
|
||||||
|
-@param dib Image to be loaded
|
||||||
|
+@param dib 4-bit image to be loaded
|
||||||
|
@return Returns TRUE if successful, returns FALSE otherwise
|
||||||
|
*/
|
||||||
|
static BOOL
|
||||||
|
@@ -217,7 +218,9 @@
|
||||||
|
height = abs(height);
|
||||||
|
|
||||||
|
pixels = (BYTE*)malloc(width * height * sizeof(BYTE));
|
||||||
|
- if(!pixels) throw(1);
|
||||||
|
+ if (!pixels) {
|
||||||
|
+ throw(1);
|
||||||
|
+ }
|
||||||
|
memset(pixels, 0, width * height * sizeof(BYTE));
|
||||||
|
|
||||||
|
BYTE *q = pixels;
|
||||||
|
@@ -237,7 +240,7 @@
|
||||||
|
throw(1);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < status_byte; i++) {
|
||||||
|
- *q++=(BYTE)((i & 0x01) ? (second_byte & 0x0f) : ((second_byte >> 4) & 0x0f));
|
||||||
|
+ *q++ = (BYTE)((i & 0x01) ? (second_byte & 0x0f) : ((second_byte >> 4) & 0x0f));
|
||||||
|
}
|
||||||
|
bits += status_byte;
|
||||||
|
}
|
||||||
|
@@ -252,7 +255,7 @@
|
||||||
|
// End of line
|
||||||
|
bits = 0;
|
||||||
|
scanline++;
|
||||||
|
- q = pixels + scanline*width;
|
||||||
|
+ q = pixels + scanline * width;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
@@ -264,7 +267,6 @@
|
||||||
|
case RLE_DELTA:
|
||||||
|
{
|
||||||
|
// read the delta values
|
||||||
|
-
|
||||||
|
BYTE delta_x = 0;
|
||||||
|
BYTE delta_y = 0;
|
||||||
|
|
||||||
|
@@ -276,7 +278,6 @@
|
||||||
|
}
|
||||||
|
|
||||||
|
// apply them
|
||||||
|
-
|
||||||
|
bits += delta_x;
|
||||||
|
scanline += delta_y;
|
||||||
|
q = pixels + scanline*width+bits;
|
||||||
|
@@ -293,7 +294,7 @@
|
||||||
|
throw(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
- *q++=(BYTE)((i & 0x01) ? (second_byte & 0x0f) : ((second_byte >> 4) & 0x0f));
|
||||||
|
+ *q++ = (BYTE)((i & 0x01) ? (second_byte & 0x0f) : ((second_byte >> 4) & 0x0f));
|
||||||
|
}
|
||||||
|
bits += status_byte;
|
||||||
|
// Read pad byte
|
||||||
|
@@ -334,7 +335,9 @@
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
} catch(int) {
|
||||||
|
- if(pixels) free(pixels);
|
||||||
|
+ if (pixels) {
|
||||||
|
+ free(pixels);
|
||||||
|
+ }
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -345,7 +348,7 @@
|
||||||
|
@param handle FreeImage IO handle
|
||||||
|
@param width Image width
|
||||||
|
@param height Image height
|
||||||
|
-@param dib Image to be loaded
|
||||||
|
+@param dib 8-bit image to be loaded
|
||||||
|
@return Returns TRUE if successful, returns FALSE otherwise
|
||||||
|
*/
|
||||||
|
static BOOL
|
||||||
|
@@ -354,103 +357,85 @@
|
||||||
|
BYTE second_byte = 0;
|
||||||
|
int scanline = 0;
|
||||||
|
int bits = 0;
|
||||||
|
+ int count = 0;
|
||||||
|
+ BYTE delta_x = 0;
|
||||||
|
+ BYTE delta_y = 0;
|
||||||
|
|
||||||
|
- for (;;) {
|
||||||
|
- if( io->read_proc(&status_byte, sizeof(BYTE), 1, handle) != 1) {
|
||||||
|
+ height = abs(height);
|
||||||
|
+
|
||||||
|
+ while(scanline < height) {
|
||||||
|
+
|
||||||
|
+ if (io->read_proc(&status_byte, sizeof(BYTE), 1, handle) != 1) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
- switch (status_byte) {
|
||||||
|
- case RLE_COMMAND :
|
||||||
|
- if(io->read_proc(&status_byte, sizeof(BYTE), 1, handle) != 1) {
|
||||||
|
- return FALSE;
|
||||||
|
- }
|
||||||
|
+ if (status_byte == RLE_COMMAND) {
|
||||||
|
+ if (io->read_proc(&status_byte, sizeof(BYTE), 1, handle) != 1) {
|
||||||
|
+ return FALSE;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- switch (status_byte) {
|
||||||
|
- case RLE_ENDOFLINE :
|
||||||
|
- bits = 0;
|
||||||
|
- scanline++;
|
||||||
|
- break;
|
||||||
|
+ switch (status_byte) {
|
||||||
|
+ case RLE_ENDOFLINE:
|
||||||
|
+ bits = 0;
|
||||||
|
+ scanline++;
|
||||||
|
+ break;
|
||||||
|
|
||||||
|
- case RLE_ENDOFBITMAP :
|
||||||
|
- return TRUE;
|
||||||
|
+ case RLE_ENDOFBITMAP:
|
||||||
|
+ return TRUE;
|
||||||
|
|
||||||
|
- case RLE_DELTA :
|
||||||
|
- {
|
||||||
|
- // read the delta values
|
||||||
|
+ case RLE_DELTA:
|
||||||
|
+ // read the delta values
|
||||||
|
+ delta_x = 0;
|
||||||
|
+ delta_y = 0;
|
||||||
|
+ if (io->read_proc(&delta_x, sizeof(BYTE), 1, handle) != 1) {
|
||||||
|
+ return FALSE;
|
||||||
|
+ }
|
||||||
|
+ if (io->read_proc(&delta_y, sizeof(BYTE), 1, handle) != 1) {
|
||||||
|
+ return FALSE;
|
||||||
|
+ }
|
||||||
|
+ // apply them
|
||||||
|
+ bits += delta_x;
|
||||||
|
+ scanline += delta_y;
|
||||||
|
+ break;
|
||||||
|
|
||||||
|
- BYTE delta_x = 0;
|
||||||
|
- BYTE delta_y = 0;
|
||||||
|
-
|
||||||
|
- if(io->read_proc(&delta_x, sizeof(BYTE), 1, handle) != 1) {
|
||||||
|
- return FALSE;
|
||||||
|
- }
|
||||||
|
- if(io->read_proc(&delta_y, sizeof(BYTE), 1, handle) != 1) {
|
||||||
|
- return FALSE;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- // apply them
|
||||||
|
-
|
||||||
|
- bits += delta_x;
|
||||||
|
- scanline += delta_y;
|
||||||
|
-
|
||||||
|
- break;
|
||||||
|
+ default:
|
||||||
|
+ // absolute mode
|
||||||
|
+ count = MIN((int)status_byte, width - bits);
|
||||||
|
+ if (count < 0) {
|
||||||
|
+ return FALSE;
|
||||||
|
}
|
||||||
|
-
|
||||||
|
- default :
|
||||||
|
- {
|
||||||
|
- if(scanline >= abs(height)) {
|
||||||
|
- return TRUE;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- int count = MIN((int)status_byte, width - bits);
|
||||||
|
-
|
||||||
|
- BYTE *sline = FreeImage_GetScanLine(dib, scanline);
|
||||||
|
-
|
||||||
|
- if(io->read_proc((void *)(sline + bits), sizeof(BYTE) * count, 1, handle) != 1) {
|
||||||
|
+ BYTE *sline = FreeImage_GetScanLine(dib, scanline);
|
||||||
|
+ if (io->read_proc((void *)(sline + bits), sizeof(BYTE) * count, 1, handle) != 1) {
|
||||||
|
+ return FALSE;
|
||||||
|
+ }
|
||||||
|
+ // align run length to even number of bytes
|
||||||
|
+ if ((status_byte & 1) == 1) {
|
||||||
|
+ if (io->read_proc(&second_byte, sizeof(BYTE), 1, handle) != 1) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
-
|
||||||
|
- // align run length to even number of bytes
|
||||||
|
-
|
||||||
|
- if ((status_byte & 1) == 1) {
|
||||||
|
- if(io->read_proc(&second_byte, sizeof(BYTE), 1, handle) != 1) {
|
||||||
|
- return FALSE;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- bits += status_byte;
|
||||||
|
-
|
||||||
|
- break;
|
||||||
|
}
|
||||||
|
- }
|
||||||
|
+ bits += status_byte;
|
||||||
|
+ break;
|
||||||
|
|
||||||
|
- break;
|
||||||
|
-
|
||||||
|
- default :
|
||||||
|
- {
|
||||||
|
- if(scanline >= abs(height)) {
|
||||||
|
- return TRUE;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- int count = MIN((int)status_byte, width - bits);
|
||||||
|
-
|
||||||
|
- BYTE *sline = FreeImage_GetScanLine(dib, scanline);
|
||||||
|
-
|
||||||
|
- if(io->read_proc(&second_byte, sizeof(BYTE), 1, handle) != 1) {
|
||||||
|
- return FALSE;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- for (int i = 0; i < count; i++) {
|
||||||
|
- *(sline + bits) = second_byte;
|
||||||
|
-
|
||||||
|
- bits++;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- break;
|
||||||
|
+ } // switch (status_byte)
|
||||||
|
+ }
|
||||||
|
+ else {
|
||||||
|
+ count = MIN((int)status_byte, width - bits);
|
||||||
|
+ if (count < 0) {
|
||||||
|
+ return FALSE;
|
||||||
|
}
|
||||||
|
+ BYTE *sline = FreeImage_GetScanLine(dib, scanline);
|
||||||
|
+ if (io->read_proc(&second_byte, sizeof(BYTE), 1, handle) != 1) {
|
||||||
|
+ return FALSE;
|
||||||
|
+ }
|
||||||
|
+ for (int i = 0; i < count; i++) {
|
||||||
|
+ *(sline + bits) = second_byte;
|
||||||
|
+ bits++;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
@@ -463,10 +448,12 @@
|
||||||
|
BOOL header_only = (flags & FIF_LOAD_NOPIXELS) == FIF_LOAD_NOPIXELS;
|
||||||
|
|
||||||
|
// load the info header
|
||||||
|
-
|
||||||
|
BITMAPINFOHEADER bih;
|
||||||
|
+ memset(&bih, 0, sizeof(BITMAPINFOHEADER));
|
||||||
|
+ if (io->read_proc(&bih, sizeof(BITMAPINFOHEADER), 1, handle) != 1) {
|
||||||
|
+ throw FI_MSG_ERROR_INVALID_FORMAT;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- io->read_proc(&bih, sizeof(BITMAPINFOHEADER), 1, handle);
|
||||||
|
#ifdef FREEIMAGE_BIGENDIAN
|
||||||
|
SwapInfoHeader(&bih);
|
||||||
|
#endif
|
||||||
|
@@ -544,7 +531,7 @@
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BI_RLE4 :
|
||||||
|
- if( LoadPixelDataRLE4(io, handle, width, height, dib) ) {
|
||||||
|
+ if( (bit_count == 4) && LoadPixelDataRLE4(io, handle, width, height, dib) ) {
|
||||||
|
return dib;
|
||||||
|
} else {
|
||||||
|
throw "Error encountered while decoding RLE4 BMP data";
|
||||||
|
@@ -552,7 +539,7 @@
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BI_RLE8 :
|
||||||
|
- if( LoadPixelDataRLE8(io, handle, width, height, dib) ) {
|
||||||
|
+ if( (bit_count == 8) && LoadPixelDataRLE8(io, handle, width, height, dib) ) {
|
||||||
|
return dib;
|
||||||
|
} else {
|
||||||
|
throw "Error encountered while decoding RLE8 BMP data";
|
||||||
|
@@ -602,7 +589,7 @@
|
||||||
|
|
||||||
|
return dib;
|
||||||
|
}
|
||||||
|
- break; // 16-bit
|
||||||
|
+ break; // 16-bit RGB
|
||||||
|
|
||||||
|
case 24 :
|
||||||
|
case 32 :
|
||||||
|
@@ -679,10 +666,12 @@
|
||||||
|
BOOL header_only = (flags & FIF_LOAD_NOPIXELS) == FIF_LOAD_NOPIXELS;
|
||||||
|
|
||||||
|
// load the info header
|
||||||
|
-
|
||||||
|
BITMAPINFOHEADER bih;
|
||||||
|
+ memset(&bih, 0, sizeof(BITMAPINFOHEADER));
|
||||||
|
+ if (io->read_proc(&bih, sizeof(BITMAPINFOHEADER), 1, handle) != 1) {
|
||||||
|
+ throw FI_MSG_ERROR_INVALID_FORMAT;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- io->read_proc(&bih, sizeof(BITMAPINFOHEADER), 1, handle);
|
||||||
|
#ifdef FREEIMAGE_BIGENDIAN
|
||||||
|
SwapInfoHeader(&bih);
|
||||||
|
#endif
|
||||||
|
@@ -767,17 +756,19 @@
|
||||||
|
return dib;
|
||||||
|
|
||||||
|
case BI_RLE4 :
|
||||||
|
- if( LoadPixelDataRLE4(io, handle, width, height, dib) ) {
|
||||||
|
+ if ((bit_count == 4) && LoadPixelDataRLE4(io, handle, width, height, dib)) {
|
||||||
|
return dib;
|
||||||
|
- } else {
|
||||||
|
+ }
|
||||||
|
+ else {
|
||||||
|
throw "Error encountered while decoding RLE4 BMP data";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BI_RLE8 :
|
||||||
|
- if( LoadPixelDataRLE8(io, handle, width, height, dib) ) {
|
||||||
|
+ if ((bit_count == 8) && LoadPixelDataRLE8(io, handle, width, height, dib)) {
|
||||||
|
return dib;
|
||||||
|
- } else {
|
||||||
|
+ }
|
||||||
|
+ else {
|
||||||
|
throw "Error encountered while decoding RLE8 BMP data";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
@@ -863,9 +854,9 @@
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch(const char *message) {
|
||||||
|
- if(dib)
|
||||||
|
+ if (dib) {
|
||||||
|
FreeImage_Unload(dib);
|
||||||
|
-
|
||||||
|
+ }
|
||||||
|
FreeImage_OutputMessageProc(s_format_id, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -881,9 +872,13 @@
|
||||||
|
try {
|
||||||
|
BOOL header_only = (flags & FIF_LOAD_NOPIXELS) == FIF_LOAD_NOPIXELS;
|
||||||
|
|
||||||
|
+ // load the info header
|
||||||
|
BITMAPINFOOS2_1X_HEADER bios2_1x;
|
||||||
|
+ memset(&bios2_1x, 0, sizeof(BITMAPINFOOS2_1X_HEADER));
|
||||||
|
+ if (io->read_proc(&bios2_1x, sizeof(BITMAPINFOOS2_1X_HEADER), 1, handle) != 1) {
|
||||||
|
+ throw FI_MSG_ERROR_INVALID_FORMAT;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- io->read_proc(&bios2_1x, sizeof(BITMAPINFOOS2_1X_HEADER), 1, handle);
|
||||||
|
#ifdef FREEIMAGE_BIGENDIAN
|
||||||
|
SwapOS21XHeader(&bios2_1x);
|
||||||
|
#endif
|
||||||
|
@@ -1005,9 +1000,9 @@
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch(const char *message) {
|
||||||
|
- if(dib)
|
||||||
|
+ if (dib) {
|
||||||
|
FreeImage_Unload(dib);
|
||||||
|
-
|
||||||
|
+ }
|
||||||
|
FreeImage_OutputMessageProc(s_format_id, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1090,19 +1085,20 @@
|
||||||
|
BITMAPFILEHEADER bitmapfileheader;
|
||||||
|
DWORD type = 0;
|
||||||
|
|
||||||
|
- // we use this offset value to make seemingly absolute seeks relative in the file
|
||||||
|
-
|
||||||
|
+ // we use this offset value to make seemingly absolute seeks relative in the file
|
||||||
|
long offset_in_file = io->tell_proc(handle);
|
||||||
|
|
||||||
|
// read the fileheader
|
||||||
|
+ memset(&bitmapfileheader, 0, sizeof(BITMAPFILEHEADER));
|
||||||
|
+ if (io->read_proc(&bitmapfileheader, sizeof(BITMAPFILEHEADER), 1, handle) != 1) {
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- io->read_proc(&bitmapfileheader, sizeof(BITMAPFILEHEADER), 1, handle);
|
||||||
|
#ifdef FREEIMAGE_BIGENDIAN
|
||||||
|
SwapFileHeader(&bitmapfileheader);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// check the signature
|
||||||
|
-
|
||||||
|
if((bitmapfileheader.bfType != 0x4D42) && (bitmapfileheader.bfType != 0x4142)) {
|
||||||
|
FreeImage_OutputMessageProc(s_format_id, FI_MSG_ERROR_MAGIC_NUMBER);
|
||||||
|
return NULL;
|
||||||
|
@@ -1109,9 +1105,9 @@
|
||||||
|
}
|
||||||
|
|
||||||
|
// read the first byte of the infoheader
|
||||||
|
-
|
||||||
|
io->read_proc(&type, sizeof(DWORD), 1, handle);
|
||||||
|
io->seek_proc(handle, 0 - (long)sizeof(DWORD), SEEK_CUR);
|
||||||
|
+
|
||||||
|
#ifdef FREEIMAGE_BIGENDIAN
|
||||||
|
SwapLong(&type);
|
||||||
|
#endif
|
||||||
|
@@ -1138,7 +1134,7 @@
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
- FreeImage_OutputMessageProc(s_format_id, "unknown bmp subtype with id %d", type);
|
||||||
|
+ FreeImage_OutputMessageProc(s_format_id, "Unknown bmp subtype with id %d", type);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
@@ -1418,6 +1414,7 @@
|
||||||
|
}
|
||||||
|
|
||||||
|
free(buffer);
|
||||||
|
+
|
||||||
|
#ifdef FREEIMAGE_BIGENDIAN
|
||||||
|
} else if (dst_bpp == 16) {
|
||||||
|
int padding = dst_pitch - dst_width * sizeof(WORD);
|
||||||
|
@@ -1439,6 +1436,7 @@
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
+
|
||||||
|
#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_RGB
|
||||||
|
} else if (dst_bpp == 24) {
|
||||||
|
int padding = dst_pitch - dst_width * sizeof(FILE_BGR);
|
||||||
@ -0,0 +1,159 @@
|
|||||||
|
Origin: upstream, r1836
|
||||||
|
Index: Source/FreeImage/PluginBMP.cpp
|
||||||
|
---
|
||||||
|
diff --git a/Source/FreeImage/PluginBMP.cpp b/Source/FreeImage/PluginBMP.cpp
|
||||||
|
--- a/Source/FreeImage/PluginBMP.cpp (revision 1835)
|
||||||
|
+++ b/Source/FreeImage/PluginBMP.cpp (revision 1836)
|
||||||
|
@@ -139,6 +139,75 @@
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
+Check if a BITMAPINFOHEADER is valid
|
||||||
|
+@return Returns TRUE if successful, returns FALSE otherwise
|
||||||
|
+*/
|
||||||
|
+static BOOL
|
||||||
|
+CheckBitmapInfoHeader(BITMAPINFOHEADER *bih) {
|
||||||
|
+ if (bih->biSize != sizeof(BITMAPINFOHEADER)) {
|
||||||
|
+ // The size, in bytes, of the image.This may be set to zero for BI_RGB bitmaps.
|
||||||
|
+ // If biCompression is BI_JPEG or BI_PNG, biSizeImage indicates the size of the JPEG or PNG image buffer, respectively.
|
||||||
|
+ if ((bih->biSize == 0) && (bih->biCompression != BI_RGB)) {
|
||||||
|
+ return FALSE;
|
||||||
|
+ }
|
||||||
|
+ else if ((bih->biCompression == BI_JPEG) || (bih->biCompression == BI_PNG)) {
|
||||||
|
+ // JPEG or PNG is not yet supported
|
||||||
|
+ return FALSE;
|
||||||
|
+ }
|
||||||
|
+ else {
|
||||||
|
+ return FALSE;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ if (bih->biWidth < 0) {
|
||||||
|
+ return FALSE;
|
||||||
|
+ }
|
||||||
|
+ if (bih->biHeight < 0) {
|
||||||
|
+ // If biHeight is negative, indicating a top-down DIB, biCompression must be either BI_RGB or BI_BITFIELDS.
|
||||||
|
+ // Top-down DIBs cannot be compressed.
|
||||||
|
+ // If biCompression is BI_JPEG or BI_PNG, the biHeight member specifies the height of the decompressed JPEG or PNG image file, respectively.
|
||||||
|
+ if ((bih->biCompression != BI_RGB) && (bih->biCompression != BI_BITFIELDS)) {
|
||||||
|
+ return FALSE;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ if (bih->biPlanes != 1) {
|
||||||
|
+ // The number of planes for the target device. This value must be set to 1.
|
||||||
|
+ return FALSE;
|
||||||
|
+ }
|
||||||
|
+ switch (bih->biBitCount) {
|
||||||
|
+ case 0:
|
||||||
|
+ // The number of bits-per-pixel is specified or is implied by the JPEG or PNG format.
|
||||||
|
+ // JPEG or PNG is not yet supported
|
||||||
|
+ return FALSE;
|
||||||
|
+ break;
|
||||||
|
+ case 1:
|
||||||
|
+ case 4:
|
||||||
|
+ case 8:
|
||||||
|
+ case 16:
|
||||||
|
+ case 24:
|
||||||
|
+ case 32:
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ // Unsupported bitdepth
|
||||||
|
+ return FALSE;
|
||||||
|
+ }
|
||||||
|
+ switch (bih->biCompression) {
|
||||||
|
+ case BI_RGB:
|
||||||
|
+ case BI_RLE8:
|
||||||
|
+ case BI_RLE4:
|
||||||
|
+ case BI_BITFIELDS:
|
||||||
|
+ break;
|
||||||
|
+ case BI_JPEG:
|
||||||
|
+ case BI_PNG:
|
||||||
|
+ default:
|
||||||
|
+ return FALSE;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return TRUE;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+// --------------------------------------------------------------------------
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
Load uncompressed image pixels for 1-, 4-, 8-, 16-, 24- and 32-bit dib
|
||||||
|
@param io FreeImage IO
|
||||||
|
@param handle FreeImage IO handle
|
||||||
|
@@ -458,6 +527,10 @@
|
||||||
|
SwapInfoHeader(&bih);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+ if (CheckBitmapInfoHeader(&bih) == FALSE) {
|
||||||
|
+ throw FI_MSG_ERROR_INVALID_FORMAT;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
// keep some general information about the bitmap
|
||||||
|
|
||||||
|
unsigned used_colors = bih.biClrUsed;
|
||||||
|
@@ -555,10 +628,18 @@
|
||||||
|
case 16 :
|
||||||
|
{
|
||||||
|
int use_bitfields = 0;
|
||||||
|
- if (bih.biCompression == BI_BITFIELDS) use_bitfields = 3;
|
||||||
|
- else if (bih.biCompression == BI_ALPHABITFIELDS) use_bitfields = 4;
|
||||||
|
- else if (type == 52) use_bitfields = 3;
|
||||||
|
- else if (type >= 56) use_bitfields = 4;
|
||||||
|
+ if (bih.biCompression == BI_BITFIELDS) {
|
||||||
|
+ use_bitfields = 3;
|
||||||
|
+ }
|
||||||
|
+ else if (bih.biCompression == BI_ALPHABITFIELDS) {
|
||||||
|
+ use_bitfields = 4;
|
||||||
|
+ }
|
||||||
|
+ else if (type == 52) {
|
||||||
|
+ use_bitfields = 3;
|
||||||
|
+ }
|
||||||
|
+ else if (type >= 56) {
|
||||||
|
+ use_bitfields = 4;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
if (use_bitfields > 0) {
|
||||||
|
DWORD bitfields[4];
|
||||||
|
@@ -595,10 +676,18 @@
|
||||||
|
case 32 :
|
||||||
|
{
|
||||||
|
int use_bitfields = 0;
|
||||||
|
- if (bih.biCompression == BI_BITFIELDS) use_bitfields = 3;
|
||||||
|
- else if (bih.biCompression == BI_ALPHABITFIELDS) use_bitfields = 4;
|
||||||
|
- else if (type == 52) use_bitfields = 3;
|
||||||
|
- else if (type >= 56) use_bitfields = 4;
|
||||||
|
+ if (bih.biCompression == BI_BITFIELDS) {
|
||||||
|
+ use_bitfields = 3;
|
||||||
|
+ }
|
||||||
|
+ else if (bih.biCompression == BI_ALPHABITFIELDS) {
|
||||||
|
+ use_bitfields = 4;
|
||||||
|
+ }
|
||||||
|
+ else if (type == 52) {
|
||||||
|
+ use_bitfields = 3;
|
||||||
|
+ }
|
||||||
|
+ else if (type >= 56) {
|
||||||
|
+ use_bitfields = 4;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
if (use_bitfields > 0) {
|
||||||
|
DWORD bitfields[4];
|
||||||
|
@@ -676,6 +765,10 @@
|
||||||
|
SwapInfoHeader(&bih);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+ if (CheckBitmapInfoHeader(&bih) == FALSE) {
|
||||||
|
+ throw FI_MSG_ERROR_INVALID_FORMAT;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
// keep some general information about the bitmap
|
||||||
|
|
||||||
|
unsigned used_colors = bih.biClrUsed;
|
||||||
|
@@ -780,7 +873,7 @@
|
||||||
|
|
||||||
|
case 16 :
|
||||||
|
{
|
||||||
|
- if (bih.biCompression == 3) {
|
||||||
|
+ if (bih.biCompression == BI_BITFIELDS) {
|
||||||
|
DWORD bitfields[3];
|
||||||
|
|
||||||
|
io->read_proc(bitfields, 3 * sizeof(DWORD), 1, handle);
|
||||||
15
CVE-2020-21427-pre-r1830-minor-refactoring.patch
Normal file
15
CVE-2020-21427-pre-r1830-minor-refactoring.patch
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
Index: Source/Utilities.h
|
||||||
|
===================================================================
|
||||||
|
diff --git a/Source/Utilities.h b/Source/Utilities.h
|
||||||
|
--- a/Source/Utilities.h (revision 1829)
|
||||||
|
+++ b/Source/Utilities.h (revision 1830)
|
||||||
|
@@ -529,7 +529,8 @@
|
||||||
|
static const char *FI_MSG_ERROR_DIB_MEMORY = "DIB allocation failed, maybe caused by an invalid image size or by a lack of memory";
|
||||||
|
static const char *FI_MSG_ERROR_PARSING = "Parsing error";
|
||||||
|
static const char *FI_MSG_ERROR_MAGIC_NUMBER = "Invalid magic number";
|
||||||
|
-static const char *FI_MSG_ERROR_UNSUPPORTED_FORMAT = "Unsupported format";
|
||||||
|
+static const char *FI_MSG_ERROR_UNSUPPORTED_FORMAT = "Unsupported image format";
|
||||||
|
+static const char *FI_MSG_ERROR_INVALID_FORMAT = "Invalid file format";
|
||||||
|
static const char *FI_MSG_ERROR_UNSUPPORTED_COMPRESSION = "Unsupported compression type";
|
||||||
|
static const char *FI_MSG_WARNING_INVALID_THUMBNAIL = "Warning: attached thumbnail cannot be written to output file (invalid format) - Thumbnail saving aborted";
|
||||||
|
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
Origin: upstream, r1877
|
||||||
|
Index: Source/FreeImage/PluginDDS.cpp
|
||||||
|
===================================================================
|
||||||
|
diff --git a/Source/FreeImage/PluginDDS.cpp b/Source/FreeImage/PluginDDS.cpp
|
||||||
|
--- a/Source/FreeImage/PluginDDS.cpp (revision 1876)
|
||||||
|
+++ b/Source/FreeImage/PluginDDS.cpp (revision 1877)
|
||||||
|
@@ -617,7 +617,7 @@
|
||||||
|
// read the file
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
|
||||||
|
- const int line = CalculateLine(width, bpp);
|
||||||
|
+ const int line = CalculateLine(width, FreeImage_GetBPP(dib));
|
||||||
|
const int filePitch = ((desc->dwFlags & DDSD_PITCH) == DDSD_PITCH) ? (int)desc->dwPitchOrLinearSize : line;
|
||||||
|
const long delta = (long)filePitch - (long)line;
|
||||||
|
|
||||||
@ -0,0 +1,227 @@
|
|||||||
|
Origin: upstream, r1848
|
||||||
|
Index: Source/FreeImage/PluginPFM.cpp
|
||||||
|
---
|
||||||
|
diff --git a/Source/FreeImage/PluginPFM.cpp b/Source/FreeImage/PluginPFM.cpp
|
||||||
|
--- a/Source/FreeImage/PluginPFM.cpp (revision 1847)
|
||||||
|
+++ b/Source/FreeImage/PluginPFM.cpp (revision 1848)
|
||||||
|
@@ -23,6 +23,12 @@
|
||||||
|
#include "Utilities.h"
|
||||||
|
|
||||||
|
// ==========================================================
|
||||||
|
+// Plugin Interface
|
||||||
|
+// ==========================================================
|
||||||
|
+
|
||||||
|
+static int s_format_id;
|
||||||
|
+
|
||||||
|
+// ==========================================================
|
||||||
|
// Internal functions
|
||||||
|
// ==========================================================
|
||||||
|
|
||||||
|
@@ -59,6 +65,9 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
Get an integer value from the actual position pointed by handle
|
||||||
|
+@param io
|
||||||
|
+@param handle
|
||||||
|
+@return Returns -1 in case of failure, returns the found number otherwise
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
pfm_get_int(FreeImageIO *io, fi_handle handle) {
|
||||||
|
@@ -65,70 +74,72 @@
|
||||||
|
char c = 0;
|
||||||
|
BOOL bFirstChar;
|
||||||
|
|
||||||
|
- // skip forward to start of next number
|
||||||
|
+ try {
|
||||||
|
|
||||||
|
- if(!io->read_proc(&c, 1, 1, handle)) {
|
||||||
|
- throw FI_MSG_ERROR_PARSING;
|
||||||
|
- }
|
||||||
|
+ // skip forward to start of next number
|
||||||
|
|
||||||
|
- while (1) {
|
||||||
|
- // eat comments
|
||||||
|
+ if (io->read_proc(&c, 1, 1, handle) != 1) {
|
||||||
|
+ throw FI_MSG_ERROR_PARSING;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- if (c == '#') {
|
||||||
|
- // if we're at a comment, read to end of line
|
||||||
|
+ while (1) {
|
||||||
|
+ // eat comments
|
||||||
|
|
||||||
|
- bFirstChar = TRUE;
|
||||||
|
+ if (c == '#') {
|
||||||
|
+ // if we're at a comment, read to end of line
|
||||||
|
|
||||||
|
- while (1) {
|
||||||
|
- if(!io->read_proc(&c, 1, 1, handle)) {
|
||||||
|
- throw FI_MSG_ERROR_PARSING;
|
||||||
|
- }
|
||||||
|
+ bFirstChar = TRUE;
|
||||||
|
|
||||||
|
- if (bFirstChar && c == ' ') {
|
||||||
|
- // loop off 1 sp after #
|
||||||
|
- bFirstChar = FALSE;
|
||||||
|
- } else if (c == '\n') {
|
||||||
|
- break;
|
||||||
|
+ while (1) {
|
||||||
|
+ if (io->read_proc(&c, 1, 1, handle) != 1) {
|
||||||
|
+ throw FI_MSG_ERROR_PARSING;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (bFirstChar && c == ' ') {
|
||||||
|
+ // loop off 1 sp after #
|
||||||
|
+ bFirstChar = FALSE;
|
||||||
|
+ }
|
||||||
|
+ else if (c == '\n') {
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
- }
|
||||||
|
|
||||||
|
- if (c >= '0' && c <='9') {
|
||||||
|
- // we've found what we were looking for
|
||||||
|
- break;
|
||||||
|
- }
|
||||||
|
+ if (c >= '0' && c <= '9') {
|
||||||
|
+ // we've found what we were looking for
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- if(!io->read_proc(&c, 1, 1, handle)) {
|
||||||
|
- throw FI_MSG_ERROR_PARSING;
|
||||||
|
+ if (io->read_proc(&c, 1, 1, handle) != 1) {
|
||||||
|
+ throw FI_MSG_ERROR_PARSING;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
- }
|
||||||
|
|
||||||
|
- // we're at the start of a number, continue until we hit a non-number
|
||||||
|
+ // we're at the start of a number, continue until we hit a non-number
|
||||||
|
|
||||||
|
- int i = 0;
|
||||||
|
+ int i = 0;
|
||||||
|
|
||||||
|
- while (1) {
|
||||||
|
- i = (i * 10) + (c - '0');
|
||||||
|
+ while (1) {
|
||||||
|
+ i = (i * 10) + (c - '0');
|
||||||
|
|
||||||
|
- if(!io->read_proc(&c, 1, 1, handle)) {
|
||||||
|
- throw FI_MSG_ERROR_PARSING;
|
||||||
|
- }
|
||||||
|
+ if (io->read_proc(&c, 1, 1, handle) != 1) {
|
||||||
|
+ throw FI_MSG_ERROR_PARSING;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- if (c < '0' || c > '9') {
|
||||||
|
- break;
|
||||||
|
+ if (c < '0' || c > '9') {
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
- }
|
||||||
|
|
||||||
|
- return i;
|
||||||
|
+ return i;
|
||||||
|
+ }
|
||||||
|
+ catch (const char *message) {
|
||||||
|
+ FreeImage_OutputMessageProc(s_format_id, message);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==========================================================
|
||||||
|
-// Plugin Interface
|
||||||
|
-// ==========================================================
|
||||||
|
-
|
||||||
|
-static int s_format_id;
|
||||||
|
-
|
||||||
|
-// ==========================================================
|
||||||
|
// Plugin Implementation
|
||||||
|
// ==========================================================
|
||||||
|
|
||||||
|
@@ -230,8 +241,12 @@
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the header information: width, height and the scale value
|
||||||
|
- unsigned width = (unsigned) pfm_get_int(io, handle);
|
||||||
|
- unsigned height = (unsigned) pfm_get_int(io, handle);
|
||||||
|
+ int width = pfm_get_int(io, handle);
|
||||||
|
+ int height = pfm_get_int(io, handle);
|
||||||
|
+ if ((width <= 0) || (height <= 0)) {
|
||||||
|
+ throw FI_MSG_ERROR_PARSING;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
float scalefactor = 1;
|
||||||
|
|
||||||
|
BOOL bResult = pfm_get_line(io, handle, line_buffer, PFM_MAXLINE);
|
||||||
|
@@ -262,7 +277,7 @@
|
||||||
|
throw FI_MSG_ERROR_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
- for (unsigned y = 0; y < height; y++) {
|
||||||
|
+ for (int y = 0; y < height; y++) {
|
||||||
|
FIRGBF *bits = (FIRGBF*)FreeImage_GetScanLine(dib, height - 1 - y);
|
||||||
|
|
||||||
|
if(io->read_proc(lineBuffer, sizeof(float), lineWidth, handle) != lineWidth) {
|
||||||
|
@@ -271,7 +286,7 @@
|
||||||
|
float *channel = lineBuffer;
|
||||||
|
if(scalefactor > 0) {
|
||||||
|
// MSB
|
||||||
|
- for (unsigned x = 0; x < width; x++) {
|
||||||
|
+ for (int x = 0; x < width; x++) {
|
||||||
|
REVERSEBYTES(channel++, &bits[x].red);
|
||||||
|
REVERSEBYTES(channel++, &bits[x].green);
|
||||||
|
REVERSEBYTES(channel++, &bits[x].blue);
|
||||||
|
@@ -278,7 +293,7 @@
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// LSB
|
||||||
|
- for (unsigned x = 0; x < width; x++) {
|
||||||
|
+ for (int x = 0; x < width; x++) {
|
||||||
|
bits[x].red = *channel++;
|
||||||
|
bits[x].green = *channel++;
|
||||||
|
bits[x].blue = *channel++;
|
||||||
|
@@ -296,7 +311,7 @@
|
||||||
|
throw FI_MSG_ERROR_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
- for (unsigned y = 0; y < height; y++) {
|
||||||
|
+ for (int y = 0; y < height; y++) {
|
||||||
|
float *bits = (float*)FreeImage_GetScanLine(dib, height - 1 - y);
|
||||||
|
|
||||||
|
if(io->read_proc(lineBuffer, sizeof(float), lineWidth, handle) != lineWidth) {
|
||||||
|
@@ -305,12 +320,12 @@
|
||||||
|
float *channel = lineBuffer;
|
||||||
|
if(scalefactor > 0) {
|
||||||
|
// MSB - File is Big endian
|
||||||
|
- for (unsigned x = 0; x < width; x++) {
|
||||||
|
+ for (int x = 0; x < width; x++) {
|
||||||
|
REVERSEBYTES(channel++, &bits[x]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// LSB - File is Little Endian
|
||||||
|
- for (unsigned x = 0; x < width; x++) {
|
||||||
|
+ for (int x = 0; x < width; x++) {
|
||||||
|
bits[x] = *channel++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -323,9 +338,12 @@
|
||||||
|
return dib;
|
||||||
|
|
||||||
|
} catch (const char *text) {
|
||||||
|
- if(lineBuffer) free(lineBuffer);
|
||||||
|
- if(dib) FreeImage_Unload(dib);
|
||||||
|
-
|
||||||
|
+ if (lineBuffer) {
|
||||||
|
+ free(lineBuffer);
|
||||||
|
+ }
|
||||||
|
+ if (dib) {
|
||||||
|
+ FreeImage_Unload(dib);
|
||||||
|
+ }
|
||||||
|
if(NULL != text) {
|
||||||
|
FreeImage_OutputMessageProc(s_format_id, text);
|
||||||
|
}
|
||||||
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
Name: freeimage
|
Name: freeimage
|
||||||
Version: 3.18.0
|
Version: 3.18.0
|
||||||
Release: 10
|
Release: 11
|
||||||
Summary: FreeImage is a library project for developers who would like to support popular graphics image formats (PNG, JPEG, TIFF, BMP and others)
|
Summary: FreeImage is a library project for developers who would like to support popular graphics image formats (PNG, JPEG, TIFF, BMP and others)
|
||||||
License: GPLv2 or GPLv3 and FIPL
|
License: GPLv2 or GPLv3 and FIPL
|
||||||
URL: https://freeimage.sourceforge.io/
|
URL: https://freeimage.sourceforge.io/
|
||||||
@ -23,7 +23,12 @@ Patch5: substream.patch
|
|||||||
Patch6: Fix-build-failure-with-OpenEXR-3.0.patch
|
Patch6: Fix-build-failure-with-OpenEXR-3.0.patch
|
||||||
Patch7: freeimage-libtiff45.patch
|
Patch7: freeimage-libtiff45.patch
|
||||||
Patch8: Fix-build-failure-with-LibRaw-0.21.1.patch
|
Patch8: Fix-build-failure-with-LibRaw-0.21.1.patch
|
||||||
|
# https://sources.debian.org/src/freeimage/3.18.0%2Bds2-10/debian/patches/
|
||||||
|
Patch9: CVE-2020-21427-pre-r1830-minor-refactoring.patch
|
||||||
|
Patch10: CVE-2020-21427-1-r1832-improved-BMP-plugin-when-working-with-malicious-images.patch
|
||||||
|
Patch11: CVE-2020-21428-r1877-improved-DDS-plugin-against-malicious-images.patch
|
||||||
|
Patch12: CVE-2020-21427-2-r1836-improved-BMP-plugin-when-working-with-malicious-images.patch
|
||||||
|
Patch13: CVE-2020-22524-r1848-improved-PFM-plugin-against-malicious-images.patch
|
||||||
|
|
||||||
BuildRequires: doxygen gcc-c++ make jxrlib-devel libjpeg-devel libmng-devel libpng-devel libtiff-devel libwebp-devel LibRaw-devel OpenEXR-devel openjpeg2-devel
|
BuildRequires: doxygen gcc-c++ make jxrlib-devel libjpeg-devel libmng-devel libpng-devel libtiff-devel libwebp-devel LibRaw-devel OpenEXR-devel openjpeg2-devel
|
||||||
|
|
||||||
@ -107,6 +112,9 @@ ldconfig -n %{buildroot}%{_libdir}
|
|||||||
|
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Mon Dec 04 2023 wangkai <13474090681@163.com> - 3.18.0-11
|
||||||
|
- Fix CVE-2020-21427,CVE-2020-21428,CVE-2020-22524
|
||||||
|
|
||||||
* Wed Jul 5 2023 liyanan <thistleslyn@163.com> - 3.18.0-10
|
* Wed Jul 5 2023 liyanan <thistleslyn@163.com> - 3.18.0-10
|
||||||
- Fix compilation failure caused by LibRaw upgrade
|
- Fix compilation failure caused by LibRaw upgrade
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user