$NetBSD: patch-ak,v 1.3 2005/06/14 18:10:37 jlam Exp $

--- lib/scan.c.orig	1998-03-19 14:51:00.000000000 -0500
+++ lib/scan.c
@@ -42,6 +42,8 @@
  * Lorens Younes (d93-hyo@nada.kth.se) 4/96
  */
 
+/* October 2004, source code review by Thomas Biege <thomas@suse.de> */
+
 #include "XpmI.h"
 
 #define MAXPRINTABLE 92			/* number of printable ascii chars
@@ -103,7 +105,8 @@ LFUNC(MSWGetImagePixels, int, (Display *
 LFUNC(ScanTransparentColor, int, (XpmColor *color, unsigned int cpp,
 				  XpmAttributes *attributes));
 
-LFUNC(ScanOtherColors, int, (Display *display, XpmColor *colors, int ncolors,
+LFUNC(ScanOtherColors, int, (Display *display, XpmColor *colors,
+			     unsigned int ncolors,
 			     Pixel *pixels, unsigned int mask,
 			     unsigned int cpp, XpmAttributes *attributes));
 
@@ -167,10 +170,10 @@ storeMaskPixel(pixel, pmap, index_return
 /* function call in case of error */
 #undef RETURN
 #define RETURN(status) \
-{ \
+do { \
       ErrorStatus = status; \
       goto error; \
-}
+} while(0)
 
 /*
  * This function scans the given image and stores the found informations in
@@ -191,7 +194,7 @@ XpmCreateXpmImageFromImage(display, imag
     /* variables to return */
     PixelsMap pmap;
     XpmColor *colorTable = NULL;
-    int ErrorStatus;
+    int ErrorStatus = 0;
 
     /* calculation variables */
     unsigned int width = 0;
@@ -228,11 +231,17 @@ XpmCreateXpmImageFromImage(display, imag
     else
 	cpp = 0;
 
+    if ((height > 0 && width >= UINT_MAX / height) ||
+	width * height >= UINT_MAX / sizeof(unsigned int))
+	RETURN(XpmNoMemory);
     pmap.pixelindex =
 	(unsigned int *) XpmCalloc(width * height, sizeof(unsigned int));
     if (!pmap.pixelindex)
 	RETURN(XpmNoMemory);
 
+    if (pmap.size >= UINT_MAX / sizeof(Pixel)) 
+	RETURN(XpmNoMemory);
+
     pmap.pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * pmap.size);
     if (!pmap.pixels)
 	RETURN(XpmNoMemory);
@@ -297,7 +306,8 @@ XpmCreateXpmImageFromImage(display, imag
      * get rgb values and a string of char, and possibly a name for each
      * color
      */
-
+    if (pmap.ncolors >= UINT_MAX / sizeof(XpmColor))
+	RETURN(XpmNoMemory);
     colorTable = (XpmColor *) XpmCalloc(pmap.ncolors, sizeof(XpmColor));
     if (!colorTable)
 	RETURN(XpmNoMemory);
@@ -356,6 +366,8 @@ ScanTransparentColor(color, cpp, attribu
 
     /* first get a character string */
     a = 0;
+    if (cpp >= UINT_MAX - 1)
+	return (XpmNoMemory);
     if (!(s = color->string = (char *) XpmMalloc(cpp + 1)))
 	return (XpmNoMemory);
     *s++ = printable[c = a % MAXPRINTABLE];
@@ -403,7 +415,7 @@ static int
 ScanOtherColors(display, colors, ncolors, pixels, mask, cpp, attributes)
     Display *display;
     XpmColor *colors;
-    int ncolors;
+    unsigned int ncolors;
     Pixel *pixels;
     unsigned int mask;
     unsigned int cpp;
@@ -423,10 +435,10 @@ ScanOtherColors(display, colors, ncolors
     XpmColor *color;
     XColor *xcolors = NULL, *xcolor;
     char *colorname, *s;
-    XpmColor *colorTable, **oldColorTable = NULL;
+    XpmColor *colorTable = NULL, **oldColorTable = NULL;
     unsigned int ancolors = 0;
-    Pixel *apixels;
-    unsigned int mask_pixel;
+    Pixel *apixels = NULL;
+    unsigned int mask_pixel = 0;
     Bool found;
 
     /* retrieve information from the XpmAttributes */
@@ -447,6 +459,8 @@ ScanOtherColors(display, colors, ncolors
     }
 
     /* first get character strings and rgb values */
+    if (ncolors >= UINT_MAX / sizeof(XColor) || cpp >= UINT_MAX - 1)
+	return (XpmNoMemory);
     xcolors = (XColor *) XpmMalloc(sizeof(XColor) * ncolors);
     if (!xcolors)
 	return (XpmNoMemory);
@@ -603,8 +617,8 @@ GetImagePixels(image, width, height, pma
     char *dst;
     unsigned int *iptr;
     char *data;
-    int x, y, i;
-    int bits, depth, ibu, ibpp, offset;
+    unsigned int x, y;
+    int bits, depth, ibu, ibpp, offset, i;
     unsigned long lbt;
     Pixel pixel, px;
 
@@ -615,6 +629,9 @@ GetImagePixels(image, width, height, pma
     ibpp = image->bits_per_pixel;
     offset = image->xoffset;
 
+    if (image->bitmap_unit < 0)
+	return (XpmNoMemory);
+
     if ((image->bits_per_pixel | image->depth) == 1) {
 	ibu = image->bitmap_unit;
 	for (y = 0; y < height; y++)
@@ -705,7 +722,7 @@ GetImagePixels32(image, width, height, p
     unsigned char *addr;
     unsigned char *data;
     unsigned int *iptr;
-    int x, y;
+    unsigned int x, y;
     unsigned long lbt;
     Pixel pixel;
     int depth;
@@ -770,7 +787,7 @@ GetImagePixels16(image, width, height, p
     unsigned char *addr;
     unsigned char *data;
     unsigned int *iptr;
-    int x, y;
+    unsigned int x, y;
     unsigned long lbt;
     Pixel pixel;
     int depth;
@@ -815,7 +832,7 @@ GetImagePixels8(image, width, height, pm
 {
     unsigned int *iptr;
     unsigned char *data;
-    int x, y;
+    unsigned int x, y;
     unsigned long lbt;
     Pixel pixel;
     int depth;
@@ -848,7 +865,7 @@ GetImagePixels1(image, width, height, pm
     int (*storeFunc) ();
 {
     unsigned int *iptr;
-    int x, y;
+    unsigned int x, y;
     char *data;
     Pixel pixel;
     int xoff, yoff, offset, bpl;
@@ -884,11 +901,11 @@ GetImagePixels1(image, width, height, pm
 # else /* AMIGA */
 
 #define CLEAN_UP(status) \
-{\
+do {\
     if (pixels) XpmFree (pixels);\
     if (tmp_img) FreeXImage (tmp_img);\
     return (status);\
-}
+} while(0)
 
 static int
 AGetImagePixels (
@@ -909,7 +926,7 @@ AGetImagePixels (
     
     tmp_img = AllocXImage ((((width+15)>>4)<<4), 1, image->rp->BitMap->Depth);
     if (tmp_img == NULL)
-	CLEAN_UP (XpmNoMemory)
+	CLEAN_UP (XpmNoMemory);
     
     iptr = pmap->pixelindex;
     for (y = 0; y < height; ++y)
@@ -918,11 +935,11 @@ AGetImagePixels (
 	for (x = 0; x < width; ++x, ++iptr)
 	{
 	    if ((*storeFunc) (pixels[x], pmap, iptr))
-		CLEAN_UP (XpmNoMemory)
+		CLEAN_UP (XpmNoMemory);
 	}
     }
     
-    CLEAN_UP (XpmSuccess)
+    CLEAN_UP (XpmSuccess);
 }
 
 #undef CLEAN_UP
