$OpenBSD: patch-gdk_imlib_io-bmp_c,v 1.2 2004/09/15 19:41:44 robert Exp $
--- gdk_imlib/io-bmp.c.orig	Mon Mar  4 18:06:29 2002
+++ gdk_imlib/io-bmp.c	Wed Sep 15 11:30:44 2004
@@ -42,12 +42,12 @@
   fread(dbuf, 4, 2, file);
   *w = (int)dbuf[0];
   *h = (int)dbuf[1];
-  if (*w > 32767)
+  if ((*w < 0) || (*w > 32767))
     {
       fprintf(stderr, "IMLIB ERROR: Image width > 32767 pixels for file\n");
       return NULL;
     }
-  if (*h > 32767)
+  if ((*h < 0) || (*h > 32767))
     {
       fprintf(stderr, "IMLIB ERROR: Image height > 32767 pixels for file\n");
       return NULL;
@@ -56,9 +56,9 @@
   planes = (int)word;
   fread(&word, 2, 1, file);
   bpp = (int)word;
-  if (bpp != 1 && bpp != 4 && bpp != 8 && bpp && 16 && bpp != 24 && bpp != 32)
+  if (bpp != 1 && bpp != 4 && bpp != 8 && bpp != 16 && bpp != 24 && bpp != 32)
     {
-      fprintf(stderr, "IMLIB ERROR: unknown bitdepth in file\n");
+      fprintf(stderr, "IMLIB ERROR: unknown bitdepth %d in file\n", bpp);
       return NULL;
     }
   fread(dbuf, 4, 4, file);
@@ -72,6 +72,9 @@
   ncolors = (int)dbuf[0];
   if (ncolors == 0)
     ncolors = 1 << bpp;
+  if ((ncolors < 0) || (ncolors > (1 << bpp)))
+    ncolors = 1 << bpp;
+
   /* some more sanity checks */
   if (((comp == BI_RLE4) && (bpp != 4)) || ((comp == BI_RLE8) && (bpp != 8)) || ((comp == BI_BITFIELDS) && (bpp != 16 && bpp != 32)))
     {
@@ -197,9 +200,13 @@
 		  for (bit = 0; bit < 8; bit++)
 		    {
 		      index = ((byte & (0x80 >> bit)) ? 1 : 0);
-		      ptr[poffset] = cmap[index].r;
-		      ptr[poffset + 1] = cmap[index].g;
-		      ptr[poffset + 2] = cmap[index].b;
+		      /* possibly corrupted file? */
+		      if (index < ncolors && poffset < *w * *h * 3)
+			{
+			  ptr[poffset] = cmap[index].r;
+			  ptr[poffset + 1] = cmap[index].g;
+			  ptr[poffset + 2] = cmap[index].b;
+			}
 		      column++;
 		    }
 		}
@@ -221,9 +228,13 @@
 			  index = ((byte & (0xF0 >> nibble * 4)) >> (!nibble * 4));
 			  if (index >= 16)
 			    index = 15;
-			  ptr[poffset] = cmap[index].r;
-			  ptr[poffset + 1] = cmap[index].g;
-			  ptr[poffset + 2] = cmap[index].b;
+			  /* possibly corrupted file? */
+			  if (index < ncolors && poffset < *w * *h * 3)
+			    {
+			      ptr[poffset] = cmap[index].r;
+			      ptr[poffset + 1] = cmap[index].g;
+			      ptr[poffset + 2] = cmap[index].b;
+			    }
 			  column++;
 			}
 		    }
@@ -263,9 +274,13 @@
 				{
 				  linepos++;
 				  byte = getc(file);
-				  ptr[poffset] = cmap[byte].r;
-				  ptr[poffset + 1] = cmap[byte].g;
-				  ptr[poffset + 2] = cmap[byte].b;
+				  /* possibly corrupted file? */
+				  if (byte < ncolors && poffset < *w * *h * 3)
+				    {
+				      ptr[poffset] = cmap[byte].r;
+				      ptr[poffset + 1] = cmap[byte].g;
+				      ptr[poffset + 2] = cmap[byte].b;
+				    }
 				  column++;
 				}
 			      if (absolute & 0x01)
