diff -cr xpm-3.4k.orig/cxpm/Imakefile xpm-3.4k/cxpm/Imakefile
*** xpm-3.4k.orig/cxpm/Imakefile	1998-03-19 13:51:01.000000000 -0600
--- xpm-3.4k/cxpm/Imakefile	2004-12-01 15:49:00.000000000 -0600
***************
*** 31,36 ****
--- 31,39 ----
  XCOMM
  
  XCOMM default locations
+ #ifndef XpmLibDir
+ #define XpmLibDir $(USRLIBDIR)
+ #endif
  #ifndef XpmBinDir
  #define XpmBinDir $(BINDIR)
  #endif
***************
*** 41,51 ****
  #define XpmIncDir $(BUILDINCTOP)
  #endif
  
        XPMBINDIR = XpmBinDir
        XPMMANDIR = XpmManDir
        XPMINCDIR = XpmIncDir
  
!        INCLUDES = -I$(BUILDINCDIR) -I$(XPMINCDIR)
  
  #ifdef OsNameDefines
  OS_NAME_DEFINES = OsNameDefines
--- 44,58 ----
  #define XpmIncDir $(BUILDINCTOP)
  #endif
  
+       XPMLIBDIR = XpmLibDir
        XPMBINDIR = XpmBinDir
        XPMMANDIR = XpmManDir
        XPMINCDIR = XpmIncDir
  
!       INCLUDES = -I$(BUILDINCDIR) -I$(XPMINCDIR)
! 
! XPMLIB = -lXpm
! LOCAL_LIBRARIES = -L../lib -L$(XPMLIBDIR) $(XPMLIB) $(XTOOLLIB) $(XLIB)
  
  #ifdef OsNameDefines
  OS_NAME_DEFINES = OsNameDefines
diff -cr xpm-3.4k.orig/lib/Attrib.c xpm-3.4k/lib/Attrib.c
*** xpm-3.4k.orig/lib/Attrib.c	2004-12-01 14:43:15.000000000 -0600
--- xpm-3.4k/lib/Attrib.c	2004-12-01 15:49:00.000000000 -0600
***************
*** 32,44 ****
  *  Developed by Arnaud Le Hors                                                *
  \*****************************************************************************/
  
  #include "XpmI.h"
  
  /* 3.2 backward compatibility code */
  LFUNC(CreateOldColorTable, int, (XpmColor *ct, unsigned int ncolors,
  				 XpmColor ***oldct));
  
! LFUNC(FreeOldColorTable, void, (XpmColor **colorTable, int ncolors));
  
  /*
   * Create a colortable compatible with the old style colortable
--- 32,46 ----
  *  Developed by Arnaud Le Hors                                                *
  \*****************************************************************************/
  
+ /* October 2004, source code review by Thomas Biege <thomas@suse.de> */
+ 
  #include "XpmI.h"
  
  /* 3.2 backward compatibility code */
  LFUNC(CreateOldColorTable, int, (XpmColor *ct, unsigned int ncolors,
  				 XpmColor ***oldct));
  
! LFUNC(FreeOldColorTable, void, (XpmColor **colorTable, unsigned int ncolors));
  
  /*
   * Create a colortable compatible with the old style colortable
***************
*** 50,58 ****
      XpmColor ***oldct;
  {
      XpmColor **colorTable, **color;
!     int a;
  
!     if (ncolors >= SIZE_MAX / sizeof(XpmColor *)) 
  	return XpmNoMemory;
  
      colorTable = (XpmColor **) XpmMalloc(ncolors * sizeof(XpmColor *));
--- 52,60 ----
      XpmColor ***oldct;
  {
      XpmColor **colorTable, **color;
!     unsigned int a;
  
!     if (ncolors >= UINT_MAX / sizeof(XpmColor *)) 
  	return XpmNoMemory;
  
      colorTable = (XpmColor **) XpmMalloc(ncolors * sizeof(XpmColor *));
***************
*** 69,77 ****
  static void
  FreeOldColorTable(colorTable, ncolors)
      XpmColor **colorTable;
!     int ncolors;
  {
!     int a, b;
      XpmColor **color;
      char **sptr;
  
--- 71,79 ----
  static void
  FreeOldColorTable(colorTable, ncolors)
      XpmColor **colorTable;
!     unsigned int ncolors;
  {
!     unsigned int a, b;
      XpmColor **color;
      char **sptr;
  
***************
*** 122,128 ****
      XpmExtension *ext;
      char **sptr;
  
!     if (extensions) {
  	for (i = 0, ext = extensions; i < nextensions; i++, ext++) {
  	    if (ext->name)
  		XpmFree(ext->name);
--- 124,130 ----
      XpmExtension *ext;
      char **sptr;
  
!     if (extensions  && nextensions > 0) {
  	for (i = 0, ext = extensions; i < nextensions; i++, ext++) {
  	    if (ext->name)
  		XpmFree(ext->name);
diff -cr xpm-3.4k.orig/lib/CrBufFrI.c xpm-3.4k/lib/CrBufFrI.c
*** xpm-3.4k.orig/lib/CrBufFrI.c	1998-03-19 13:50:59.000000000 -0600
--- xpm-3.4k/lib/CrBufFrI.c	2004-12-01 15:49:00.000000000 -0600
***************
*** 32,52 ****
  *  Developed by Arnaud Le Hors                                                *
  \*****************************************************************************/
  
  #include "XpmI.h"
  
  LFUNC(WriteColors, int, (char **dataptr, unsigned int *data_size,
  			 unsigned int *used_size, XpmColor *colors,
  			 unsigned int ncolors, unsigned int cpp));
  
! LFUNC(WritePixels, void, (char *dataptr, unsigned int *used_size,
  			  unsigned int width, unsigned int height,
  			  unsigned int cpp, unsigned int *pixels,
  			  XpmColor *colors));
  
! LFUNC(WriteExtensions, void, (char *dataptr, unsigned int *used_size,
  			      XpmExtension *ext, unsigned int num));
  
! LFUNC(ExtensionsSize, int, (XpmExtension *ext, unsigned int num));
  LFUNC(CommentsSize, int, (XpmInfo *info));
  
  int
--- 32,56 ----
  *  Developed by Arnaud Le Hors                                                *
  \*****************************************************************************/
  
+ /* October 2004, source code review by Thomas Biege <thomas@suse.de> */
+ 
  #include "XpmI.h"
  
  LFUNC(WriteColors, int, (char **dataptr, unsigned int *data_size,
  			 unsigned int *used_size, XpmColor *colors,
  			 unsigned int ncolors, unsigned int cpp));
  
! LFUNC(WritePixels, void, (char *dataptr, unsigned int data_size,
! 			  unsigned int *used_size,
  			  unsigned int width, unsigned int height,
  			  unsigned int cpp, unsigned int *pixels,
  			  XpmColor *colors));
  
! LFUNC(WriteExtensions, void, (char *dataptr, unsigned int data_size,
! 			      unsigned int *used_size,
  			      XpmExtension *ext, unsigned int num));
  
! LFUNC(ExtensionsSize, unsigned int, (XpmExtension *ext, unsigned int num));
  LFUNC(CommentsSize, int, (XpmInfo *info));
  
  int
***************
*** 89,98 ****
  
  #undef RETURN
  #define RETURN(status) \
  { \
        ErrorStatus = status; \
        goto error; \
! }
  
  int
  XpmCreateBufferFromXpmImage(buffer_return, image, info)
--- 93,103 ----
  
  #undef RETURN
  #define RETURN(status) \
+ do \
  { \
        ErrorStatus = status; \
        goto error; \
! }while(0)
  
  int
  XpmCreateBufferFromXpmImage(buffer_return, image, info)
***************
*** 106,112 ****
      unsigned int cmts, extensions, ext_size = 0;
      unsigned int l, cmt_size = 0;
      char *ptr = NULL, *p;
!     unsigned int ptr_size, used_size;
  
      *buffer_return = NULL;
  
--- 111,117 ----
      unsigned int cmts, extensions, ext_size = 0;
      unsigned int l, cmt_size = 0;
      char *ptr = NULL, *p;
!     unsigned int ptr_size, used_size, tmp;
  
      *buffer_return = NULL;
  
***************
*** 128,134 ****
  #ifdef VOID_SPRINTF
      used_size = strlen(buf);
  #endif
!     ptr_size = used_size + ext_size + cmt_size + 1;
      ptr = (char *) XpmMalloc(ptr_size);
      if (!ptr)
  	return XpmNoMemory;
--- 133,145 ----
  #ifdef VOID_SPRINTF
      used_size = strlen(buf);
  #endif
!     ptr_size = used_size + ext_size + cmt_size + 1; /* ptr_size can't be 0 */
!     if(ptr_size <= used_size ||
!        ptr_size <= ext_size  ||
!        ptr_size <= cmt_size)
!     {
!         return XpmNoMemory;
!     }
      ptr = (char *) XpmMalloc(ptr_size);
      if (!ptr)
  	return XpmNoMemory;
***************
*** 139,145 ****
  #ifndef VOID_SPRINTF
  	used_size +=
  #endif
! 	sprintf(ptr + used_size, "/*%s*/\n", info->hints_cmt);
  #ifdef VOID_SPRINTF
  	used_size += strlen(info->hints_cmt) + 5;
  #endif
--- 150,156 ----
  #ifndef VOID_SPRINTF
  	used_size +=
  #endif
! 	snprintf(ptr + used_size, ptr_size-used_size, "/*%s*/\n", info->hints_cmt);
  #ifdef VOID_SPRINTF
  	used_size += strlen(info->hints_cmt) + 5;
  #endif
***************
*** 157,163 ****
  #ifndef VOID_SPRINTF
  	l +=
  #endif
! 	sprintf(buf + l, " %d %d", info->x_hotspot, info->y_hotspot);
  #ifdef VOID_SPRINTF
  	l = strlen(buf);
  #endif
--- 168,174 ----
  #ifndef VOID_SPRINTF
  	l +=
  #endif
! 	snprintf(buf + l, sizeof(buf)-l, " %d %d", info->x_hotspot, info->y_hotspot);
  #ifdef VOID_SPRINTF
  	l = strlen(buf);
  #endif
***************
*** 179,184 ****
--- 190,197 ----
      l = strlen(buf);
  #endif
      ptr_size += l;
+     if(ptr_size <= l)
+         RETURN(XpmNoMemory);
      p = (char *) XpmRealloc(ptr, ptr_size);
      if (!p)
  	RETURN(XpmNoMemory);
***************
*** 191,197 ****
  #ifndef VOID_SPRINTF
  	used_size +=
  #endif
! 	sprintf(ptr + used_size, "/*%s*/\n", info->colors_cmt);
  #ifdef VOID_SPRINTF
  	used_size += strlen(info->colors_cmt) + 5;
  #endif
--- 204,210 ----
  #ifndef VOID_SPRINTF
  	used_size +=
  #endif
! 	snprintf(ptr + used_size, ptr_size-used_size, "/*%s*/\n", info->colors_cmt);
  #ifdef VOID_SPRINTF
  	used_size += strlen(info->colors_cmt) + 5;
  #endif
***************
*** 207,213 ****
       * 4 = 1 (for '"') + 3 (for '",\n')
       * 1 = - 2 (because the last line does not end with ',\n') + 3 (for '};\n')
       */
!     ptr_size += image->height * (image->width * image->cpp + 4) + 1;
  
      p = (char *) XpmRealloc(ptr, ptr_size);
      if (!p)
--- 220,231 ----
       * 4 = 1 (for '"') + 3 (for '",\n')
       * 1 = - 2 (because the last line does not end with ',\n') + 3 (for '};\n')
       */
!      if(image->width  > UINT_MAX / image->cpp ||
!        (tmp = image->width * image->cpp + 4) <= 4 ||
!         image->height > UINT_MAX / tmp ||
!        (tmp = image->height * tmp + 1) <= 1 ||
!        (ptr_size += tmp) <= tmp)
! 	RETURN(XpmNoMemory);
  
      p = (char *) XpmRealloc(ptr, ptr_size);
      if (!p)
