aboutsummaryrefslogtreecommitdiff
https://sources.debian.org/data/main/f/freeimage/3.18.0%2Bds2-10/debian/patches/r1848-improved-PFM-plugin-against-malicious-images.patch

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);
 		}