@@ -276,9 +291,13 @@
 			{
 			  for (i = 0; i < first; i++)
 			    {
-			      ptr[poffset] = cmap[byte].r;
-			      ptr[poffset + 1] = cmap[byte].g;
-			      ptr[poffset + 2] = cmap[byte].b;
+			      /* possibly corrupted file? */
+			      if (byte < ncolors && poffset < *w * *h * 3)
+				{
+				  ptr[poffset] = cmap[byte].r;
+				  ptr[poffset + 1] = cmap[byte].g;
+				  ptr[poffset + 2] = cmap[byte].b;
+				}
 			      column++;
 			      linepos++;
 			    }
@@ -286,9 +305,13 @@
 		    }
 		  else
 		    {
-		      ptr[poffset] = cmap[byte].r;
-		      ptr[poffset + 1] = cmap[byte].g;
-		      ptr[poffset + 2] = cmap[byte].b;
+		      /* possibly corrupted file? */
+		      if (byte < ncolors && poffset < *w * *h * 3)
+			{
+			  ptr[poffset] = cmap[byte].r;
+			  ptr[poffset + 1] = cmap[byte].g;
+			  ptr[poffset + 2] = cmap[byte].b;
+			}
 		      column++;
 		      linepos += size;
 		    }
@@ -297,9 +320,13 @@
 	  else if (bpp == 24)
 	    {
 	      linepos += fread(&bbuf, 1, 3, file);
-	      ptr[poffset] = (unsigned char)bbuf[2];
-	      ptr[poffset + 1] = (unsigned char)bbuf[1];
-	      ptr[poffset + 2] = (unsigned char)bbuf[0];
+	      /* possibly corrupted file? */
+	      if (poffset < *w * *h * 3)
+		{
+		  ptr[poffset] = (unsigned char)bbuf[2];
+		  ptr[poffset + 1] = (unsigned char)bbuf[1];
+		  ptr[poffset + 2] = (unsigned char)bbuf[0];
+		}
 	      column++;
 	    }
 	  else if (bpp == 16)
@@ -307,12 +334,16 @@
 	      unsigned char       temp;
 
 	      linepos += fread(&word, 2, 1, file);
-	      temp = (word & rmask) >> rshift;
-	      ptr[poffset] = temp;
-	      temp = (word & gmask) >> gshift;
-	      ptr[poffset + 1] = temp;
-	      temp = (word & bmask) >> gshift;
-	      ptr[poffset + 2] = temp;
+	      /* possibly corrupted file? */
+	      if (poffset < *w * *h * 3)
+		{
+		  temp = (word & rmask) >> rshift;
+		  ptr[poffset] = temp;
+		  temp = (word & gmask) >> gshift;
+		  ptr[poffset + 1] = temp;
+		  temp = (word & bmask) >> gshift;
+		  ptr[poffset + 2] = temp;
+		}
 	      column++;
 	    }
 	  else
@@ -320,12 +351,16 @@
 	      unsigned char       temp;
 
 	      linepos += fread(&dword, 4, 1, file);
-	      temp = (dword & rmask) >> rshift;
-	      ptr[poffset] = temp;
-	      temp = (dword & gmask) >> gshift;
-	      ptr[poffset + 1] = temp;
-	      temp = (dword & bmask) >> bshift;
-	      ptr[poffset + 2] = temp;
+	      /* possibly corrupted file? */
+	      if (poffset < *w * *h * 3)
+		{
+		  temp = (dword & rmask) >> rshift;
+		  ptr[poffset] = temp;
+		  temp = (dword & gmask) >> gshift;
+		  ptr[poffset + 1] = temp;
+		  temp = (dword & bmask) >> bshift;
+		  ptr[poffset + 2] = temp;
+		}
 	      column++;
 	    }
 	}