***************
*** 219,235 ****
  #ifndef VOID_SPRINTF
  	used_size +=
  #endif
! 	sprintf(ptr + used_size, "/*%s*/\n", info->pixels_cmt);
  #ifdef VOID_SPRINTF
  	used_size += strlen(info->pixels_cmt) + 5;
  #endif
      }
!     WritePixels(ptr + used_size, &used_size, image->width, image->height,
  		image->cpp, image->data, image->colorTable);
  
      /* print extensions */
      if (extensions)
! 	WriteExtensions(ptr + used_size, &used_size,
  			info->extensions, info->nextensions);
  
      /* close the array */
--- 237,253 ----
  #ifndef VOID_SPRINTF
  	used_size +=
  #endif
! 	snprintf(ptr + used_size, ptr_size-used_size, "/*%s*/\n", info->pixels_cmt);
  #ifdef VOID_SPRINTF
  	used_size += strlen(info->pixels_cmt) + 5;
  #endif
      }
!     WritePixels(ptr + used_size, ptr_size - used_size, &used_size, image->width, image->height,
  		image->cpp, image->data, image->colorTable);
  
      /* print extensions */
      if (extensions)
! 	WriteExtensions(ptr + used_size, ptr_size-used_size, &used_size,
  			info->extensions, info->nextensions);
  
      /* close the array */
***************
*** 246,251 ****
--- 264,270 ----
      return (ErrorStatus);
  }
  
+ 
  static int
  WriteColors(dataptr, data_size, used_size, colors, ncolors, cpp)
      char **dataptr;
***************
*** 255,261 ****
      unsigned int ncolors;
      unsigned int cpp;
  {
!     char buf[BUFSIZ];
      unsigned int a, key, l;
      char *s, *s2;
      char **defaults;
--- 274,280 ----
      unsigned int ncolors;
      unsigned int cpp;
  {
!     char buf[BUFSIZ] = {0};
      unsigned int a, key, l;
      char *s, *s2;
      char **defaults;
***************
*** 265,270 ****
--- 284,291 ----
  
  	defaults = (char **) colors;
  	s = buf + 1;
+ 	if(cpp > (sizeof(buf) - (s-buf)))
+ 		return(XpmNoMemory);
  	strncpy(s, *defaults++, cpp);
  	s += cpp;
  
***************
*** 273,286 ****
  #ifndef VOID_SPRINTF
  		s +=
  #endif
! 		sprintf(s, "\t%s %s", xpmColorKeys[key - 1], s2);
  #ifdef VOID_SPRINTF
  		s += strlen(s);
  #endif
  	    }
  	}
  	strcpy(s, "\",\n");
  	l = s + 3 - buf;
  	s = (char *) XpmRealloc(*dataptr, *data_size + l);
  	if (!s)
  	    return (XpmNoMemory);
--- 294,317 ----
  #ifndef VOID_SPRINTF
  		s +=
  #endif
! 		/* assume C99 compliance */
! 		snprintf(s, sizeof(buf) - (s-buf), "\t%s %s", xpmColorKeys[key - 1], s2);
  #ifdef VOID_SPRINTF
  		s += strlen(s);
  #endif
+ 		/* now let's check if s points out-of-bounds */
+ 		if((s-buf) > sizeof(buf))
+ 			return(XpmNoMemory);
  	    }
  	}
+ 	if(sizeof(buf) - (s-buf) < 4)
+ 		return(XpmNoMemory);
  	strcpy(s, "\",\n");
  	l = s + 3 - buf;
+ 	if( *data_size                   >= UINT_MAX-l ||
+ 	    *data_size + l               <= *used_size ||
+ 	   (*data_size + l - *used_size) <= sizeof(buf))
+ 		return(XpmNoMemory);
  	s = (char *) XpmRealloc(*dataptr, *data_size + l);
  	if (!s)
  	    return (XpmNoMemory);
***************
*** 293,300 ****
  }
  
  static void
! WritePixels(dataptr, used_size, width, height, cpp, pixels, colors)
      char *dataptr;
      unsigned int *used_size;
      unsigned int width;
      unsigned int height;
--- 324,332 ----
  }
  
  static void
! WritePixels(dataptr, data_size, used_size, width, height, cpp, pixels, colors)
      char *dataptr;
+     unsigned int data_size;
      unsigned int *used_size;
      unsigned int width;
      unsigned int height;
***************
*** 305,331 ****
      char *s = dataptr;
      unsigned int x, y, h;
  
      h = height - 1;
      for (y = 0; y < h; y++) {
  	*s++ = '"';
  	for (x = 0; x < width; x++, pixels++) {
! 	    strncpy(s, colors[*pixels].string, cpp);
  	    s += cpp;
  	}
  	strcpy(s, "\",\n");
  	s += 3;
      }
      /* duplicate some code to avoid a test in the loop */
      *s++ = '"';
      for (x = 0; x < width; x++, pixels++) {
! 	strncpy(s, colors[*pixels].string, cpp);
  	s += cpp;
      }
      *s++ = '"';
      *used_size += s - dataptr;
  }
  
! static int
  ExtensionsSize(ext, num)
      XpmExtension *ext;
      unsigned int num;
--- 337,372 ----
      char *s = dataptr;
      unsigned int x, y, h;
  
+     if(height <= 1)
+     	return;
+ 
      h = height - 1;
      for (y = 0; y < h; y++) {
  	*s++ = '"';
  	for (x = 0; x < width; x++, pixels++) {
! 	    if(cpp >= (data_size - (s-dataptr)))
! 		return;
! 	    strncpy(s, colors[*pixels].string, cpp); /* how can we trust *pixels? :-\ */
  	    s += cpp;
  	}
+ 	if((data_size - (s-dataptr)) < 4)
+ 		return;
  	strcpy(s, "\",\n");
  	s += 3;
      }
      /* duplicate some code to avoid a test in the loop */
      *s++ = '"';
      for (x = 0; x < width; x++, pixels++) {
! 	if(cpp >= (data_size - (s-dataptr)))
! 	    return;
! 	strncpy(s, colors[*pixels].string, cpp); /* how can we trust *pixels? */
  	s += cpp;
      }
      *s++ = '"';
      *used_size += s - dataptr;
  }
  
! static unsigned int
  ExtensionsSize(ext, num)
      XpmExtension *ext;
      unsigned int num;
***************
*** 334,354 ****
      char **line;
  
      size = 0;
      for (x = 0; x < num; x++, ext++) {
  	/* 11 = 10 (for ',\n"XPMEXT ') + 1 (for '"') */
  	size += strlen(ext->name) + 11;
! 	a = ext->nlines;
  	for (y = 0, line = ext->lines; y < a; y++, line++)
  	    /* 4 = 3 (for ',\n"') + 1 (for '"') */
  	    size += strlen(*line) + 4;
      }
      /* 13 is for ',\n"XPMENDEXT"' */
      return size + 13;
  }
  
  static void
! WriteExtensions(dataptr, used_size, ext, num)
      char *dataptr;
      unsigned int *used_size;
      XpmExtension *ext;
      unsigned int num;
--- 375,400 ----
      char **line;
  
      size = 0;
+     if(num == 0)
+     	return(0); /* ok? */
      for (x = 0; x < num; x++, ext++) {
  	/* 11 = 10 (for ',\n"XPMEXT ') + 1 (for '"') */
  	size += strlen(ext->name) + 11;
! 	a = ext->nlines; /* how can we trust ext->nlines to be not out-of-bounds? */
  	for (y = 0, line = ext->lines; y < a; y++, line++)
  	    /* 4 = 3 (for ',\n"') + 1 (for '"') */
  	    size += strlen(*line) + 4;
      }
      /* 13 is for ',\n"XPMENDEXT"' */
+     if(size > UINT_MAX - 13) /* unlikely */
+     	return(0);
      return size + 13;
  }
  
  static void
! WriteExtensions(dataptr, data_size, used_size, ext, num)
      char *dataptr;
+     unsigned int data_size;
      unsigned int *used_size;
      XpmExtension *ext;
      unsigned int num;
***************
*** 361,367 ****
  #ifndef VOID_SPRINTF
  	s +=
  #endif
! 	sprintf(s, ",\n\"XPMEXT %s\"", ext->name);
  #ifdef VOID_SPRINTF
  	s += strlen(ext->name) + 11;
  #endif
--- 407,413 ----
  #ifndef VOID_SPRINTF
  	s +=
  #endif
! 	snprintf(s, data_size - (s-dataptr), ",\n\"XPMEXT %s\"", ext->name);
  #ifdef VOID_SPRINTF
  	s += strlen(ext->name) + 11;
  #endif
***************
*** 370,382 ****
  #ifndef VOID_SPRINTF
  	    s +=
  #endif
! 	    sprintf(s, ",\n\"%s\"", *line);
  #ifdef VOID_SPRINTF
  	    s += strlen(*line) + 4;
  #endif
  	}
      }
!     strcpy(s, ",\n\"XPMENDEXT\"");
      *used_size += s - dataptr + 13;
  }
  
--- 416,428 ----
  #ifndef VOID_SPRINTF
  	    s +=
  #endif
! 	    snprintf(s, data_size - (s-dataptr), ",\n\"%s\"", *line);
  #ifdef VOID_SPRINTF
  	    s += strlen(*line) + 4;
  #endif
  	}
      }
!     strncpy(s, ",\n\"XPMENDEXT\"", data_size - (s-dataptr)-1);
      *used_size += s - dataptr + 13;
  }
  
***************
*** 387,392 ****
--- 433,439 ----
      int size = 0;
  
      /* 5 = 2 (for "/_*") + 3 (for "*_/\n") */
+     /* wrap possible but *very* unlikely */
      if (info->hints_cmt)
  	size += 5 + strlen(info->hints_cmt);
  
diff -cr xpm-3.4k.orig/lib/CrDatFrI.c xpm-3.4k/lib/CrDatFrI.c
*** xpm-3.4k.orig/lib/CrDatFrI.c	2004-12-01 14:43:15.000000000 -0600
--- xpm-3.4k/lib/CrDatFrI.c	2004-12-01 15:49:00.000000000 -0600
***************
*** 32,44 ****
  *  Developed by Arnaud Le Hors                                                *
  \*****************************************************************************/
  
  #include "XpmI.h"
  
  LFUNC(CreateColors, int, (char **dataptr, unsigned int *data_size,
  			  XpmColor *colors, unsigned int ncolors,
  			  unsigned int cpp));
  
! LFUNC(CreatePixels, void, (char **dataptr, unsigned int width,
  			   unsigned int height, unsigned int cpp,
  			   unsigned int *pixels, XpmColor *colors));
  
--- 32,47 ----
  *  Developed by Arnaud Le Hors                                                *
  \*****************************************************************************/
  
+ /* October 2004, source code review by Thomas Biege <thomas@suse.de> */
+ 
  #include "XpmI.h"
  
  LFUNC(CreateColors, int, (char **dataptr, unsigned int *data_size,
  			  XpmColor *colors, unsigned int ncolors,
  			  unsigned int cpp));
  
! LFUNC(CreatePixels, void, (char **dataptr, unsigned int data_size,
! 			   unsigned int width,
  			   unsigned int height, unsigned int cpp,
  			   unsigned int *pixels, XpmColor *colors));
  
***************
*** 46,52 ****
  			      unsigned int *ext_size,
  			      unsigned int *ext_nlines));
  
! LFUNC(CreateExtensions, void, (char **dataptr, unsigned int offset,
  			       XpmExtension *ext, unsigned int num,
  			       unsigned int ext_nlines));
  
--- 49,56 ----
  			      unsigned int *ext_size,
  			      unsigned int *ext_nlines));
  
! LFUNC(CreateExtensions, void, (char **dataptr, unsigned int data_size,
! 			       unsigned int offset,
  			       XpmExtension *ext, unsigned int num,
  			       unsigned int ext_nlines));
  
***************
*** 87,96 ****
  
  #undef RETURN
  #define RETURN(status) \
  { \
        ErrorStatus = status; \
        goto exit; \
! }
  
  int
  XpmCreateDataFromXpmImage(data_return, image, info)
