freeimage/FreeImage-3.10.0_CVE-2015-0852.patch
2015-09-17 16:26:12 +02:00

162 lines
5.3 KiB
Diff

diff -rupN FreeImage/Source/FreeImage/PluginPCX.cpp FreeImage-new/Source/FreeImage/PluginPCX.cpp
--- FreeImage/Source/FreeImage/PluginPCX.cpp 2007-05-08 20:04:18.000000000 +0200
+++ FreeImage-new/Source/FreeImage/PluginPCX.cpp 2015-09-17 16:19:19.862693426 +0200
@@ -30,7 +30,7 @@
// Constants + headers
// ----------------------------------------------------------
-#define IO_BUF_SIZE 2048
+#define PCX_IO_BUF_SIZE 2048
// ----------------------------------------------------------
@@ -95,17 +95,17 @@ readline(FreeImageIO &io, fi_handle hand
while (length--) {
if (count == 0) {
- if (*ReadPos >= IO_BUF_SIZE - 1 ) {
- if (*ReadPos == IO_BUF_SIZE - 1) {
+ if (*ReadPos >= PCX_IO_BUF_SIZE - 1 ) {
+ if (*ReadPos == PCX_IO_BUF_SIZE - 1) {
// we still have one BYTE, copy it to the start pos
- *ReadBuf = ReadBuf[IO_BUF_SIZE - 1];
+ *ReadBuf = ReadBuf[PCX_IO_BUF_SIZE - 1];
- io.read_proc(ReadBuf + 1, 1, IO_BUF_SIZE - 1, handle);
+ io.read_proc(ReadBuf + 1, 1, PCX_IO_BUF_SIZE - 1, handle);
} else {
// read the complete buffer
- io.read_proc(ReadBuf, 1, IO_BUF_SIZE, handle);
+ io.read_proc(ReadBuf, 1, PCX_IO_BUF_SIZE, handle);
}
*ReadPos = 0;
@@ -333,19 +333,38 @@ Load(FreeImageIO *io, fi_handle handle,
if ((header.manufacturer != 0x0A) || (header.version > 5))
throw "Invalid PCX file";
- // allocate a new DIB
+ // process the window
+ const WORD *window = header.window; // left, upper, right,lower pixel coord.
+ const int left = window[0];
+ const int top = window[1];
+ const int right = window[2];
+ const int bottom = window[3];
+
+ // check image size
+ if((left >= right) || (top >= bottom)) {
+ throw "Parsing error";
+ }
- WORD width = header.window[2] - header.window[0] + 1;
- WORD height = header.window[3] - header.window[1] + 1;
+ WORD width = right - left + 1;
+ WORD height = bottom - top + 1;
WORD bitcount = header.bpp * header.planes;
- if (bitcount == 24)
- dib = FreeImage_Allocate(width, height, bitcount, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
- else
- dib = FreeImage_Allocate(width, height, bitcount);
+ // allocate a new dib
+ switch(bitcount) {
+ case 1:
+ case 4:
+ case 8:
+ dib = FreeImage_Allocate(width, height, bitcount);
+ break;
+ case 24:
+ dib = FreeImage_Allocate(width, height, bitcount, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
+ break;
+ default:
+ throw "DIB allocation failed, maybe caused by an invalid image size or by a lack of memory";
+ break;
+ }
// if the dib couldn't be allocated, throw an error
-
if (!dib)
throw "DIB allocation failed";
@@ -392,19 +411,21 @@ Load(FreeImageIO *io, fi_handle handle,
if (palette_id == 0x0C) {
BYTE *cmap = (BYTE*)malloc(768 * sizeof(BYTE));
- io->read_proc(cmap, 768, 1, handle);
+ if(cmap) {
+ io->read_proc(cmap, 768, 1, handle);
- pal = FreeImage_GetPalette(dib);
- BYTE *pColormap = &cmap[0];
+ pal = FreeImage_GetPalette(dib);
+ BYTE *pColormap = &cmap[0];
- for(int i = 0; i < 256; i++) {
- pal[i].rgbRed = pColormap[0];
- pal[i].rgbGreen = pColormap[1];
- pal[i].rgbBlue = pColormap[2];
- pColormap += 3;
- }
+ for(int i = 0; i < 256; i++) {
+ pal[i].rgbRed = pColormap[0];
+ pal[i].rgbGreen = pColormap[1];
+ pal[i].rgbBlue = pColormap[2];
+ pColormap += 3;
+ }
- free(cmap);
+ free(cmap);
+ }
}
// wrong palette ID, perhaps a gray scale is needed ?
@@ -437,10 +458,16 @@ Load(FreeImageIO *io, fi_handle handle,
// ---------------
line = new BYTE[linelength];
+ if(!line) {
+ throw "Memory allocation failed";
+ }
bits = FreeImage_GetScanLine(dib, height - 1);
- ReadBuf = new BYTE[IO_BUF_SIZE];
+ ReadBuf = new BYTE[PCX_IO_BUF_SIZE];
+ if(!ReadBuf) {
+ throw "Memory allocation failed";
+ }
- int ReadPos = IO_BUF_SIZE;
+ int ReadPos = PCX_IO_BUF_SIZE;
if ((header.planes == 1) && ((header.bpp == 1) || (header.bpp == 8))) {
BYTE skip;
@@ -452,7 +479,7 @@ Load(FreeImageIO *io, fi_handle handle,
// skip trailing garbage at the end of the scanline
for (int count = written; count < linelength; count++) {
- if (ReadPos < IO_BUF_SIZE) {
+ if (ReadPos < PCX_IO_BUF_SIZE) {
ReadPos++;
} else {
io->read_proc(&skip, sizeof(BYTE), 1, handle);
@@ -468,6 +495,9 @@ Load(FreeImageIO *io, fi_handle handle,
WORD x, y, written;
buffer = new BYTE[width];
+ if(!buffer) {
+ throw "Memory allocation failed";
+ }
for (y = 0; y < height; y++) {
written = readline(*io, handle, line, linelength, rle, ReadBuf, &ReadPos);
@@ -494,7 +524,7 @@ Load(FreeImageIO *io, fi_handle handle,
// skip trailing garbage at the end of the scanline
for (int count = written; count < linelength; count++) {
- if (ReadPos < IO_BUF_SIZE) {
+ if (ReadPos < PCX_IO_BUF_SIZE) {
ReadPos++;
} else {
io->read_proc(&skip, sizeof(BYTE), 1, handle);