--- 91,101 ----
  
  #undef RETURN
  #define RETURN(status) \
+ do \
  { \
        ErrorStatus = status; \
        goto exit; \
! } while(0)
  
  int
  XpmCreateDataFromXpmImage(data_return, image, info)
***************
*** 121,131 ****
       * alloc a temporary array of char pointer for the header section which
       * is the hints line + the color table lines
       */
!     header_nlines = 1 + image->ncolors;
      header_size = sizeof(char *) * header_nlines;
!     if (header_size >= SIZE_MAX / sizeof(char *))
  	return (XpmNoMemory);
!     header = (char **) XpmCalloc(header_size, sizeof(char *));
      if (!header)
  	return (XpmNoMemory);
  
--- 126,142 ----
       * alloc a temporary array of char pointer for the header section which
       * is the hints line + the color table lines
       */
!     header_nlines = 1 + image->ncolors; /* this may wrap and/or become 0 */
! 
!     /* 2nd check superfluous if we do not need header_nlines any further */
!     if(header_nlines <= image->ncolors ||
!        header_nlines >= UINT_MAX / sizeof(char *))
!     	return(XpmNoMemory);
! 
      header_size = sizeof(char *) * header_nlines;
!     if (header_size >= UINT_MAX / sizeof(char *))
  	return (XpmNoMemory);
!     header = (char **) XpmCalloc(header_size, sizeof(char *)); /* can we trust image->ncolors */
      if (!header)
  	return (XpmNoMemory);
  
***************
*** 169,176 ****
  
      /* now we know the size needed, alloc the data and copy the header lines */
      offset = image->width * image->cpp + 1;
!     data_size = header_size + (image->height + ext_nlines) * sizeof(char *)
! 	+ image->height * offset + ext_size;
  
      data = (char **) XpmMalloc(data_size);
      if (!data)
--- 180,201 ----
  
      /* now we know the size needed, alloc the data and copy the header lines */
      offset = image->width * image->cpp + 1;
! 
!     if(offset <= image->width || offset <= image->cpp)
! 	RETURN(XpmNoMemory);
! 
!     if( (image->height + ext_nlines) >= UINT_MAX / sizeof(char *))
! 	RETURN(XpmNoMemory);
!     data_size = (image->height + ext_nlines) * sizeof(char *);
! 
!     if (image->height > UINT_MAX / offset ||
!         image->height * offset > UINT_MAX - data_size)
! 	RETURN(XpmNoMemory);
!     data_size += image->height * offset;
! 
!     if( (header_size + ext_size) >= (UINT_MAX - data_size) )
! 	RETURN(XpmNoMemory);
!     data_size += header_size + ext_size;
  
      data = (char **) XpmMalloc(data_size);
      if (!data)
***************
*** 178,185 ****
  
      data_nlines = header_nlines + image->height + ext_nlines;
      *data = (char *) (data + data_nlines);
      n = image->ncolors;
!     for (l = 0, sptr = data, sptr2 = header; l <= n; l++, sptr++, sptr2++) {
  	strcpy(*sptr, *sptr2);
  	*(sptr + 1) = *sptr + strlen(*sptr2) + 1;
      }
--- 203,212 ----
  
      data_nlines = header_nlines + image->height + ext_nlines;
      *data = (char *) (data + data_nlines);
+ 
+     /* can header have less elements then n suggests? */
      n = image->ncolors;
!     for (l = 0, sptr = data, sptr2 = header; l <= n && sptr && sptr2; l++, sptr++, sptr2++) {
  	strcpy(*sptr, *sptr2);
  	*(sptr + 1) = *sptr + strlen(*sptr2) + 1;
      }
***************
*** 188,199 ****
      data[header_nlines] = (char *) data + header_size
  	+ (image->height + ext_nlines) * sizeof(char *);
  
!     CreatePixels(data + header_nlines, image->width, image->height,
  		 image->cpp, image->data, image->colorTable);
  
      /* print extensions */
      if (extensions)
! 	CreateExtensions(data + header_nlines + image->height - 1, offset,
  			 info->extensions, info->nextensions,
  			 ext_nlines);
  
--- 215,227 ----
      data[header_nlines] = (char *) data + header_size
  	+ (image->height + ext_nlines) * sizeof(char *);
  
!     CreatePixels(data + header_nlines, data_size-header_nlines, image->width, image->height,
  		 image->cpp, image->data, image->colorTable);
  
      /* print extensions */
      if (extensions)
! 	CreateExtensions(data + header_nlines + image->height - 1,
! 			 data_size - header_nlines - image->height + 1, offset,
  			 info->extensions, info->nextensions,
  			 ext_nlines);
  
***************
*** 224,246 ****
      char *s, *s2;
      char **defaults;
  
      for (a = 0; a < ncolors; a++, colors++, dataptr++) {
  
  	defaults = (char **) colors;
  	strncpy(buf, *defaults++, cpp);
  	s = buf + cpp;
  
  	for (key = 1; key <= NKEYS; key++, defaults++) {
  	    if (s2 = *defaults) {
  #ifndef VOID_SPRINTF
  		s +=
  #endif
! 		sprintf(s, "\t%s %s", xpmColorKeys[key - 1], s2);
  #ifdef VOID_SPRINTF
  		s += strlen(s);
  #endif
  	    }
  	}
  	l = s - buf + 1;
  	s = (char *) XpmMalloc(l);
  	if (!s)
--- 252,285 ----
      char *s, *s2;
      char **defaults;
  
+     /* can ncolors be trusted here? */
      for (a = 0; a < ncolors; a++, colors++, dataptr++) {
  
  	defaults = (char **) colors;
+ 	if (sizeof(buf) <= cpp)
+             return(XpmNoMemory);
  	strncpy(buf, *defaults++, cpp);
  	s = buf + cpp;
  
+ 	if (sizeof(buf) <= (s-buf))
+ 	    return XpmNoMemory;
+ 
  	for (key = 1; key <= NKEYS; key++, defaults++) {
  	    if (s2 = *defaults) {
  #ifndef VOID_SPRINTF
  		s +=
  #endif
! 		     /* assume C99 compliance */
!                      snprintf(s, sizeof(buf)-(s-buf), "\t%s %s", xpmColorKeys[key - 1], s2);
  #ifdef VOID_SPRINTF
  		s += strlen(s);
  #endif
+ 		/* does s point out-of-bounds? */
+                 if (sizeof(buf) < (s-buf))
+                     return XpmNoMemory;
  	    }
  	}
+ 	/* what about using strdup()? */
  	l = s - buf + 1;
  	s = (char *) XpmMalloc(l);
  	if (!s)
***************
*** 252,259 ****
  }
  
  static void
! CreatePixels(dataptr, width, height, cpp, pixels, colors)
      char **dataptr;
      unsigned int width;
      unsigned int height;
      unsigned int cpp;
--- 291,299 ----
  }
  
  static void
! CreatePixels(dataptr, data_size, width, height, cpp, pixels, colors)
      char **dataptr;
+     unsigned int data_size;
      unsigned int width;
      unsigned int height;
      unsigned int cpp;
***************
*** 263,283 ****
      char *s;
      unsigned int x, y, h, offset;
  
      h = height - 1;
      offset = width * cpp + 1;
      for (y = 0; y < h; y++, dataptr++) {
  	s = *dataptr;
  	for (x = 0; x < width; x++, pixels++) {
! 	    strncpy(s, colors[*pixels].string, cpp);
  	    s += cpp;
  	}
  	*s = '\0';
  	*(dataptr + 1) = *dataptr + offset;
      }
      /* duplicate some code to avoid a test in the loop */
      s = *dataptr;
      for (x = 0; x < width; x++, pixels++) {
! 	strncpy(s, colors[*pixels].string, cpp);
  	s += cpp;
      }
      *s = '\0';
--- 303,340 ----
      char *s;
      unsigned int x, y, h, offset;
  
+     if(height <= 1)
+     	return;
+ 
      h = height - 1;
+ 
      offset = width * cpp + 1;
+ 
+     if(offset <= width || offset <= cpp)
+     	return;
+ 
+     /* why trust h? */
      for (y = 0; y < h; y++, dataptr++) {
  	s = *dataptr;
+ 	/* why trust width? */
  	for (x = 0; x < width; x++, pixels++) {
! 	    if(cpp > (data_size - (s - *dataptr)))
! 	    	return;
! 	    strncpy(s, colors[*pixels].string, cpp); /* why trust pixel? */
  	    s += cpp;
  	}
  	*s = '\0';
+ 	if(offset > data_size)
+ 		return;
  	*(dataptr + 1) = *dataptr + offset;
      }
      /* duplicate some code to avoid a test in the loop */
      s = *dataptr;
+     /* why trust width? */
      for (x = 0; x < width; x++, pixels++) {
! 	if(cpp > data_size - (s - *dataptr))
! 	    	return;
! 	strncpy(s, colors[*pixels].string, cpp); /* why should we trust *pixel? */
  	s += cpp;
      }
      *s = '\0';
***************
*** 310,317 ****
  }
  
  static void
! CreateExtensions(dataptr, offset, ext, num, ext_nlines)
      char **dataptr;
      unsigned int offset;
      XpmExtension *ext;
      unsigned int num;
--- 367,375 ----
  }
  
  static void
! CreateExtensions(dataptr, data_size, offset, ext, num, ext_nlines)
      char **dataptr;
+     unsigned int data_size;
      unsigned int offset;
      XpmExtension *ext;
      unsigned int num;
***************
*** 324,335 ****
      dataptr++;
      a = 0;
      for (x = 0; x < num; x++, ext++) {
! 	sprintf(*dataptr, "XPMEXT %s", ext->name);
  	a++;
  	if (a < ext_nlines)
  	    *(dataptr + 1) = *dataptr + strlen(ext->name) + 8;
  	dataptr++;
! 	b = ext->nlines;
  	for (y = 0, line = ext->lines; y < b; y++, line++) {
  	    strcpy(*dataptr, *line);
  	    a++;
--- 382,393 ----
      dataptr++;
      a = 0;
      for (x = 0; x < num; x++, ext++) {
! 	snprintf(*dataptr, data_size, "XPMEXT %s", ext->name);
  	a++;
  	if (a < ext_nlines)
  	    *(dataptr + 1) = *dataptr + strlen(ext->name) + 8;
  	dataptr++;
! 	b = ext->nlines; /* can we trust these values? */
  	for (y = 0, line = ext->lines; y < b; y++, line++) {
  	    strcpy(*dataptr, *line);
  	    a++;
diff -cr xpm-3.4k.orig/lib/Imakefile xpm-3.4k/lib/Imakefile
*** xpm-3.4k.orig/lib/Imakefile	2004-12-01 14:43:15.000000000 -0600
--- xpm-3.4k/lib/Imakefile	2004-12-01 15:49:00.000000000 -0600
***************
*** 105,117 ****
  	 CrBufFrI.c CrDatFrP.c CrPFrBuf.c RdFToI.c WrFFrI.c \
  	 CrBufFrP.c CrIFrBuf.c CrPFrDat.c RdFToP.c WrFFrP.c \
  	 CrDatFrI.c CrIFrDat.c RdFToDat.c WrFFrDat.c \
! 	 Attrib.c CrIFrP.c CrPFrI.c Image.c Info.c RdFToBuf.c WrFFrBuf.c
  
    OBJS = data.o create.o misc.o rgb.o scan.o parse.o hashtab.o \
  	 CrBufFrI.o CrDatFrP.o CrPFrBuf.o RdFToI.o WrFFrI.o \
  	 CrBufFrP.o CrIFrBuf.o CrPFrDat.o RdFToP.o WrFFrP.o \
  	 CrDatFrI.o CrIFrDat.o RdFToDat.o WrFFrDat.o \
! 	 Attrib.o CrIFrP.o CrPFrI.o Image.o Info.o RdFToBuf.o WrFFrBuf.o
  
         INCLUDES = -I.
         LINTLIBS = $(LINTXTOLL) $(LINTXLIB) 
--- 105,119 ----
  	 CrBufFrI.c CrDatFrP.c CrPFrBuf.c RdFToI.c WrFFrI.c \
  	 CrBufFrP.c CrIFrBuf.c CrPFrDat.c RdFToP.c WrFFrP.c \
  	 CrDatFrI.c CrIFrDat.c RdFToDat.c WrFFrDat.c \
! 	 Attrib.c CrIFrP.c CrPFrI.c Image.c Info.c RdFToBuf.c WrFFrBuf.c \
! 	 s_popen.c
  
    OBJS = data.o create.o misc.o rgb.o scan.o parse.o hashtab.o \
  	 CrBufFrI.o CrDatFrP.o CrPFrBuf.o RdFToI.o WrFFrI.o \
  	 CrBufFrP.o CrIFrBuf.o CrPFrDat.o RdFToP.o WrFFrP.o \
  	 CrDatFrI.o CrIFrDat.o RdFToDat.o WrFFrDat.o \
! 	 Attrib.o CrIFrP.o CrPFrI.o Image.o Info.o RdFToBuf.o WrFFrBuf.o \
! 	 s_popen.o
  
         INCLUDES = -I.
         LINTLIBS = $(LINTXTOLL) $(LINTXLIB) 
diff -cr xpm-3.4k.orig/lib/RdFToBuf.c xpm-3.4k/lib/RdFToBuf.c
*** xpm-3.4k.orig/lib/RdFToBuf.c	1998-03-19 13:51:00.000000000 -0600
--- xpm-3.4k/lib/RdFToBuf.c	2004-12-01 15:49:00.000000000 -0600
***************
*** 37,42 ****
--- 37,44 ----
   * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94
   */
  
+ /* October 2004, source code review by Thomas Biege <thomas@suse.de> */
+ 
  #include "XpmI.h"
  #include <sys/stat.h>
  #if !defined(FOR_MSW) && !defined(WIN32)
***************
*** 58,64 ****
      char *filename;
      char **buffer_return;
  {
!     int fd, fcheck, len;
      char *ptr;
      struct stat stats;
      FILE *fp;
--- 60,67 ----
      char *filename;
      char **buffer_return;
  {
!     int fd, fcheck;
!     off_t len;
      char *ptr;
      struct stat stats;
      FILE *fp;
***************
*** 82,88 ****
  	close(fd);
  	return XpmOpenFailed;
      }
!     len = (int) stats.st_size;
      ptr = (char *) XpmMalloc(len + 1);
      if (!ptr) {
  	fclose(fp);
--- 85,91 ----
  	close(fd);
  	return XpmOpenFailed;
      }
!     len = stats.st_size;
      ptr = (char *) XpmMalloc(len + 1);
      if (!ptr) {
  	fclose(fp);
diff -cr xpm-3.4k.orig/lib/RdFToI.c xpm-3.4k/lib/RdFToI.c
*** xpm-3.4k.orig/lib/RdFToI.c	1998-03-19 13:51:00.000000000 -0600
--- xpm-3.4k/lib/RdFToI.c	2004-12-01 15:49:00.000000000 -0600
***************
*** 32,37 ****
--- 32,39 ----
  *  Developed by Arnaud Le Hors                                                *
  \*****************************************************************************/
  
+ /* October 2004, source code review by Thomas Biege <thomas@suse.de> */
+ 
  #include "XpmI.h"
  #include <sys/stat.h>
  #if !defined(NO_ZPIPE) && defined(WIN32)
***************
*** 122,127 ****
--- 124,135 ----
  /*
   * open the given file to be read as an xpmData which is returned.
   */
+ #ifndef NO_ZPIPE
+ 	FILE *s_popen(char *cmd, const char *type);
+ #else
+ #	define s_popen popen
+ #endif
+ 
  static int
  OpenReadFile(filename, mdata)
      char *filename;
***************
*** 139,155 ****
  	mdata->type = XPMFILE;
      } else {
  #ifndef NO_ZPIPE
! 	int len = strlen(filename);
  	if ((len > 2) && !strcmp(".Z", filename + (len - 2))) {
  	    mdata->type = XPMPIPE;
! 	    sprintf(buf, "uncompress -c \"%s\"", filename);
! 	    if (!(mdata->stream.file = popen(buf, "r")))
  		return (XpmOpenFailed);
  
  	} else if ((len > 3) && !strcmp(".gz", filename + (len - 3))) {
  	    mdata->type = XPMPIPE;
! 	    sprintf(buf, "gunzip -qc \"%s\"", filename);
! 	    if (!(mdata->stream.file = popen(buf, "r")))
  		return (XpmOpenFailed);
  
  	} else {
--- 147,167 ----
  	mdata->type = XPMFILE;
      } else {
  #ifndef NO_ZPIPE
! 	size_t len = strlen(filename);
! 
! 	if(len == 0                        ||
! 	   filename[len-1] == '/')
! 		return(XpmOpenFailed);
  	if ((len > 2) && !strcmp(".Z", filename + (len - 2))) {
  	    mdata->type = XPMPIPE;
! 	    snprintf(buf, sizeof(buf), "uncompress -c \"%s\"", filename);
! 	    if (!(mdata->stream.file = s_popen(buf, "r")))
  		return (XpmOpenFailed);
  
  	} else if ((len > 3) && !strcmp(".gz", filename + (len - 3))) {
  	    mdata->type = XPMPIPE;
! 	    snprintf(buf, sizeof(buf), "gunzip -qc \"%s\"", filename);
! 	    if (!(mdata->stream.file = s_popen(buf, "r")))
  		return (XpmOpenFailed);
  
  	} else {
***************
*** 157,175 ****
  	    if (!(compressfile = (char *) XpmMalloc(len + 4)))
  		return (XpmNoMemory);
  
! 	    sprintf(compressfile, "%s.Z", filename);
  	    if (!stat(compressfile, &status)) {
! 		sprintf(buf, "uncompress -c \"%s\"", compressfile);
! 		if (!(mdata->stream.file = popen(buf, "r"))) {
  		    XpmFree(compressfile);
  		    return (XpmOpenFailed);
  		}
  		mdata->type = XPMPIPE;
  	    } else {
! 		sprintf(compressfile, "%s.gz", filename);
  		if (!stat(compressfile, &status)) {
! 		    sprintf(buf, "gunzip -c \"%s\"", compressfile);
! 		    if (!(mdata->stream.file = popen(buf, "r"))) {
  			XpmFree(compressfile);
  			return (XpmOpenFailed);
  		    }
--- 169,187 ----
  	    if (!(compressfile = (char *) XpmMalloc(len + 4)))
  		return (XpmNoMemory);
  
! 	    snprintf(compressfile, len+4, "%s.Z", filename);
  	    if (!stat(compressfile, &status)) {
! 		snprintf(buf, sizeof(buf), "uncompress -c \"%s\"", compressfile);
! 		if (!(mdata->stream.file = s_popen(buf, "r"))) {
  		    XpmFree(compressfile);
  		    return (XpmOpenFailed);
  		}
  		mdata->type = XPMPIPE;
  	    } else {
! 		snprintf(compressfile, len+4, "%s.gz", filename);
  		if (!stat(compressfile, &status)) {
! 		    snprintf(buf, sizeof(buf), "gunzip -c \"%s\"", compressfile);
! 		    if (!(mdata->stream.file = s_popen(buf, "r"))) {
  			XpmFree(compressfile);
  			return (XpmOpenFailed);
  		    }
***************
*** 215,221 ****
  	break;
  #ifndef NO_ZPIPE
      case XPMPIPE:
! 	pclose(mdata->stream.file);
  	break;
  #endif
      }
--- 227,233 ----
  	break;
  #ifndef NO_ZPIPE
      case XPMPIPE:
! 	fclose(mdata->stream.file);
  	break;
  #endif
      }
diff -cr xpm-3.4k.orig/lib/WrFFrBuf.c xpm-3.4k/lib/WrFFrBuf.c
*** xpm-3.4k.orig/lib/WrFFrBuf.c	1998-03-19 13:51:00.000000000 -0600
--- xpm-3.4k/lib/WrFFrBuf.c	2004-12-01 15:49:00.000000000 -0600
***************
*** 32,37 ****
--- 32,39 ----
  *  Developed by Arnaud Le Hors                                                *
  \*****************************************************************************/
  
+ /* October 2004, source code review by Thomas Biege <thomas@suse.de> */
+ 
  #include "XpmI.h"
  
  int
***************
*** 49,55 ****
      fcheck = fwrite(buffer, len, 1, fp);
      fclose(fp);
      if (fcheck != 1)
! 	return XpmOpenFailed;
  
      return XpmSuccess;
  }
--- 51,57 ----
      fcheck = fwrite(buffer, len, 1, fp);
      fclose(fp);
      if (fcheck != 1)
! 	return XpmOpenFailed; /* maybe use a better return value */
  
      return XpmSuccess;
  }
diff -cr xpm-3.4k.orig/lib/WrFFrI.c xpm-3.4k/lib/WrFFrI.c
*** xpm-3.4k.orig/lib/WrFFrI.c	2004-12-01 14:43:15.000000000 -0600
--- xpm-3.4k/lib/WrFFrI.c	2004-12-01 15:49:00.000000000 -0600
***************
*** 37,42 ****
--- 37,44 ----
   * Lorens Younes (d93-hyo@nada.kth.se) 4/96
   */
  
+ /* October 2004, source code review by Thomas Biege <thomas@suse.de> */
+ 
  #include "XpmI.h"
  #if !defined(NO_ZPIPE) && defined(WIN32)
  # define popen _popen
***************
*** 97,103 ****
      XpmInfo *info;
  {
      xpmData mdata;
!     char *name, *dot, *s, new_name[BUFSIZ];
      int ErrorStatus;
  
      /* open file to write */
--- 99,105 ----
      XpmInfo *info;
  {
      xpmData mdata;
!     char *name, *dot, *s, new_name[BUFSIZ] = {0};
      int ErrorStatus;
  
      /* open file to write */
***************
*** 119,126 ****
  	    name++;
  #endif
  	/* let's try to make a valid C syntax name */
! 	if (dot = index(name, '.')) {
! 	    strcpy(new_name, name);
  	    /* change '.' to '_' */
  	    name = s = new_name;
  	    while (dot = index(s, '.')) {
--- 121,129 ----
  	    name++;
  #endif
  	/* let's try to make a valid C syntax name */
! 	if (index(name, '.')) {
! 	    strncpy(new_name, name, sizeof(new_name));
!             new_name[sizeof(new_name)-1] = 0;
  	    /* change '.' to '_' */
  	    name = s = new_name;
  	    while (dot = index(s, '.')) {
***************
*** 130,136 ****
  	}
  	if (dot = index(name, '-')) {
  	    if (name != new_name) {
! 		strcpy(new_name, name);
  		name = new_name;
  	    }
  	    /* change '-' to '_' */
--- 133,140 ----
  	}
  	if (dot = index(name, '-')) {
  	    if (name != new_name) {
! 		strncpy(new_name, name, sizeof(new_name));
! 		new_name[sizeof(new_name)-1] = 0;
  		name = new_name;
  	    }
  	    /* change '-' to '_' */
***************
*** 247,253 ****
      unsigned int x, y, h;
  
      h = height - 1;
!     if (cpp != 0 && width >= (SIZE_MAX - 3)/cpp) 
  	return XpmNoMemory;    
      p = buf = (char *) XpmMalloc(width * cpp + 3);
      if (!buf)
--- 251,257 ----
      unsigned int x, y, h;
  
      h = height - 1;
!     if (cpp != 0 && width >= (UINT_MAX - 3)/cpp)
  	return XpmNoMemory;    
      p = buf = (char *) XpmMalloc(width * cpp + 3);
      if (!buf)
***************
*** 299,304 ****
--- 303,313 ----
  /*
   * open the given file to be written as an xpmData which is returned
   */
+ #ifndef NO_ZPIPE
+ 	FILE *s_popen(char *cmd, const char *type);
+ #else
+ #	define s_popen popen
+ #endif
  static int
  OpenWriteFile(filename, mdata)
      char *filename;
***************
*** 314,329 ****
  	mdata->type = XPMFILE;
      } else {
  #ifndef NO_ZPIPE
! 	int len = strlen(filename);
  	if (len > 2 && !strcmp(".Z", filename + (len - 2))) {
! 	    sprintf(buf, "compress > \"%s\"", filename);
! 	    if (!(mdata->stream.file = popen(buf, "w")))
  		return (XpmOpenFailed);
  
  	    mdata->type = XPMPIPE;
  	} else if (len > 3 && !strcmp(".gz", filename + (len - 3))) {
! 	    sprintf(buf, "gzip -q > \"%s\"", filename);
! 	    if (!(mdata->stream.file = popen(buf, "w")))
  		return (XpmOpenFailed);
  
  	    mdata->type = XPMPIPE;
--- 323,345 ----
  	mdata->type = XPMFILE;
      } else {
  #ifndef NO_ZPIPE
! 	size_t len = strlen(filename);
! 
! 	if(len == 0                        ||
! 	   filename[0] == '/'              ||
! 	   strstr(filename, "../") != NULL ||
! 	   filename[len-1] == '/')
! 		return(XpmOpenFailed);
! 
  	if (len > 2 && !strcmp(".Z", filename + (len - 2))) {
! 	    snprintf(buf, sizeof(buf), "compress > \"%s\"", filename);
! 	    if (!(mdata->stream.file = s_popen(buf, "w")))
  		return (XpmOpenFailed);
  
  	    mdata->type = XPMPIPE;
  	} else if (len > 3 && !strcmp(".gz", filename + (len - 3))) {
! 	    snprintf(buf, sizeof(buf), "gzip -q > \"%s\"", filename);
! 	    if (!(mdata->stream.file = s_popen(buf, "w")))
  		return (XpmOpenFailed);
  
  	    mdata->type = XPMPIPE;
***************
*** 354,360 ****
  	break;
  #ifndef NO_ZPIPE
      case XPMPIPE:
! 	pclose(mdata->stream.file);
  	break;
  #endif
      }
--- 370,376 ----
  	break;
  #ifndef NO_ZPIPE
      case XPMPIPE:
! 	fclose(mdata->stream.file);
  	break;
  #endif
      }
diff -cr xpm-3.4k.orig/lib/XpmI.h xpm-3.4k/lib/XpmI.h
*** xpm-3.4k.orig/lib/XpmI.h	2004-12-01 14:43:15.000000000 -0600
--- xpm-3.4k/lib/XpmI.h	2004-12-01 15:49:00.000000000 -0600
***************
*** 48,55 ****
--- 48,57 ----
   * lets try to solve include files
   */
  
+ #include <sys/types.h>
  #include <stdio.h>
  #include <stdlib.h>
+ #include <limits.h>
  /* stdio.h doesn't declare popen on a Sequent DYNIX OS */
  #ifdef sequent
  extern FILE *popen();
diff -cr xpm-3.4k.orig/lib/create.c xpm-3.4k/lib/create.c
*** xpm-3.4k.orig/lib/create.c	2004-12-01 14:43:15.000000000 -0600
--- xpm-3.4k/lib/create.c	2004-12-01 15:49:00.000000000 -0600
***************
*** 44,49 ****
--- 44,51 ----
   * Lorens Younes (d93-hyo@nada.kth.se) 4/96
   */
  
+ /* October 2004, source code review by Thomas Biege <thomas@suse.de> */
+ 
  #include "XpmI.h"
  #include <ctype.h>
  
***************
*** 584,590 ****
  	     */
  	} else {
  #endif
! 	    int i;
  
  #ifndef AMIGA
  	    ncols = visual->map_entries;
--- 586,592 ----
  	     */
  	} else {
  #endif
! 	    unsigned int i;
  
  #ifndef AMIGA
  	    ncols = visual->map_entries;
***************
*** 744,755 ****
  
  
  /* function call in case of error */
  #undef RETURN
  #define RETURN(status) \
  { \
        ErrorStatus = status; \
        goto error; \
! }
  
  int
  XpmCreateImageFromXpmImage(display, image,
--- 746,759 ----
  
  
  /* function call in case of error */
+ 
  #undef RETURN
  #define RETURN(status) \
+ do \
  { \
        ErrorStatus = status; \
        goto error; \
! } while(0)
  
  int
  XpmCreateImageFromXpmImage(display, image,
***************
*** 820,826 ****
  
      ErrorStatus = XpmSuccess;
  
!     if (image->ncolors >= SIZE_MAX / sizeof(Pixel)) 
  	return (XpmNoMemory);
  
      /* malloc pixels index tables */
--- 824,830 ----
  
      ErrorStatus = XpmSuccess;
  
!     if (image->ncolors >= UINT_MAX / sizeof(Pixel)) 
  	return (XpmNoMemory);
  
      /* malloc pixels index tables */
***************
*** 995,1003 ****
  	return (XpmNoMemory);
  
  #if !defined(FOR_MSW) && !defined(AMIGA)
!     if (height != 0 && (*image_return)->bytes_per_line >= SIZE_MAX / height)
  	return XpmNoMemory;
      /* now that bytes_per_line must have been set properly alloc data */
      (*image_return)->data =
  	(char *) XpmMalloc((*image_return)->bytes_per_line * height);
  
--- 999,1011 ----
  	return (XpmNoMemory);
  
  #if !defined(FOR_MSW) && !defined(AMIGA)
!     if (height != 0 && (*image_return)->bytes_per_line >= INT_MAX / height) {
! 	XDestroyImage(*image_return);
  	return XpmNoMemory;
+     }
      /* now that bytes_per_line must have been set properly alloc data */
+     if((*image_return)->bytes_per_line == 0 ||  height == 0)
+     	return XpmNoMemory;
      (*image_return)->data =
  	(char *) XpmMalloc((*image_return)->bytes_per_line * height);
  
***************
*** 1026,1032 ****
  LFUNC(_putbits, void, (register char *src, int dstoffset,
  		       register int numbits, register char *dst));
  
! LFUNC(_XReverse_Bytes, int, (register unsigned char *bpt, register int nb));
  
  static unsigned char Const _reverse_byte[0x100] = {
      0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
--- 1034,1040 ----
  LFUNC(_putbits, void, (register char *src, int dstoffset,
  		       register int numbits, register char *dst));
  
! LFUNC(_XReverse_Bytes, int, (register unsigned char *bpt, register unsigned int nb));
  
  static unsigned char Const _reverse_byte[0x100] = {
      0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
***************
*** 1066,1077 ****
  static int
  _XReverse_Bytes(bpt, nb)
      register unsigned char *bpt;
!     register int nb;
  {
      do {
  	*bpt = _reverse_byte[*bpt];
  	bpt++;
!     } while (--nb > 0);
      return 0;
  }
  
--- 1074,1085 ----
  static int
  _XReverse_Bytes(bpt, nb)
      register unsigned char *bpt;
!     register unsigned int nb;
  {
      do {
  	*bpt = _reverse_byte[*bpt];
  	bpt++;
!     } while (--nb > 0); /* is nb user-controled? */
      return 0;
  }
  
***************
*** 1210,1216 ****
      register char *src;
      register char *dst;
      register unsigned int *iptr;
!     register int x, y, i;
      register char *data;
      Pixel pixel, px;
      int nbytes, depth, ibu, ibpp;
--- 1218,1224 ----
      register char *src;
      register char *dst;
      register unsigned int *iptr;
!     register unsigned int x, y, i;
      register char *data;
      Pixel pixel, px;
      int nbytes, depth, ibu, ibpp;
***************
*** 1220,1227 ****
      depth = image->depth;
      if (depth == 1) {
  	ibu = image->bitmap_unit;
! 	for (y = 0; y < height; y++)
! 	    for (x = 0; x < width; x++, iptr++) {
  		pixel = pixels[*iptr];
  		for (i = 0, px = pixel; i < sizeof(unsigned long);
  		     i++, px >>= 8)
--- 1228,1235 ----
      depth = image->depth;
      if (depth == 1) {
  	ibu = image->bitmap_unit;
! 	for (y = 0; y < height; y++) /* how can we trust height */
! 	    for (x = 0; x < width; x++, iptr++) { /* how can we trust width */
  		pixel = pixels[*iptr];
  		for (i = 0, px = pixel; i < sizeof(unsigned long);
  		     i++, px >>= 8)
***************
*** 1296,1307 ****
  {
      unsigned char *data;
      unsigned int *iptr;
!     int y;
      Pixel pixel;
  
  #ifdef WITHOUT_SPEEDUPS
  
!     int x;
      unsigned char *addr;
  
      data = (unsigned char *) image->data;
--- 1304,1315 ----
  {
      unsigned char *data;
      unsigned int *iptr;
!     unsigned int y;
      Pixel pixel;
  
  #ifdef WITHOUT_SPEEDUPS
  
!     unsigned int x;
      unsigned char *addr;
  
      data = (unsigned char *) image->data;
***************
*** 1338,1344 ****
  
  #else  /* WITHOUT_SPEEDUPS */
  
!     int bpl = image->bytes_per_line;
      unsigned char *data_ptr, *max_data;
  
      data = (unsigned char *) image->data;
--- 1346,1352 ----
  
  #else  /* WITHOUT_SPEEDUPS */
  
!     unsigned int bpl = image->bytes_per_line;
      unsigned char *data_ptr, *max_data;
  
      data = (unsigned char *) image->data;
***************
*** 1406,1416 ****
  {
      unsigned char *data;
      unsigned int *iptr;
!     int y;
  
  #ifdef WITHOUT_SPEEDUPS
  
!     int x;
      unsigned char *addr;
  
      data = (unsigned char *) image->data;
--- 1414,1424 ----
  {
      unsigned char *data;
      unsigned int *iptr;
!     unsigned int y;
  
  #ifdef WITHOUT_SPEEDUPS
  
!     unsigned int x;
      unsigned char *addr;
  
      data = (unsigned char *) image->data;
***************
*** 1434,1440 ****
  
      Pixel pixel;
  
!     int bpl = image->bytes_per_line;
      unsigned char *data_ptr, *max_data;
  
      data = (unsigned char *) image->data;
--- 1442,1448 ----
  
      Pixel pixel;
  
!     unsigned int bpl = image->bytes_per_line;
      unsigned char *data_ptr, *max_data;
  
      data = (unsigned char *) image->data;
***************
*** 1487,1497 ****
  {
      char *data;
      unsigned int *iptr;
!     int y;
  
  #ifdef WITHOUT_SPEEDUPS
  
!     int x;
  
      data = image->data;
      iptr = pixelindex;
--- 1495,1505 ----
  {
      char *data;
      unsigned int *iptr;
!     unsigned int y;
  
  #ifdef WITHOUT_SPEEDUPS
  
!     unsigned int x;
  
      data = image->data;
      iptr = pixelindex;
***************
*** 1501,1507 ****
  
  #else  /* WITHOUT_SPEEDUPS */
  
!     int bpl = image->bytes_per_line;
      char *data_ptr, *max_data;
  
      data = image->data;
--- 1509,1515 ----
  
  #else  /* WITHOUT_SPEEDUPS */
  
!     unsigned int bpl = image->bytes_per_line;
      char *data_ptr, *max_data;
  
      data = image->data;
***************
*** 1536,1547 ****
  	PutImagePixels(image, width, height, pixelindex, pixels);
      else {
  	unsigned int *iptr;
! 	int y;
  	char *data;
  
  #ifdef WITHOUT_SPEEDUPS
  
! 	int x;
  
  	data = image->data;
  	iptr = pixelindex;
--- 1544,1555 ----
  	PutImagePixels(image, width, height, pixelindex, pixels);
      else {
  	unsigned int *iptr;
! 	unsigned int y;
  	char *data;
  
  #ifdef WITHOUT_SPEEDUPS
  
! 	unsigned int x;
  
  	data = image->data;
  	iptr = pixelindex;
***************
*** 1765,1770 ****
--- 1773,1781 ----
      Pixel px;
      int nbytes;
  
+     if(x < 0 || y < 0)
+     	return 0;
+ 
      for (i=0, px=pixel; i<sizeof(unsigned long); i++, px>>=8)
  	((unsigned char *)&pixel)[i] = px;
      src = &ximage->data[XYINDEX(x, y, ximage)];
***************
*** 1796,1802 ****
      register int i;
      register char *data;
      Pixel px;
!     int nbytes, ibpp;
  
      ibpp = ximage->bits_per_pixel;
      if (ximage->depth == 4)
--- 1807,1816 ----
      register int i;
      register char *data;
      Pixel px;
!     unsigned int nbytes, ibpp;
! 
!     if(x < 0 || y < 0)
!     	return 0;
  
      ibpp = ximage->bits_per_pixel;
      if (ximage->depth == 4)
***************
*** 1829,1834 ****
--- 1843,1851 ----
  {
      unsigned char *addr;
  
+     if(x < 0 || y < 0)
+     	return 0;
+ 
      addr = &((unsigned char *)ximage->data) [ZINDEX32(x, y, ximage)];
      *((unsigned long *)addr) = pixel;
      return 1;
***************
*** 1843,1848 ****
--- 1860,1868 ----
  {
      unsigned char *addr;
  
+     if(x < 0 || y < 0)
+     	return 0;
+ 
      addr = &((unsigned char *)ximage->data) [ZINDEX32(x, y, ximage)];
      addr[0] = pixel >> 24;
      addr[1] = pixel >> 16;
***************
*** 1860,1865 ****
--- 1880,1888 ----
  {
      unsigned char *addr;
  
+     if(x < 0 || y < 0)
+     	return 0;
+ 
      addr = &((unsigned char *)ximage->data) [ZINDEX32(x, y, ximage)];
      addr[3] = pixel >> 24;
      addr[2] = pixel >> 16;
***************
*** 1877,1882 ****
--- 1900,1908 ----
  {
      unsigned char *addr;
      
+     if(x < 0 || y < 0)
+     	return 0;
+ 
      addr = &((unsigned char *)ximage->data) [ZINDEX16(x, y, ximage)];
      addr[0] = pixel >> 8;
      addr[1] = pixel;
***************
*** 1892,1897 ****
--- 1918,1926 ----
  {
      unsigned char *addr;
      
+     if(x < 0 || y < 0)
+     	return 0;
+ 
      addr = &((unsigned char *)ximage->data) [ZINDEX16(x, y, ximage)];
      addr[1] = pixel >> 8;
      addr[0] = pixel;
***************
*** 1905,1910 ****
--- 1934,1942 ----
      int y;
      unsigned long pixel;
  {
+     if(x < 0 || y < 0)
+     	return 0;
+ 
      ximage->data[ZINDEX8(x, y, ximage)] = pixel;
      return 1;
  }
***************
*** 1916,1921 ****
--- 1948,1956 ----
      int y;
      unsigned long pixel;
  {
+     if(x < 0 || y < 0)
+     	return 0;
+ 
      if (pixel & 1)
  	ximage->data[ZINDEX1(x, y, ximage)] |= 0x80 >> (x & 7);
      else
***************
*** 1930,1935 ****
--- 1965,1973 ----
      int y;
      unsigned long pixel;
  {
+     if(x < 0 || y < 0)
+     	return 0;
+ 
      if (pixel & 1)
  	ximage->data[ZINDEX1(x, y, ximage)] |= 1 << (x & 7);
      else
***************
*** 2069,2076 ****
  	xpmGetCmt(data, &colors_cmt);
  
      /* malloc pixels index tables */
!     if (ncolors >= SIZE_MAX / sizeof(Pixel)) 
! 	return XpmNoMemory;
  
      image_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * ncolors);
      if (!image_pixels)
--- 2107,2114 ----
  	xpmGetCmt(data, &colors_cmt);
  
      /* malloc pixels index tables */
!     if (ncolors >= UINT_MAX / sizeof(Pixel)) 
! 	RETURN(XpmNoMemory);
  
      image_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * ncolors);
      if (!image_pixels)
***************
*** 2182,2188 ****
       * free the hastable
       */
      if (ErrorStatus != XpmSuccess)
! 	RETURN(ErrorStatus)
      else if (USE_HASHTABLE)
  	xpmHashTableFree(&hashtable);
  
--- 2220,2226 ----
       * free the hastable
       */
      if (ErrorStatus != XpmSuccess)
! 	RETURN(ErrorStatus);
      else if (USE_HASHTABLE)
  	xpmHashTableFree(&hashtable);
  
***************
*** 2374,2384 ****
  
  	    /* array of pointers malloced by need */
  	    unsigned short *cidx[256];
! 	    int char1;
  
  	    bzero((char *)cidx, 256 * sizeof(unsigned short *)); /* init */
  	    for (a = 0; a < ncolors; a++) {
! 		char1 = colorTable[a].string[0];
  		if (cidx[char1] == NULL) { /* get new memory */
  		    cidx[char1] = (unsigned short *)
  			XpmCalloc(256, sizeof(unsigned short));
--- 2412,2422 ----
  
  	    /* array of pointers malloced by need */
  	    unsigned short *cidx[256];
! 	    unsigned int char1;
  
  	    bzero((char *)cidx, 256 * sizeof(unsigned short *)); /* init */
  	    for (a = 0; a < ncolors; a++) {
! 		char1 = (unsigned char) colorTable[a].string[0];
  		if (cidx[char1] == NULL) { /* get new memory */
  		    cidx[char1] = (unsigned short *)
  			XpmCalloc(256, sizeof(unsigned short));
diff -cr xpm-3.4k.orig/lib/data.c xpm-3.4k/lib/data.c
*** xpm-3.4k.orig/lib/data.c	2004-12-01 14:43:15.000000000 -0600
--- xpm-3.4k/lib/data.c	2004-12-01 15:49:00.000000000 -0600
***************
*** 32,37 ****
--- 32,39 ----
  *  Developed by Arnaud Le Hors                                                *
  \*****************************************************************************/
  
+ /* October 2004, source code review by Thomas Biege <thomas@suse.de> */
+ 
  #ifndef CXPMPROG
  /* Official version number */
  static char *RCS_Version = "$XpmVersion: 3.4k $";
***************
*** 261,267 ****
  	}
  	Ungetc(data, c, file);
      }
!     return (n);
  }
  
  /*
--- 263,269 ----
  	}
  	Ungetc(data, c, file);
      }
!     return (n); /* this returns bytes read + 1 */
  }
  
  /*
***************
*** 374,381 ****
  {
      if (!data->type)
  	*cmt = NULL;
!     else if (data->CommentLength != 0 && data->CommentLength < SIZE_MAX - 1) {
! 	*cmt = (char *) XpmMalloc(data->CommentLength + 1);
  	strncpy(*cmt, data->Comment, data->CommentLength);
  	(*cmt)[data->CommentLength] = '\0';
  	data->CommentLength = 0;
--- 376,384 ----
  {
      if (!data->type)
  	*cmt = NULL;
!     else if (data->CommentLength != 0 && data->CommentLength < UINT_MAX - 1) {
! 	if( (*cmt = (char *) XpmMalloc(data->CommentLength + 1)) == NULL)
! 		return XpmNoMemory;
  	strncpy(*cmt, data->Comment, data->CommentLength);
  	(*cmt)[data->CommentLength] = '\0';
  	data->CommentLength = 0;
***************
*** 403,409 ****
  xpmParseHeader(data)
      xpmData *data;
  {
!     char buf[BUFSIZ];
      int l, n = 0;
  
      if (data->type) {
--- 406,412 ----
  xpmParseHeader(data)
      xpmData *data;
  {
!     char buf[BUFSIZ+1] = {0};
      int l, n = 0;
  
      if (data->type) {
diff -cr xpm-3.4k.orig/lib/hashtab.c xpm-3.4k/lib/hashtab.c
*** xpm-3.4k.orig/lib/hashtab.c	2004-12-01 14:43:15.000000000 -0600
--- xpm-3.4k/lib/hashtab.c	2004-12-01 15:49:00.000000000 -0600
***************
*** 138,150 ****
      unsigned int size = table->size;
      xpmHashAtom *t, *p;
      int i;
!     int oldSize = size;
  
      t = atomTable;
      HASH_TABLE_GROWS
  	table->size = size;
      table->limit = size / 3;
!     if (size >= SIZE_MAX / sizeof(*atomTable)) 
  	return (XpmNoMemory);
      atomTable = (xpmHashAtom *) XpmMalloc(size * sizeof(*atomTable));
      if (!atomTable)
--- 138,150 ----
      unsigned int size = table->size;
      xpmHashAtom *t, *p;
      int i;
!     unsigned int oldSize = size;
  
      t = atomTable;
      HASH_TABLE_GROWS
  	table->size = size;
      table->limit = size / 3;
!     if (size >= UINT_MAX / sizeof(*atomTable)) 
  	return (XpmNoMemory);
      atomTable = (xpmHashAtom *) XpmMalloc(size * sizeof(*atomTable));
      if (!atomTable)
***************
*** 206,212 ****
      table->size = INITIAL_HASH_SIZE;
      table->limit = table->size / 3;
      table->used = 0;
!     if (table->size >= SIZE_MAX / sizeof(*atomTable))
  	return (XpmNoMemory);
      atomTable = (xpmHashAtom *) XpmMalloc(table->size * sizeof(*atomTable));
      if (!atomTable)
--- 206,212 ----
      table->size = INITIAL_HASH_SIZE;
      table->limit = table->size / 3;
      table->used = 0;
!     if (table->size >= UINT_MAX / sizeof(*atomTable))
  	return (XpmNoMemory);
      atomTable = (xpmHashAtom *) XpmMalloc(table->size * sizeof(*atomTable));
      if (!atomTable)
diff -cr xpm-3.4k.orig/lib/misc.c xpm-3.4k/lib/misc.c
*** xpm-3.4k.orig/lib/misc.c	1998-03-19 13:51:00.000000000 -0600
--- xpm-3.4k/lib/misc.c	2004-12-01 15:49:00.000000000 -0600
***************
*** 44,50 ****
      char *s1;
  {
      char *s2;
!     int l = strlen(s1) + 1;
  
      if (s2 = (char *) XpmMalloc(l))
  	strcpy(s2, s1);
--- 44,50 ----
      char *s1;
  {
      char *s2;
!     size_t l = strlen(s1) + 1;
  
      if (s2 = (char *) XpmMalloc(l))
  	strcpy(s2, s1);
diff -cr xpm-3.4k.orig/lib/parse.c xpm-3.4k/lib/parse.c
*** xpm-3.4k.orig/lib/parse.c	2004-12-01 14:43:15.000000000 -0600
--- xpm-3.4k/lib/parse.c	2004-12-01 15:49:00.000000000 -0600
***************
*** 39,63 ****
   * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94
   */
  
  #include "XpmI.h"
  #include <ctype.h>
  
  #ifdef HAS_STRLCAT
! # define STRLCAT(dst, src, dstsize) { \
!   	if (strlcat(dst, src, dstsize) >= (dstsize)) \
! 	    return (XpmFileInvalid); }
! # define STRLCPY(dst, src, dstsize) { \
!   	if (strlcpy(dst, src, dstsize) >= (dstsize)) \
! 	    return (XpmFileInvalid); }
  #else
! # define STRLCAT(dst, src, dstsize) { \
! 	if ((strlen(dst) + strlen(src)) < (dstsize)) \
!  	    strcat(dst, src); \
! 	else return (XpmFileInvalid); }
! # define STRLCPY(dst, src, dstsize) { \
! 	if (strlen(src) < (dstsize)) \
!  	    strcpy(dst, src); \
! 	else return (XpmFileInvalid); }
  #endif
  
  LFUNC(ParsePixels, int, (xpmData *data, unsigned int width,
--- 39,66 ----
   * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94
   */
  
+ /* October 2004, source code review by Thomas Biege <thomas@suse.de> */
+ 
  #include "XpmI.h"
  #include <ctype.h>
+ #include <string.h>
  
  #ifdef HAS_STRLCAT
! # define STRLCAT(dst, src, dstsize) do { \
!       if (strlcat(dst, src, dstsize) >= (dstsize)) \
!           return (XpmFileInvalid); } while(0)
! # define STRLCPY(dst, src, dstsize) do { \
!       if (strlcpy(dst, src, dstsize) >= (dstsize)) \
!           return (XpmFileInvalid); } while(0)
  #else
! # define STRLCAT(dst, src, dstsize) do { \
!       if ((strlen(dst) + strlen(src)) < (dstsize)) \
!           strcat(dst, src); \
!       else return (XpmFileInvalid); } while(0)
! # define STRLCPY(dst, src, dstsize) do { \
!       if (strlen(src) < (dstsize)) \
!           strcpy(dst, src); \
!       else return (XpmFileInvalid); } while(0)
  #endif
  
  LFUNC(ParsePixels, int, (xpmData *data, unsigned int width,
***************
*** 202,208 ****
      char **defaults;
      int ErrorStatus;
  
!     if (ncolors >= SIZE_MAX / sizeof(XpmColor))
  	return (XpmNoMemory);
      colorTable = (XpmColor *) XpmCalloc(ncolors, sizeof(XpmColor));
      if (!colorTable)
--- 205,211 ----
      char **defaults;
      int ErrorStatus;
  
!     if (ncolors >= UINT_MAX / sizeof(XpmColor))
  	return (XpmNoMemory);
      colorTable = (XpmColor *) XpmCalloc(ncolors, sizeof(XpmColor));
      if (!colorTable)
***************
*** 215,221 ****
  	    /*
  	     * read pixel value
  	     */
! 	    if (cpp >= SIZE_MAX - 1) {
  		xpmFreeColorTable(colorTable, ncolors);
  		return (XpmNoMemory);
  	    }
--- 218,224 ----
  	    /*
  	     * read pixel value
  	     */
! 	    if (cpp >= UINT_MAX - 1) {
  		xpmFreeColorTable(colorTable, ncolors);
  		return (XpmNoMemory);
  	    }
***************
*** 274,282 ****
  			return (XpmFileInvalid);
  		    }
  		    if (!lastwaskey)
! 			STRLCAT(curbuf, " ", sizeof(curbuf)); /* append space */
  		    buf[l] = '\0';
! 		    STRLCAT(curbuf, buf, sizeof(curbuf));/* append buf */
  		    lastwaskey = 0;
  		}
  	    }
--- 277,285 ----
  			return (XpmFileInvalid);
  		    }
  		    if (!lastwaskey)
! 			STRLCAT(curbuf, " ", sizeof(curbuf));/* append space */
  		    buf[l] = '\0';
! 		    STRLCAT(curbuf, buf, sizeof(curbuf)); /* append buf */
  		    lastwaskey = 0;
  		}
  	    }
***************
*** 284,290 ****
  		xpmFreeColorTable(colorTable, ncolors);
  		return (XpmFileInvalid);
  	    }
! 	    len = strlen(curbuf) + 1;
  	    s = defaults[curkey] = (char *) XpmMalloc(len);
  	    if (!s) {
  		xpmFreeColorTable(colorTable, ncolors);
--- 287,293 ----
  		xpmFreeColorTable(colorTable, ncolors);
  		return (XpmFileInvalid);
  	    }
! 	    len = strlen(curbuf) + 1; /* integer overflow just theoretically possible */
  	    s = defaults[curkey] = (char *) XpmMalloc(len);
  	    if (!s) {
  		xpmFreeColorTable(colorTable, ncolors);
***************
*** 303,309 ****
  	    /*
  	     * read pixel value
  	     */
! 	    if (cpp >= SIZE_MAX - 1) {
  		xpmFreeColorTable(colorTable, ncolors);
  		return (XpmNoMemory);
  	    }
--- 306,312 ----
  	    /*
  	     * read pixel value
  	     */
! 	    if (cpp >= UINT_MAX - 1) {
  		xpmFreeColorTable(colorTable, ncolors);
  		return (XpmNoMemory);
  	    }
***************
*** 348,354 ****
  	    memcpy(s, curbuf, len);
  	    color->c_color = s;
  	    *curbuf = '\0';		/* reset curbuf */
! 	    if (a < ncolors - 1)
  		xpmNextString(data);	/* get to the next string */
  	}
      }
--- 351,357 ----
  	    memcpy(s, curbuf, len);
  	    color->c_color = s;
  	    *curbuf = '\0';		/* reset curbuf */
! 	    if (a < ncolors - 1)	/* can we trust ncolors -> leave data's bounds */
  		xpmNextString(data);	/* get to the next string */
  	}
      }
***************
*** 367,377 ****
      xpmHashTable *hashtable;
      unsigned int **pixels;
  {
!     unsigned int *iptr, *iptr2;
      unsigned int a, x, y;
  
!     if ((height > 0 && width >= SIZE_MAX / height) ||
! 	width * height >= SIZE_MAX / sizeof(unsigned int)) 
  	return XpmNoMemory;
  #ifndef FOR_MSW
      iptr2 = (unsigned int *) XpmMalloc(sizeof(unsigned int) * width * height);
--- 370,380 ----
      xpmHashTable *hashtable;
      unsigned int **pixels;
  {
!     unsigned int *iptr, *iptr2 = NULL; /* found by Egbert Eich */
      unsigned int a, x, y;
  
!     if ((height > 0 && width >= UINT_MAX / height) ||
! 	width * height >= UINT_MAX / sizeof(unsigned int)) 
  	return XpmNoMemory;
  #ifndef FOR_MSW
      iptr2 = (unsigned int *) XpmMalloc(sizeof(unsigned int) * width * height);
***************
*** 396,403 ****
  	{
  	    unsigned short colidx[256];
  
! 	    if (ncolors > 256)
  		return (XpmFileInvalid);
  
  	    bzero((char *)colidx, 256 * sizeof(short));
  	    for (a = 0; a < ncolors; a++)
--- 399,408 ----
  	{
  	    unsigned short colidx[256];
  
! 	    if (ncolors > 256) {
! 		XpmFree(iptr2); /* found by Egbert Eich */
  		return (XpmFileInvalid);
+ 	    }
  
  	    bzero((char *)colidx, 256 * sizeof(short));
  	    for (a = 0; a < ncolors; a++)
***************
*** 424,439 ****
  	{
  
  /* free all allocated pointers at all exits */
! #define FREE_CIDX {int f; for (f = 0; f < 256; f++) \
! if (cidx[f]) XpmFree(cidx[f]);}
  
  	    /* array of pointers malloced by need */
  	    unsigned short *cidx[256];
! 	    int char1;
  
  	    bzero((char *)cidx, 256 * sizeof(unsigned short *)); /* init */
  	    for (a = 0; a < ncolors; a++) {
! 		char1 = colorTable[a].string[0];
  		if (cidx[char1] == NULL) { /* get new memory */
  		    cidx[char1] = (unsigned short *)
  			XpmCalloc(256, sizeof(unsigned short));
--- 429,448 ----
  	{
  
  /* free all allocated pointers at all exits */
! #define FREE_CIDX \
! do \
! { \
! 	int f; for (f = 0; f < 256; f++) \
! 	if (cidx[f]) XpmFree(cidx[f]); \
! } while(0)
  
  	    /* array of pointers malloced by need */
  	    unsigned short *cidx[256];
! 	    unsigned int char1;
  
  	    bzero((char *)cidx, 256 * sizeof(unsigned short *)); /* init */
  	    for (a = 0; a < ncolors; a++) {
! 		char1 = (unsigned char) colorTable[a].string[0];
  		if (cidx[char1] == NULL) { /* get new memory */
  		    cidx[char1] = (unsigned short *)
  			XpmCalloc(256, sizeof(unsigned short));
***************
*** 477,484 ****
  	    char *s;
  	    char buf[BUFSIZ];
  
! 	    if (cpp >= sizeof(buf))
  		return (XpmFileInvalid);
  
  	    buf[cpp] = '\0';
  	    if (USE_HASHTABLE) {
--- 486,495 ----
  	    char *s;
  	    char buf[BUFSIZ];
  
! 	    if (cpp >= sizeof(buf)) {
! 		XpmFree(iptr2); /* found by Egbert Eich */
  		return (XpmFileInvalid);
+ 	    }
  
  	    buf[cpp] = '\0';
  	    if (USE_HASHTABLE) {
***************
*** 488,494 ****
  		    xpmNextString(data);
  		    for (x = 0; x < width; x++, iptr++) {
  			for (a = 0, s = buf; a < cpp; a++, s++)
! 			    *s = xpmGetC(data);
  			slot = xpmHashSlot(hashtable, buf);
  			if (!*slot) {	/* no color matches */
  			    XpmFree(iptr2);
--- 499,505 ----
  		    xpmNextString(data);
  		    for (x = 0; x < width; x++, iptr++) {
  			for (a = 0, s = buf; a < cpp; a++, s++)
! 			    *s = xpmGetC(data); /* int assigned to char, not a problem here */
  			slot = xpmHashSlot(hashtable, buf);
  			if (!*slot) {	/* no color matches */
  			    XpmFree(iptr2);
***************
*** 502,508 ****
  		    xpmNextString(data);
  		    for (x = 0; x < width; x++, iptr++) {
  			for (a = 0, s = buf; a < cpp; a++, s++)
! 			    *s = xpmGetC(data);
  			for (a = 0; a < ncolors; a++)
  			    if (!strcmp(colorTable[a].string, buf))
  				break;
--- 513,519 ----
  		    xpmNextString(data);
  		    for (x = 0; x < width; x++, iptr++) {
  			for (a = 0, s = buf; a < cpp; a++, s++)
! 			    *s = xpmGetC(data); /* int assigned to char, not a problem here */
  			for (a = 0; a < ncolors; a++)
  			    if (!strcmp(colorTable[a].string, buf))
  				break;
***************
*** 557,563 ****
      while (!notstart && notend) {
  	/* there starts an extension */
  	ext = (XpmExtension *)
! 	    XpmRealloc(exts, (num + 1) * sizeof(XpmExtension));
  	if (!ext) {
  	    XpmFree(string);
  	    XpmFreeExtensions(exts, num);
--- 568,574 ----
      while (!notstart && notend) {
  	/* there starts an extension */
  	ext = (XpmExtension *)
! 	    XpmRealloc(exts, (num + 1) * sizeof(XpmExtension)); /* can the loop be forced to iterate often enough to make "(num + 1) * sizeof(XpmExtension)" wrapping? */
  	if (!ext) {
  	    XpmFree(string);
  	    XpmFreeExtensions(exts, num);
***************
*** 594,600 ****
  	while ((notstart = strncmp("XPMEXT", string, 6))
  	       && (notend = strncmp("XPMENDEXT", string, 9))) {
  	    sp = (char **)
! 		XpmRealloc(ext->lines, (nlines + 1) * sizeof(char *));
  	    if (!sp) {
  		XpmFree(string);
  		ext->nlines = nlines;
--- 605,611 ----
  	while ((notstart = strncmp("XPMEXT", string, 6))
  	       && (notend = strncmp("XPMENDEXT", string, 9))) {
  	    sp = (char **)
! 		XpmRealloc(ext->lines, (nlines + 1) * sizeof(char *)); /* can we iterate enough for a wrapping? */
  	    if (!sp) {
  		XpmFree(string);
  		ext->nlines = nlines;
***************
*** 634,642 ****
  /* function call in case of error */
  #undef RETURN
  #define RETURN(status) \
! { \
        goto error; \
! }
  
  /*
   * This function parses an Xpm file or data and store the found informations
--- 645,653 ----
  /* function call in case of error */
  #undef RETURN
  #define RETURN(status) \
! do { \
        goto error; \
! } while(0)
  
  /*
   * This function parses an Xpm file or data and store the found informations
diff -cr xpm-3.4k.orig/lib/s_popen.c xpm-3.4k/lib/s_popen.c
*** xpm-3.4k.orig/lib/s_popen.c	2004-12-01 15:51:30.000000000 -0600
--- xpm-3.4k/lib/s_popen.c	2004-12-01 15:50:05.000000000 -0600
***************
*** 0 ****
--- 1,181 ----
+ /*
+  * Copyright (C) 2004 The X.Org fundation
+  * 
+  * Permission is hereby granted, free of charge, to any person
+  * obtaining a copy of this software and associated documentation
+  * files (the "Software"), to deal in the Software without
+  * restriction, including without limitation the rights to use, copy,
+  * modify, merge, publish, distribute, sublicense, and/or sell copies
+  * of the Software, and to permit persons to whom the Software is fur-
+  * nished to do so, subject to the following conditions:
+  * 
+  * The above copyright notice and this permission notice shall be
+  * included in all copies or substantial portions of the Software.
+  * 
+  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+  * NONINFRINGEMENT.  IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR
+  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+  * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+  * 
+  * Except as contained in this notice, the name of the X.Org fundation
+  * shall not be used in advertising or otherwise to promote the sale,
+  * use or other dealings in this Software without prior written
+  * authorization from the X.Org fundation.
+  */
+ 
+ /*
+ ** This is a secure but NOT 100% compatible replacement for popen()
+ ** Note:        - don't use pclose() use fclose() for closing the returned
+ **                filedesc.!!!
+ **
+ ** Known Bugs:  - unable to use i/o-redirection like > or <
+ ** Author:      - Thomas Biege <thomas@suse.de>
+ ** Credits:     - Andreas Pfaller <a.pfaller@pop.gun.de> for fixing a SEGV when
+ **                calling strtok()
+ */
+ 
+ #include <sys/types.h>
+ #include <sys/wait.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <unistd.h>
+ #include <string.h>
+ 
+ #define __SEC_POPEN_TOKEN " "
+ 
+ FILE *s_popen(char *cmd, const char *type)
+ {
+   pid_t pid;
+   int pfd[2];
+   int rpipe = 0, wpipe = 0, i;
+   char **argv;
+   char *ptr;
+   char *cmdcpy;
+ 
+ 
+   if(cmd == NULL || cmd == "")
+     return(NULL);
+ 
+   if(type[0] != 'r' && type[0] != 'w')
+     return(NULL);
+ 
+   if ((cmdcpy = strdup(cmd)) == NULL)
+     return(NULL);
+ 
+   argv = NULL;
+   if( (ptr = strtok(cmdcpy, __SEC_POPEN_TOKEN)) == NULL)
+   {
+     free(cmdcpy);
+     return(NULL);
+   }
+ 
+   for(i = 0;; i++)
+   {
+     if( ( argv = (char **) realloc(argv, (i+1) * sizeof(char *)) ) == NULL)
+     {
+       free(cmdcpy);
+       return(NULL);
+     }
+ 
+     if( (*(argv+i) = (char *) malloc((strlen(ptr)+1) * sizeof(char))) == NULL)
+     {
+       free(cmdcpy);
+       return(NULL);
+     }
+ 
+     strcpy(argv[i], ptr);
+ 
+     if( (ptr = strtok(NULL, __SEC_POPEN_TOKEN)) == NULL)
+     {
+       if( ( argv = (char **) realloc(argv, (i+2) * sizeof(char *))) == NULL)
+       {
+         free(cmdcpy);
+         return(NULL);
+       }
+       argv[i+1] = NULL;
+       break;
+     }
+   }
+ 
+ 
+   if(type[0] == 'r')
+     rpipe = 1;
+   else
+     wpipe = 1;
+ 
+   if (pipe(pfd) < 0)
+   {
+     free(cmdcpy);
+     return(NULL);
+   }
+ 
+ 	if((pid = fork()) < 0)
+   {
+     close(pfd[0]);
+     close(pfd[1]);
+     free(cmdcpy);
+     return(NULL);
+   }
+ 
+ 	if(pid == 0)    /* child */
+   {
+     if((pid = fork()) < 0)
+     {
+       close(pfd[0]);
+       close(pfd[1]);
+       free(cmdcpy);
+       return(NULL);
+     }
+     if(pid > 0)
+     {
+       exit(0);  /* child nr. 1 exits */
+     }
+ 
+     /* child nr. 2 */
+     if(rpipe)
+     {
+       close(pfd[0]);  /* close reading end, we don't need it */
+       dup2(STDOUT_FILENO, STDERR_FILENO);
+       if (pfd[1] != STDOUT_FILENO)
+         dup2(pfd[1], STDOUT_FILENO);  /* redirect stdout to writing end of pipe */
+     }
+     else
+     {
+       close(pfd[1]);  /* close writing end, we don't need it */
+       if (pfd[0] != STDIN_FILENO)
+         dup2(pfd[0], STDIN_FILENO);    /* redirect stdin to reading end of pipe */
+ 	  }
+ 
+     if(strchr(argv[0], '/') == NULL)
+       execvp(argv[0], argv);  /* search in $PATH */
+     else
+       execv(argv[0], argv);
+ 
+     close(pfd[0]);
+     close(pfd[1]);
+     free(cmdcpy);
+     return(NULL);  /* exec failed.. ooops! */
+   }
+   else          /* parent */
+   {
+     waitpid(pid, NULL, 0); /* wait for child nr. 1 */
+ 
+     if(rpipe)
+     {
+       close(pfd[1]);
+       free(cmdcpy);
+       return(fdopen(pfd[0], "r"));
+     }
+     else
+     {
+       close(pfd[0]);
+       free(cmdcpy);
+       return(fdopen(pfd[1], "w"));
+     }
+ 
+   }
+ }
+ 
diff -cr xpm-3.4k.orig/lib/scan.c xpm-3.4k/lib/scan.c
*** xpm-3.4k.orig/lib/scan.c	2004-12-01 14:43:15.000000000 -0600
--- xpm-3.4k/lib/scan.c	2004-12-01 15:50:05.000000000 -0600
***************
*** 42,47 ****
--- 42,49 ----
   * 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
***************
*** 168,177 ****
  /* function call in case of error */
  #undef RETURN
  #define RETURN(status) \
! { \
        ErrorStatus = status; \
        goto error; \
! }
  
  /*
   * This function scans the given image and stores the found informations in
--- 170,179 ----
  /* 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
***************
*** 229,243 ****
      else
  	cpp = 0;
  
!     if ((height > 0 && width >= SIZE_MAX / height) ||
! 	width * height >= SIZE_MAX / sizeof(unsigned int))
  	RETURN(XpmNoMemory);
      pmap.pixelindex =
  	(unsigned int *) XpmCalloc(width * height, sizeof(unsigned int));
      if (!pmap.pixelindex)
  	RETURN(XpmNoMemory);
  
!     if (pmap.size >= SIZE_MAX / sizeof(Pixel)) 
  	RETURN(XpmNoMemory);
  
      pmap.pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * pmap.size);
--- 231,245 ----
      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);
***************
*** 304,310 ****
       * get rgb values and a string of char, and possibly a name for each
       * color
       */
!     if (pmap.ncolors >= SIZE_MAX / sizeof(XpmColor))
  	RETURN(XpmNoMemory);
      colorTable = (XpmColor *) XpmCalloc(pmap.ncolors, sizeof(XpmColor));
      if (!colorTable)
--- 306,312 ----
       * 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)
***************
*** 364,370 ****
  
      /* first get a character string */
      a = 0;
!     if (cpp >= SIZE_MAX - 1)
  	return (XpmNoMemory);
      if (!(s = color->string = (char *) XpmMalloc(cpp + 1)))
  	return (XpmNoMemory);
--- 366,372 ----
  
      /* first get a character string */
      a = 0;
!     if (cpp >= UINT_MAX - 1)
  	return (XpmNoMemory);
      if (!(s = color->string = (char *) XpmMalloc(cpp + 1)))
  	return (XpmNoMemory);
***************
*** 457,463 ****
      }
  
      /* first get character strings and rgb values */
!     if (ncolors >= SIZE_MAX / sizeof(XColor) || cpp >= SIZE_MAX - 1)
  	return (XpmNoMemory);
      xcolors = (XColor *) XpmMalloc(sizeof(XColor) * ncolors);
      if (!xcolors)
--- 459,465 ----
      }
  
      /* 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)
***************
*** 615,621 ****
      char *dst;
      unsigned int *iptr;
      char *data;
!     int x, y, i;
      int bits, depth, ibu, ibpp, offset;
      unsigned long lbt;
      Pixel pixel, px;
--- 617,623 ----
      char *dst;
      unsigned int *iptr;
      char *data;
!     unsigned int x, y, i;
      int bits, depth, ibu, ibpp, offset;
      unsigned long lbt;
      Pixel pixel, px;
***************
*** 717,723 ****
      unsigned char *addr;
      unsigned char *data;
      unsigned int *iptr;
!     int x, y;
      unsigned long lbt;
      Pixel pixel;
      int depth;
--- 719,725 ----
      unsigned char *addr;
      unsigned char *data;
      unsigned int *iptr;
!     unsigned int x, y;
      unsigned long lbt;
      Pixel pixel;
      int depth;
***************
*** 782,788 ****
      unsigned char *addr;
      unsigned char *data;
      unsigned int *iptr;
!     int x, y;
      unsigned long lbt;
      Pixel pixel;
      int depth;
--- 784,790 ----
      unsigned char *addr;
      unsigned char *data;
      unsigned int *iptr;
!     unsigned int x, y;
      unsigned long lbt;
      Pixel pixel;
      int depth;
***************
*** 827,833 ****
  {
      unsigned int *iptr;
      unsigned char *data;
!     int x, y;
      unsigned long lbt;
      Pixel pixel;
      int depth;
--- 829,835 ----
  {
      unsigned int *iptr;
      unsigned char *data;
!     unsigned int x, y;
      unsigned long lbt;
      Pixel pixel;
      int depth;
***************
*** 860,866 ****
      int (*storeFunc) ();
  {
      unsigned int *iptr;
!     int x, y;
      char *data;
      Pixel pixel;
      int xoff, yoff, offset, bpl;
--- 862,868 ----
      int (*storeFunc) ();
  {
      unsigned int *iptr;
!     unsigned int x, y;
      char *data;
      Pixel pixel;
      int xoff, yoff, offset, bpl;
***************
*** 896,906 ****
  # else /* AMIGA */
  
  #define CLEAN_UP(status) \
! {\
      if (pixels) XpmFree (pixels);\
      if (tmp_img) FreeXImage (tmp_img);\
      return (status);\
! }
  
  static int
  AGetImagePixels (
--- 898,908 ----
  # else /* AMIGA */
  
  #define CLEAN_UP(status) \
! do {\
      if (pixels) XpmFree (pixels);\
      if (tmp_img) FreeXImage (tmp_img);\
      return (status);\
! } while(0)
  
  static int
  AGetImagePixels (
***************
*** 921,927 ****
      
      tmp_img = AllocXImage ((((width+15)>>4)<<4), 1, image->rp->BitMap->Depth);
      if (tmp_img == NULL)
! 	CLEAN_UP (XpmNoMemory)
      
      iptr = pmap->pixelindex;
      for (y = 0; y < height; ++y)
--- 923,929 ----
      
      tmp_img = AllocXImage ((((width+15)>>4)<<4), 1, image->rp->BitMap->Depth);
      if (tmp_img == NULL)
! 	CLEAN_UP (XpmNoMemory);
      
      iptr = pmap->pixelindex;
      for (y = 0; y < height; ++y)
***************
*** 930,940 ****
  	for (x = 0; x < width; ++x, ++iptr)
  	{
  	    if ((*storeFunc) (pixels[x], pmap, iptr))
! 		CLEAN_UP (XpmNoMemory)
  	}
      }
      
!     CLEAN_UP (XpmSuccess)
  }
  
  #undef CLEAN_UP
--- 932,942 ----
  	for (x = 0; x < width; ++x, ++iptr)
  	{
  	    if ((*storeFunc) (pixels[x], pmap, iptr))
! 		CLEAN_UP (XpmNoMemory);
  	}
      }
      
!     CLEAN_UP (XpmSuccess);
  }
  
  #undef CLEAN_UP
