--- analyzer/pgmhist.c
+++ analyzer/pgmhist.c
@@ -45,6 +45,7 @@
     grayrow = pgm_allocrow( cols );
 
     /* Build histogram. */
+    overflow_add(maxval, 1);
     MALLOCARRAY(hist, maxval + 1);
     MALLOCARRAY(rcount, maxval + 1);
     if ( hist == NULL || rcount == NULL )
--- analyzer/pgmtexture.c
+++ analyzer/pgmtexture.c
@@ -74,7 +74,9 @@
 vector (int nl, int nh)
 {
   float *v;
-
+  overflow_add(nh, 1);
+  if(nh < nl)
+  	pm_error("assert: h < l");
   MALLOCARRAY(v, (unsigned) (nh - nl + 1));
   if (v == NULL)
     pm_error("Unable to allocate memory for a vector.");
@@ -91,12 +93,18 @@
   float **m;
 
   /* allocate pointers to rows */
+  overflow_add(nrh, 1);
+  if(nrh < nrl)
+  	pm_error("assert: nrh < nrl");
   MALLOCARRAY(m, (unsigned) (nrh - nrl + 1));
   if (m == NULL)
     pm_error("Unable to allocate memory for a matrix.");
 
   m -= ncl;
 
+  if(nch < ncl)
+  	pm_error("assert: nch < ncl");
+  overflow_add(nch, 1);
   /* allocate rows and set pointers to them */
   for (i = nrl; i <= nrh; i++)
   {
--- converter/other/bmptopnm.c
+++ converter/other/bmptopnm.c
@@ -550,6 +550,12 @@
 
     xel * colormap;
     unsigned int bytesRead;
+    
+    if (cmapsize == 0) {
+	*colormapP = NULL;
+	*bytesReadP = 0;
+	return;
+    }
 
     colormap = pnm_allocrow(MAX(1, cmapsize));
     
--- converter/other/gemtopnm.c
+++ converter/other/gemtopnm.c
@@ -106,6 +106,7 @@
 
 	pnm_writepnminit( stdout, cols, rows, MAXVAL, type, 0 );
 
+    overflow_add(cols, padright);
     { 
         /* allocate input row data structure */
         int plane;
--- converter/other/jpegtopnm.c
+++ converter/other/jpegtopnm.c
@@ -827,7 +827,9 @@
 
     /* Calculate output image dimensions so we can allocate space */
     jpeg_calc_output_dimensions(cinfoP);
-
+   
+    overflow2(cinfoP->output_width, cinfoP->output_components);
+    
     jpegbuffer = ((*cinfoP->mem->alloc_sarray)
                   ((j_common_ptr) cinfoP, JPOOL_IMAGE,
                    cinfoP->output_width * cinfoP->output_components, 
--- converter/other/pamtouil.c
+++ converter/other/pamtouil.c
@@ -134,6 +134,7 @@
     int i;
 
     /* Allocate memory for printed number.  Abort if error. */
+    overflow_add(digits, 1);
     str = (char*) malloc(digits + 1);
     if (str == NULL)
         pm_error("out of memory allocating number string");
@@ -168,6 +169,7 @@
     else {
         int i;
 
+	overflow_add(strlen(rgbname), 5 + 1);
         output = malloc(strlen(rgbname) + 5 + 1);
         if (output == NULL)
             pm_error( "out of memory allocating color name" );
--- converter/other/pbmtopgm.c
+++ converter/other/pbmtopgm.c
@@ -45,6 +45,7 @@
                  "than the image height (%u rows)", height, rows);
 
     outrow = pgm_allocrow(cols) ;
+    overflow2(width, height);
     maxval = MIN(PGM_OVERALLMAXVAL, width*height);
     pgm_writepgminit(stdout, cols, rows, maxval, 0) ;
 
--- converter/other/pngtopnm.c
+++ converter/other/pngtopnm.c
@@ -612,18 +612,30 @@
   }
 
   if (info_ptr->bit_depth == 16)
+  {
+    overflow2(2, info_ptr->width);
     linesize = 2 * info_ptr->width;
+  }
   else
     linesize = info_ptr->width;
 
   if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+  {
     linesize *= 2;
+    overflow2(2, linesize);
+  }
   else
   if (info_ptr->color_type == PNG_COLOR_TYPE_RGB)
+  {
+    overflow2(3, linesize);
     linesize *= 3;
+  }
   else
   if (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+  {
+    overflow2(4, linesize);
     linesize *= 4;
+  }
 
   for (y = 0 ; y < info_ptr->height ; y++) {
     png_image[y] = malloc (linesize);
--- converter/other/pnmtoddif.c
+++ converter/other/pnmtoddif.c
@@ -484,6 +484,7 @@
     switch (PNM_FORMAT_TYPE(format)) {
     case PBM_TYPE:
         ip.bits_per_pixel = 1;
+	overflow_add(cols, 7);
         ip.bytes_per_line = (cols + 7) / 8;
         ip.spectral = 2;
         ip.components = 1;
@@ -499,6 +500,7 @@
         ip.polarity = 2;
         break;
     case PPM_TYPE:
+        overflow2(cols, 3);
         ip.bytes_per_line = 3 * cols;
         ip.bits_per_pixel = 24;
         ip.spectral = 5;
--- converter/other/pnmtojpeg.c
+++ converter/other/pnmtojpeg.c
@@ -588,6 +588,8 @@
   const long half_maxval = maxval / 2;
   long val;
 
+  overflow_add(maxval, 1);
+  overflow2(maxval+1, sizeof(JSAMPLE));
   *rescale_p = (JSAMPLE *)
     (cinfo.mem->alloc_small) ((j_common_ptr) &cinfo, JPOOL_IMAGE,
                               (size_t) (((long) maxval + 1L) * 
@@ -664,6 +666,7 @@
     */
 
   /* Allocate the libpnm output and compressor input buffers */
+  overflow2(cinfo_p->image_width, cinfo_p->input_components);
   buffer = (*cinfo_p->mem->alloc_sarray)
     ((j_common_ptr) cinfo_p, JPOOL_IMAGE,
      (unsigned int) cinfo_p->image_width * cinfo_p->input_components, 
@@ -935,6 +938,7 @@
             (jpeg_scan_info *)
             (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
                                         scan_info_size);
+	overflow2(nscans, sizeof(jpeg_scan_info));
         memcpy(scan_info, scans, scan_info_size);
         cinfo->scan_info = scan_info;
         cinfo->num_scans = nscans;
--- converter/other/pnmtopalm/palmcolormap.c
+++ converter/other/pnmtopalm/palmcolormap.c
@@ -232,7 +232,7 @@
     return 0;
 
   colormap = malloc(sizeof(Colormap_s));
-  colormap->color_entries = malloc(sizeof(Color_s) * ncolors);
+  colormap->color_entries = malloc2(sizeof(Color_s), ncolors);
   colormap->nentries = ncolors;
   colormap->ncolors = ncolors;
 
--- converter/other/pnmtopng.c
+++ converter/other/pnmtopng.c
@@ -2014,6 +2014,7 @@
   /* Write the raster */
  
   /* max: 3 color channels, one alpha channel, 16-bit */
+  overflow2(cols, 8);
   MALLOCARRAY(line, cols * 8);
   if (line == NULL)
   {
--- converter/other/pnmtops.c
+++ converter/other/pnmtops.c
@@ -147,16 +147,24 @@
 
     cmdlineP->center  = !nocenter;
     cmdlineP->canturn = !noturn;
-    
+
+    overflow2(width, 72);
+    overflow2(height, 72);
     cmdlineP->width  = width * 72;
     cmdlineP->height = height * 72;
 
     if (imagewidth_spec)
+    {
         cmdlineP->imagewidth = imagewidth * 72;
+        overflow2(imagewidth, 72);
+    }
     else
         cmdlineP->imagewidth = 0;
     if (imageheight_spec)
+    {
+    	overflow2(imageheight, 72);
         cmdlineP->imageheight = imageheight * 72;
+    }
     else
         cmdlineP->imageheight = 0;
 
--- converter/other/pnmtorle.c
+++ converter/other/pnmtorle.c
@@ -19,6 +19,8 @@
  * If you modify this software, you should include a notice giving the
  * name of the person performing the modification, the date of modification,
  * and the reason for such modification.
+ *
+ *  2002-12-19: Fix maths wrapping bugs. Alan Cox <alan@redhat.com>
  */
 /*
  * pnmtorle - A program which will convert pbmplus (ppm or pgm) images
--- converter/other/pnmtosgi.c
+++ converter/other/pnmtosgi.c
@@ -250,6 +250,7 @@
 #endif
 
     if( storage != STORAGE_VERBATIM ) {
+        overflow2(channels, rows);
         MALLOCARRAY_NOFAIL(table, channels * rows);
         MALLOCARRAY_NOFAIL(rletemp, WORSTCOMPR(cols));
     }
@@ -303,6 +304,8 @@
             break;
         case STORAGE_RLE:
             tabrow = chan_no * rows + row;
+            overflow2(chan_no, rows);
+            overflow_add(chan_no* rows, row);
             len = rle_compress(temp, cols);    /* writes result into rletemp */
             channel[chan_no][row].length = len;
             MALLOCARRAY(p, len);
--- converter/other/pnmtotiff.c
+++ converter/other/pnmtotiff.c
@@ -611,9 +611,12 @@
     if (*bitspersampleP < 8) {
         int samplesperbyte;
         samplesperbyte = 8 / *bitspersampleP;
+        overflow2(cols, *samplesperpixelP);
+        overflow_add(cols * *samplesperpixelP, samplesperbyte);
         *bytesperrowP = 
             (cols * *samplesperpixelP + samplesperbyte-1) / samplesperbyte;
     } else 
+        overflow3( *samplesperpixelP,  cols, *bitspersampleP);
         *bytesperrowP = (cols * *samplesperpixelP * *bitspersampleP) / 8;
 
     if (requested_rowsperstrip == -1 )
--- converter/other/rast.c
+++ converter/other/rast.c
@@ -46,6 +46,11 @@
     ** not to be the case.  In reality, all of Sun's code rounds up to
     ** a short, not a long.
     */
+
+    overflow_add(depth,15);
+    overflow2(w, depth+15);
+    overflow2(w * depth + 15, 2);
+
     m->md_linebytes = ( w * depth + 15 ) / 16 * 2;
     m->md_offset.x = 0;
     m->md_offset.y = 0;
@@ -108,11 +113,14 @@
     case RT_FORMAT_RGB:
         /* Ignore hP->ras_length. */
         h.ras_length = p->pr_size.y * p->pr_data->md_linebytes;
+	overflow2(p->pr_size.y, p->pr_data->md_linebytes);
         break;
 
     case RT_BYTE_ENCODED:
         size = p->pr_size.y * p->pr_data->md_linebytes;
+	overflow2(p->pr_size.y, p->pr_data->md_linebytes);
         bp = p->pr_data->md_image;
+	overflow2(size, 3);
         MALLOCARRAY(beimage, size * 3 / 2);  /* worst case */
         if ( beimage == NULL )
             return PIX_ERR;
@@ -193,6 +201,7 @@
         switch ( colormap->type )
         {
         case RMT_EQUAL_RGB:
+	    overflow2(colormap->length, 3);
             h.ras_maplength = colormap->length * 3;
             break;
 
@@ -404,6 +413,7 @@
     case RT_STANDARD:
     case RT_FORMAT_RGB:
         /* Ignore hP->ras_length. */
+	overflow2(p->pr_size.y, p->pr_data->md_linebytes);
         i = p->pr_size.y * p->pr_data->md_linebytes;
         if ( fread( p->pr_data->md_image, 1, i, in ) != i )
         {
--- converter/other/rletopnm.c
+++ converter/other/rletopnm.c
@@ -19,6 +19,8 @@
  * If you modify this software, you should include a notice giving the
  * name of the person performing the modification, the date of modification,
  * and the reason for such modification.
+ *
+ *  2002-12-19: Fix maths wrapping bugs. Alan Cox <alan@redhat.com>
  */
 /*
  * rletopnm - A conversion program to convert from Utah's "rle" image format
--- converter/other/sgitopnm.c
+++ converter/other/sgitopnm.c
@@ -252,6 +252,7 @@
 
     if (ochan < 0) {
         maxchannel = (head->zsize < 3) ? head->zsize : 3;
+	overflow2(head->ysize, maxchannel);
         MALLOCARRAY_NOFAIL(image, head->ysize * maxchannel);
     } else {
         maxchannel = ochan + 1;
--- converter/other/sirtopnm.c
+++ converter/other/sirtopnm.c
@@ -69,6 +69,7 @@
 	    }
 	    break;
 	case PPM_TYPE:
+	    overflow3(cols, rows, 3);
 	    picsize = cols * rows * 3;
 	    planesize = cols * rows;
             if ( !( sirarray = (unsigned char*) malloc( picsize ) ) ) 
--- converter/other/tifftopnm.c
+++ converter/other/tifftopnm.c
@@ -736,6 +736,7 @@
     if (scanbuf == NULL)
         pm_error("can't allocate memory for scanline buffer");
 
+    overflow2(cols, spp);
     MALLOCARRAY(samplebuf, cols * spp);
     if (samplebuf == NULL)
         pm_error ("can't allocate memory for row buffer");
--- converter/pbm/atktopbm.c
+++ converter/pbm/atktopbm.c
@@ -281,7 +281,9 @@
 
     *rwidth = width;
     *rheight = height;
+    overflow_add(width, 7);
     rowlen = (width + 7) / 8;
+    overflow2(height, rowlen);
     MALLOCARRAY(*destaddrP, height * rowlen);
     if (destaddrP == NULL)
         pm_error("Unable to allocate %u bytes for the input image.",
--- converter/pbm/icontopbm.c
+++ converter/pbm/icontopbm.c
@@ -12,6 +12,8 @@
 
 #include <string.h>
 
+#include <string.h>
+#include <limits.h>
 #include "pbm.h"
 
 /* size in bytes of a bitmap */
@@ -86,6 +88,11 @@
     if ( *heightP <= 0 )
         pm_error( "invalid height (must be positive): %d", *heightP );
 
+    if ( *widthP > INT_MAX - 16 || *widthP < 0)
+    	pm_error( "invalid width: %d", *widthP);
+
+    overflow2(*widthP + 16, *heightP);
+
     data_length = BitmapSize( *widthP, *heightP );
     *dataP = (short unsigned int *) malloc( data_length );
     if ( *dataP == NULL )
--- converter/pbm/mdatopbm.c
+++ converter/pbm/mdatopbm.c
@@ -245,10 +245,13 @@
         pm_readlittleshort(infile, &yy); nInCols = yy;
     }
     
+    overflow2(nOutCols, 8);
     nOutCols = 8 * nInCols;
     nOutRows = nInRows;
-    if (bScale) 
-        nOutRows *= 2;
+    if (bScale) {
+	overflow2(nOutRows, 2);
+	nOutRows *= 2;
+    }
 
     data = pbm_allocarray(nOutCols, nOutRows);
     
--- converter/pbm/pbmto4425.c
+++ converter/pbm/pbmto4425.c
@@ -1,6 +1,7 @@
 #include <string.h>
 
 #include "pbm.h"
+#include <string.h>
 
 /*extern char *sys_errlist[];
 char *malloc();*/
@@ -72,7 +73,7 @@
   xres = vmap_width * 2;
   yres = vmap_height * 3;
 
-  vmap = malloc(vmap_width * vmap_height * sizeof(char));
+  vmap = malloc3(vmap_width, vmap_height, sizeof(char));
   if(vmap == NULL)
 	{
 	  pm_error( "Cannot allocate memory" );
--- converter/pbm/pbmtoascii.c
+++ converter/pbm/pbmtoascii.c
@@ -115,9 +115,11 @@
         pm_usage( usage );
 
     pbm_readpbminit( ifp, &cols, &rows, &format );
+    overflow_add(cols, gridx);
     ccols = ( cols + gridx - 1 ) / gridx;
     bitrow = pbm_allocrow( cols );
     sig = (int*) pm_allocrow( ccols, sizeof(int) );
+    overflow_add(ccols, 1);
     line = (char*) pm_allocrow( ccols + 1, sizeof(char) );
 
     for ( row = 0; row < rows; row += gridy )
--- converter/pbm/pbmtocmuwm.c
+++ converter/pbm/pbmtocmuwm.c
@@ -43,6 +43,7 @@
     bitrow = pbm_allocrow( cols );
     
     /* Round cols up to the nearest multiple of 8. */
+    overflow_add(cols, 7);
     padright = ( ( cols + 7 ) / 8 ) * 8 - cols;
 
     putinit( rows, cols );
--- converter/pbm/pbmtogem.c
+++ converter/pbm/pbmtogem.c
@@ -123,6 +123,7 @@
   bitsperitem = 0;
   bitshift = 7;
   outcol = 0;
+  overflow_add(cols, 7);
   outmax = (cols + 7) / 8;
   outrow = (unsigned char *) pm_allocrow (outmax, sizeof (unsigned char));
   lastrow = (unsigned char *) pm_allocrow (outmax, sizeof (unsigned char));
--- converter/pbm/pbmtogo.c
+++ converter/pbm/pbmtogo.c
@@ -90,6 +90,7 @@
     bitrow = pbm_allocrow(cols);
 
     /* Round cols up to the nearest multiple of 8. */
+    overflow_add(cols, 7);
     rucols = ( cols + 7 ) / 8;
     bytesperrow = rucols;       /* GraphOn uses bytes */
     rucols = rucols * 8;
--- converter/pbm/pbmtoicon.c
+++ converter/pbm/pbmtoicon.c
@@ -42,6 +42,7 @@
     bitrow = pbm_allocrow( cols );
     
     /* Round cols up to the nearest multiple of 16. */
+    overflow_add(cols, 15);
     pad = ( ( cols + 15 ) / 16 ) * 16 - cols;
     padleft = pad / 2;
     padright = pad - padleft;
--- converter/pbm/pbmtolj.c
+++ converter/pbm/pbmtolj.c
@@ -30,6 +30,7 @@
 #include "pbm.h"
 #include <string.h>
 #include <assert.h>
+#include <string.h>
 
 static int dpi = 75;
 static int floating = 0;  /* suppress the ``ESC & l 0 E'' ? */
@@ -123,7 +124,11 @@
     pbm_readpbminit( ifp, &cols, &rows, &format );
     bitrow = pbm_allocrow( cols );
 
+    overflow_add(cols, 8);
     rowBufferSize = (cols + 7) / 8;
+    overflow_add(rowBufferSize, 128);
+    overflow_add(rowBufferSize, rowBufferSize+128);
+    overflow_add(rowBufferSize+10, rowBufferSize/8);
     packBufferSize = rowBufferSize + (rowBufferSize + 127) / 128 + 1;
     deltaBufferSize = rowBufferSize + rowBufferSize / 8 + 10;
 
--- converter/pbm/pbmtomacp.c
+++ converter/pbm/pbmtomacp.c
@@ -104,6 +104,7 @@
   if( !lflg )
     left = 0;
 
+  overflow_add(left, MAX_COLS - 1);
   if( rflg )
   { if( right - left >= MAX_COLS )
       right = left + MAX_COLS - 1;
@@ -114,6 +115,8 @@
   if( !tflg )
     top = 0;
 
+  overflow_add(top, MAX_LINES - 1);
+
   if( bflg )
   { if( bottom - top >= MAX_LINES )
       bottom = top + MAX_LINES - 1;
--- converter/pbm/pbmtomda.c
+++ converter/pbm/pbmtomda.c
@@ -179,6 +179,7 @@
     
     nOutRowsUnrounded = bScale ? nInRows/2 : nInRows;
 
+    overflow_add(nOutRowsUnrounded, 3);
     nOutRows = ((nOutRowsUnrounded + 3) / 4) * 4;
         /* MDA wants rows a multiple of 4 */   
     nOutCols = nInCols / 8;
--- converter/pbm/pbmtomgr.c
+++ converter/pbm/pbmtomgr.c
@@ -43,6 +43,7 @@
     bitrow = pbm_allocrow( cols );
     
     /* Round cols up to the nearest multiple of 8. */
+    overflow_add(cols, 7);
     padright = ( ( cols + 7 ) / 8 ) * 8 - cols;
 
     putinit( rows, cols );
--- converter/pbm/pbmtoppa/pbm.c
+++ converter/pbm/pbmtoppa/pbm.c
@@ -105,6 +105,7 @@
     return 0;
 
   case P4:
+    overflow_add(pbm->width, 7);
     tmp=(pbm->width+7)/8;
     tmp2=fread(data,1,tmp,pbm->fptr);
     if(tmp2 == tmp)
@@ -129,7 +130,8 @@
     return;
 
   pbm->unread = 1;
-  pbm->revdata = malloc ((pbm->width+7)/8);
+  overflow_add(pbm->width, 7);
+  pbm->revdata = malloc((pbm->width+7)/8);
   memcpy (pbm->revdata, data, (pbm->width+7)/8);
   pbm->current_line--;
 }
--- converter/pbm/pbmtoppa/pbmtoppa.c
+++ converter/pbm/pbmtoppa/pbmtoppa.c
@@ -472,6 +472,7 @@
     }
   }
 
+  overflow_add(Width, 7);
   Pwidth=(Width+7)/8;
   printer.fptr=out;
 
--- converter/pbm/pbmtox10bm.c
+++ converter/pbm/pbmtox10bm.c
@@ -57,6 +57,7 @@
     bitrow = pbm_allocrow( cols );
 
     /* Compute padding to round cols up to the nearest multiple of 16. */
+    overflow_add(cols, 15);
     padright = ( ( cols + 15 ) / 16 ) * 16 - cols;
 
     printf( "#define %s_width %d\n", name, cols );
--- converter/pbm/pbmtoxbm.c
+++ converter/pbm/pbmtoxbm.c
@@ -100,6 +100,8 @@
     bitrow = pbm_allocrow(cols);
     
     /* Compute padding to round cols up to the nearest multiple of 8. */
+
+    overflow_add(cols, 8);
     padright = ((cols + 7)/8) * 8 - cols;
 
     printf("#define %s_width %d\n", name, cols);
--- converter/pbm/pbmtoybm.c
+++ converter/pbm/pbmtoybm.c
@@ -45,6 +45,7 @@
     bitrow = pbm_allocrow( cols );
     
     /* Compute padding to round cols up to the nearest multiple of 16. */
+    overflow_add(cols, 16);
     padright = ( ( cols + 15 ) / 16 ) * 16 - cols;
 
     putinit( cols, rows );
--- converter/pbm/pbmtozinc.c
+++ converter/pbm/pbmtozinc.c
@@ -66,6 +66,7 @@
     bitrow = pbm_allocrow( cols );
 
     /* Compute padding to round cols up to the nearest multiple of 16. */
+    overflow_add(cols, 16);
     padright = ( ( cols + 15 ) / 16 ) * 16 - cols;
 
     printf( "USHORT %s[] = {\n",name);
--- converter/pbm/pktopbm.c
+++ converter/pbm/pktopbm.c
@@ -274,6 +274,7 @@
         if (flagbyte == 7) {            /* long form preamble */
             integer packetlength = get32() ;    /* character packet length */
             car = get32() ;         /* character number */
+	    overflow_add(packetlength, pktopbm_pkloc);
             endofpacket = packetlength + pktopbm_pkloc;
                 /* calculate end of packet */
             if ((car >= MAXPKCHAR) || !filename[car]) {
--- converter/pbm/thinkjettopbm.l
+++ converter/pbm/thinkjettopbm.l
@@ -90,7 +90,9 @@
 <RASTERMODE>\033\*b{DIG}+W  {
                             int l;
                             if (rowCount >= rowCapacity) {
+				overflow_add(rowCapacity, 100);
                                 rowCapacity += 100;
+				overflow2(rowCapacity, sizeof *rows);
                                 rows = realloc (rows, rowCapacity * sizeof *rows);
                                 if (rows == NULL)
                                     pm_error ("Out of memory.");
@@ -200,6 +202,8 @@
     /*
      * Quite simple since ThinkJet bit arrangement matches PBM
      */
+
+    overflow2(maxRowLength, 8);
     pbm_writepbminit(stdout, maxRowLength*8, rowCount, 0);
 
     packed_bitrow = malloc(maxRowLength);
--- converter/pbm/ybmtopbm.c
+++ converter/pbm/ybmtopbm.c
@@ -88,6 +88,7 @@
 	pm_error( "EOF / read error" );
 
     *depthP = 1;
+    overflow_add(*colsP, 15);
     *padrightP = ( ( *colsP + 15 ) / 16 ) * 16 - *colsP;
     bitsperitem = 0;
     }
--- converter/pgm/lispmtopgm.c
+++ converter/pgm/lispmtopgm.c
@@ -57,6 +57,7 @@
         pm_error( "depth (%d bits) is too large", depth);
 
     pgm_writepgminit( stdout, cols, rows, (gray) maxval, 0 );
+    overflow_add(cols, 7);
     grayrow = pgm_allocrow( ( cols + 7 ) / 8 * 8 );
 
     for ( row = 0; row < rows; ++row )
@@ -101,7 +102,9 @@
     
     if ( *depthP == 0 )
 	*depthP = 1;	/* very old file */
-    
+
+    overflow_add(colsP, 31);
+
     *padrightP = ( ( *colsP + 31 ) / 32 ) * 32 - *colsP;
     
     if ( *colsP != (cols_32 - *padrightP) ) {
--- converter/pgm/psidtopgm.c
+++ converter/pgm/psidtopgm.c
@@ -60,6 +60,7 @@
 	    "bits/sample (%d) is too large.", bitspersample );
 
     pgm_writepgminit( stdout, cols, rows, (gray) maxval, 0 );
+    overflow_add(cols, 7);
     grayrow = pgm_allocrow( ( cols + 7 ) / 8 * 8 );
     for ( row = 0; row < rows; ++row)
 	{
--- converter/ppm/Makefile
+++ converter/ppm/Makefile
@@ -11,7 +11,7 @@
 
 PORTBINARIES =	411toppm eyuvtoppm gouldtoppm ilbmtoppm imgtoppm \
 		leaftoppm mtvtoppm neotoppm \
-		pcxtoppm pc1toppm pi1toppm picttoppm pjtoppm \
+		pcxtoppm pc1toppm pi1toppm pjtoppm \
 		ppmtoacad ppmtoarbtxt \
 		ppmtobmp ppmtoeyuv ppmtogif ppmtoicr ppmtoilbm \
 		ppmtoleaf ppmtolj ppmtomitsu ppmtoneo \
--- converter/ppm/ilbmtoppm.c
+++ converter/ppm/ilbmtoppm.c
@@ -580,6 +580,7 @@
     rawtype *chp;
 
     cols = bmhd->w;
+    overflow_add(cols, 15);
     bytes = RowBytes(cols);
     for( plane = 0; plane < nPlanes; plane++ ) {
         int mask;
@@ -881,6 +882,7 @@
 
     col = cmap->ncolors;
 
+    overflow2(col, 2);
     tempcolor = ppm_allocrow(col * 2);
     for( i = 0; i < col; i++ ) {
         tempcolor[i] = cmap->color[i];
@@ -1913,6 +1915,9 @@
         cmap->mp_change[i] = NULL;
     if( PCHG.StartLine < 0 ) {
         int nch;
+        if(PCHG.MaxReg < PCHG.MinReg)
+        	pm_error("assert: MinReg > MaxReg");
+        overflow_add(PCHG.MaxReg-PCHG.MinReg, 2);
         nch = PCHG.MaxReg - PCHG.MinReg +1;
         MALLOCARRAY_NOFAIL(cmap->mp_init, nch + 1);
         for( i = 0; i < nch; i++ )
--- converter/ppm/imgtoppm.c
+++ converter/ppm/imgtoppm.c
@@ -84,6 +84,7 @@
             len = atoi((char*) buf );
             if ( fread( buf, len, 1, ifp ) != 1 )
                 pm_error( "bad colormap buf" );
+            overflow2(cmaplen, 3);
             if ( cmaplen * 3 != len )
             {
                 pm_message(
@@ -105,6 +106,7 @@
                 pm_error( "bad pixel data header" );
             buf[8] = '\0';
             len = atoi((char*) buf );
+            overflow2(cols, rows);
             if ( len != cols * rows )
                 pm_message(
                     "pixel data length (%d) does not match image size (%d)",
--- converter/ppm/pcxtoppm.c
+++ converter/ppm/pcxtoppm.c
@@ -376,6 +376,7 @@
     }
 
     /*  BytesPerLine should be >= BitsPerPixel * cols / 8  */
+    overflow2(BytesPerLine, 8);
     rawcols = BytesPerLine * 8 / BitsPerPixel;
     if( cols > rawcols ) {
         pm_message("warning - BytesPerLine = %d, "
@@ -383,6 +384,7 @@
                    BytesPerLine, rawcols);
         cols = rawcols;
     }
+    overflow2(Planes, BytesPerLine); 
     pcxrow = (unsigned char *)
         pm_allocrow(Planes * BytesPerLine, sizeof(unsigned char));
     rawrow = (unsigned char *)pm_allocrow(rawcols, sizeof(unsigned char));
@@ -578,6 +580,8 @@
     /*
      * clear the pixel buffer
      */
+
+    overflow2(bytesperline, 8);
     npixels = (bytesperline * 8) / bitsperpixel;
     p    = pixels;
     while (--npixels >= 0)
--- converter/ppm/picttoppm.c
+++ converter/ppm/picttoppm.c
@@ -1,3 +1,5 @@
+#error "Unfixable. Don't ship me"
+
 /*
  * picttoppm.c -- convert a MacIntosh PICT file to PPM format.
  *
--- converter/ppm/pjtoppm.c
+++ converter/ppm/pjtoppm.c
@@ -127,19 +127,23 @@
                 case 'V':   /* send plane */
                 case 'W':   /* send last plane */
                     if (rows == -1 || r >= rows || image == NULL) {
-                        if (rows == -1 || r >= rows)
+                        if (rows == -1 || r >= rows) {
+			    overflow_add(rows, 100);
                             rows += 100;
+			}
                         if (image == NULL) {
+			    overflow2(rows, planes);
                             MALLOCARRAY(image, rows * planes);
                             MALLOCARRAY(imlen, rows * planes);
                         }
                         else {
+			    overflow2(rows,planes);
                             image = (unsigned char **) 
-                                realloc(image, 
-                                        rows * planes * 
+                                realloc2(image, 
+                                        rows * planes,
                                         sizeof(unsigned char *));
                             imlen = (int *) 
-                                realloc(imlen, rows * planes * sizeof(int));
+                                realloc2(imlen, rows * planes,sizeof(int));
                         }
                     }
                     if (image == NULL || imlen == NULL)
@@ -215,6 +219,8 @@
                          cmd >= 0 && i < newcols; cmd--, i++) 
                         buf[i] = val;
                 cols = cols > i ? cols : i;
+		 overflow_add(i, 1);
+		
                 free(image[p + r * planes]);
                 /* 
                  * This is less than what we have so it realloc should 
@@ -224,6 +230,7 @@
                 image[p + r * planes] = (unsigned char *) realloc(buf, i);
             }
         }
+	overflow2(cols, 8);
         cols *= 8;
     }
             
--- converter/ppm/ppmtoeyuv.c
+++ converter/ppm/ppmtoeyuv.c
@@ -113,6 +113,7 @@
 
     int index;
 
+    overflow_add(maxval, 1);
     MALLOCARRAY_NOFAIL(mult299   , maxval+1);
     MALLOCARRAY_NOFAIL(mult587   , maxval+1);
     MALLOCARRAY_NOFAIL(mult114   , maxval+1);
--- converter/ppm/ppmtoicr.c
+++ converter/ppm/ppmtoicr.c
@@ -169,7 +169,7 @@
 
 	if (rleflag) {	
 		pm_message("sending run-length encoded picture data ..." );
-		testimage = (char*) malloc(rows*cols);
+		testimage = (char*) malloc2(rows, cols);
 		p = testimage;
 		for (i=0; i<rows; i++)
 			for (j=0; j<cols; j++) 
--- converter/ppm/ppmtoilbm.c
+++ converter/ppm/ppmtoilbm.c
@@ -810,11 +810,16 @@
 
     if( mode != MODE_CMAP ) {
         register int i;
+        overflow_add(cols, 15);
         MALLOCARRAY_NOFAIL(coded_rowbuf, RowBytes(cols));
         for( i = 0; i < RowBytes(cols); i++ )
             coded_rowbuf[i] = 0;
         if( DO_COMPRESS )
+        {
+            overflow2(cols,2);
+            overflow_add(cols *2, 2);
             MALLOCARRAY_NOFAIL(compr_rowbuf, WORSTCOMPR(RowBytes(cols)));
+        }
     }
 
     switch( mode ) {
@@ -1905,6 +1910,7 @@
 
     maskmethod = 0;     /* no masking - RGB8 uses genlock bits */
     compmethod = 4;     /* RGB8 files are always compressed */
+    overflow2(cols, 4);
     MALLOCARRAY_NOFAIL(compr_row, cols * 4);
 
     if( maxval != 255 ) {
@@ -1993,6 +1999,7 @@
 
     maskmethod = 0;     /* no masking - RGBN uses genlock bits */
     compmethod = 4;     /* RGBN files are always compressed */
+    overflow2(cols, 2);
     MALLOCARRAY_NOFAIL(compr_row, cols * 2);
 
     if( maxval != 15 ) {
@@ -2475,6 +2482,7 @@
     int i;
     int *table;
 
+    overflow_add(oldmaxval, 1);
     MALLOCARRAY_NOFAIL(table, oldmaxval + 1);
     for(i = 0; i <= oldmaxval; i++ )
         table[i] = (i * newmaxval + oldmaxval/2) / oldmaxval;
--- converter/ppm/ppmtolj.c
+++ converter/ppm/ppmtolj.c
@@ -182,6 +182,7 @@
     pixels = ppm_readppm( ifp, &cols, &rows, &maxval );
 
     pm_close( ifp );
+    overflow2(cols,6);
     obuf = (unsigned char *) pm_allocrow(cols * 3, sizeof(unsigned char));
     cbuf = (unsigned char *) pm_allocrow(cols * 6, sizeof(unsigned char));
     if (mode == C_TRANS_MODE_DELTA)
--- converter/ppm/ppmtomitsu.c
+++ converter/ppm/ppmtomitsu.c
@@ -164,6 +164,8 @@
         medias = MSize_User;
 
         if (dpi300) {
+        	overflow2(medias.maxcols, 2);
+        	overflow2(medias.maxrows, 2);
                 medias.maxcols *= 2;
                 medias.maxrows *= 2;
         }
--- converter/ppm/ppmtopcx.c
+++ converter/ppm/ppmtopcx.c
@@ -418,6 +418,8 @@
             else                   Planes = 1;
         }
     }
+    overflow2(BitsPerPixel, cols);
+    overflow_add(BitsPerPixel * cols, 7);
     BytesPerLine = ((cols * BitsPerPixel) + 7) / 8;
     MALLOCARRAY_NOFAIL(indexRow, cols);
     MALLOCARRAY_NOFAIL(planesrow, BytesPerLine);
--- converter/ppm/ppmtopict.c
+++ converter/ppm/ppmtopict.c
@@ -245,6 +245,8 @@
 	putShort(stdout, 0);			/* mode */
 
 	/* Finally, write out the data. */
+	overflow_add(cols/MAX_COUNT, 1);
+        overflow_add(cols, cols/MAX_COUNT+1);
 	packed = (char*) malloc((unsigned)(cols+cols/MAX_COUNT+1));
 	oc = 0;
 	for (row = 0; row < rows; row++)
--- converter/ppm/ppmtopj.c
+++ converter/ppm/ppmtopj.c
@@ -180,6 +180,7 @@
 	pixels = ppm_readppm( ifp, &cols, &rows, &maxval );
 
 	pm_close( ifp );
+	overflow2(cols,2);
 	obuf = (unsigned char *) pm_allocrow(cols, sizeof(unsigned char));
 	cbuf = (unsigned char *) pm_allocrow(cols * 2, sizeof(unsigned char));
 
--- converter/ppm/ppmtopjxl.c
+++ converter/ppm/ppmtopjxl.c
@@ -273,6 +273,8 @@
       pm_error("image too large; reduce with ppmscale");
    if (maxval > PCL_MAXVAL)
       pm_error("color range too large; reduce with ppmcscale");
+   if (cols < 0 || rows < 0)
+   	pm_error("negative size is not possible");
 
    /* Figure out the colormap. */
    fprintf( stderr, "(Computing colormap..." ); fflush( stderr );
@@ -293,6 +295,8 @@
       case 0: /* direct mode (no palette) */
 	 bpp = bitsperpixel(maxval); /* bits per pixel */
 	 bpg = bpp; bpb = bpp;
+	 overflow2(bpp, 3);
+	 overflow_add(bpp*3, 7);
 	 bpp = (bpp*3+7)>>3;     /* bytes per pixel now */
 	 bpr = (bpp<<3)-bpg-bpb; 
 	 bpp *= cols;            /* bytes per row now */
@@ -302,9 +306,13 @@
       case 3: case 7: pclindex++;
       default:
 	 bpp = 8/pclindex;
+	 overflow_add(cols, bpp);
+	 if(bpp == 0)
+		pm_error("assert: no bpp");
 	 bpp = (cols+bpp-1)/bpp;      /* bytes per row */
       }
 
+   overflow2(bpp,2);
    if ((inrow = (char *)malloc((unsigned)bpp)) == NULL ||
        (outrow = (char *)malloc((unsigned)bpp*2)) == NULL ||
        (runcnt = (signed char *)malloc((unsigned)bpp)) == NULL)
--- converter/ppm/ppmtowinicon.c
+++ converter/ppm/ppmtowinicon.c
@@ -12,6 +12,7 @@
 
 #include <math.h>
 #include <string.h>
+#include <stdlib.h>
 
 #include "winico.h"
 #include "ppm.h"
@@ -713,6 +714,12 @@
     entry->bitcount      = bpp;
     entry->ih            = createInfoHeader(entry, xorBitmap, andBitmap);
     entry->colors        = palette->colors;
+
+   overflow2(4, entry->color_count);
+   overflow_add(xorBitmap->size, andBitmap->size);
+   overflow_add(xorBitmap->size + andBitmap->size, 40);
+   overflow_add(xorBitmap->size + andBitmap->size + 40, 4 * entry->color_count);
+
     entry->size_in_bytes = 
         xorBitmap->size + andBitmap->size + 40 + (4 * entry->color_count);
     if (verbose) 
@@ -736,7 +743,7 @@
     * Perhaps I should use something that allocs a decent amount at start...
     */
     MSIconData->entries = 
-        realloc (MSIconData->entries, MSIconData->count * sizeof(IC_Entry *));
+        realloc2 (MSIconData->entries, MSIconData->count, sizeof(IC_Entry *));
     MSIconData->entries[MSIconData->count-1] = entry;
 }
 
--- converter/ppm/ppmtoxpm.c
+++ converter/ppm/ppmtoxpm.c
@@ -180,6 +180,7 @@
     int i;
 
     /* Allocate memory for printed number.  Abort if error. */
+    overflow_add(digits, 1);
     if (!(str = (char *) malloc(digits + 1)))
         pm_error("out of memory");
 
--- converter/ppm/qrttoppm.c
+++ converter/ppm/qrttoppm.c
@@ -46,7 +46,7 @@
 
     ppm_writeppminit( stdout, cols, rows, maxval, 0 );
     pixelrow = ppm_allocrow( cols );
-    buf = (unsigned char *) malloc( 3 * cols );
+    buf = (unsigned char *) malloc2( 3 , cols );
     if ( buf == (unsigned char *) 0 )
 	pm_error( "out of memory" );
 
--- converter/ppm/sldtoppm.c
+++ converter/ppm/sldtoppm.c
@@ -307,6 +307,8 @@
 
     /* Allocate image buffer and clear it to black. */
 
+    overflow_add(ixdots,1);
+    overflow_add(iydots,1);
     pixels = ppm_allocarray(pixcols = ixdots + 1, pixrows = iydots + 1);
     PPM_ASSIGN(rgbcolour, 0, 0, 0);
     ppmd_filledrectangle(pixels, pixcols, pixrows, pixmaxval, 0, 0,
--- converter/ppm/ximtoppm.c
+++ converter/ppm/ximtoppm.c
@@ -283,6 +283,7 @@
     header->bits_channel = atoi(a_head.bits_per_channel);
     header->alpha_flag = atoi(a_head.alpha_channel);
     if (strlen(a_head.author)) {
+    	overflow_add(strlen(a_head.author),1);
         if (!(header->author = calloc((unsigned int)strlen(a_head.author)+1,
                 1))) {
             pm_message("ReadXimHeader: can't calloc author string" );
@@ -292,6 +293,7 @@
         strncpy(header->author, a_head.author, strlen(a_head.author));
     }
     if (strlen(a_head.date)) {
+        overflow_add(strlen(a_head.date),1);
         if (!(header->date =calloc((unsigned int)strlen(a_head.date)+1,1))){
             pm_message("ReadXimHeader: can't calloc date string" );
             return(0);
@@ -300,6 +302,7 @@
         strncpy(header->date, a_head.date, strlen(a_head.date));
     }
     if (strlen(a_head.program)) {
+        overflow_add(strlen(a_head.program),1);
         if (!(header->program = calloc(
                     (unsigned int)strlen(a_head.program) + 1, 1))) {
             pm_message("ReadXimHeader: can't calloc program string" );
@@ -326,6 +329,7 @@
     if (header->nchannels == 3 && header->bits_channel == 8)
         header->ncolors = 0;
     else if (header->nchannels == 1 && header->bits_channel == 8) {
+	overflow2(header->ncolors, sizeof(Color));
         header->colors = (Color *)calloc((unsigned int)header->ncolors,
                 sizeof(Color));
         if (header->colors == NULL) {
--- converter/ppm/yuvtoppm.c
+++ converter/ppm/yuvtoppm.c
@@ -72,6 +72,7 @@
 
 	ppm_writeppminit(stdout, cols, rows, (pixval) 255, 0);
 	pixrow = ppm_allocrow(cols);
+    overflow_add(cols, 1);
     MALLOCARRAY(yuvbuf, (cols+1)/2);
     if (yuvbuf == NULL)
         pm_error("Unable to allocate YUV buffer for %d columns.", cols);
--- doc/COPYRIGHT.PATENT
+++ doc/COPYRIGHT.PATENT
@@ -33,6 +33,11 @@
 all the above to be modified by "to the best of the Netpbm
 maintainer's knowledge."
 
+These security fixes for netpbm are (c) Copyright 2002 Red Hat Inc.
+Red Hat has not fixed those items with patent claims or commercial
+use restrictions. These changes include NO WARRANTY and are provided
+under the Open Software License v.1 (see file OPENLICENSE).
+
 
 
 PATENTS
--- editor/pamcut.c
+++ editor/pamcut.c
@@ -509,6 +509,8 @@
     outpam.width  = rightcol-leftcol+1;
     outpam.height = bottomrow-toprow+1;
 
+    overflow_add(rightcol, 1);
+    overflow_add(toprow, 1);
     pnm_writepaminit(&outpam);
 
     /* Write out top padding */
--- editor/pamoil.c
+++ editor/pamoil.c
@@ -112,6 +112,7 @@
     tuples = pnm_readpam(ifp, &inpam, PAM_STRUCT_SIZE(tuple_type));
     pm_close(ifp);
 
+    overflow_add(inpam.maxval, 1);
     MALLOCARRAY(hist, inpam.maxval + 1);
     if (hist == NULL)
         pm_error("Unable to allocate memory for histogram.");
--- editor/pbmclean.c
+++ editor/pbmclean.c
@@ -147,7 +147,7 @@
     inrow[0] = inrow[1];
     inrow[1] = inrow[2];
     inrow[2] = shuffle ;
-    if (row+1 < rows) {
+    if (row <= rows) {
         /* Read the "next" row in from the file.  Allocate buffer if neeeded */
         if (inrow[2] == NULL)
             inrow[2] = pbm_allocrow(cols);
--- editor/pbmlife.c
+++ editor/pbmlife.c
@@ -54,7 +54,7 @@
 	prevrow = thisrow;
 	thisrow = nextrow;
 	nextrow = temprow;
-	if ( row < rows - 1 )
+	if ( row <= rows )
 	    pbm_readpbmrow( ifp, nextrow, cols, format );
 
         for ( col = 0; col < cols; ++col )
--- editor/pbmpscale.c
+++ editor/pbmpscale.c
@@ -109,6 +109,7 @@
    inrow[0] = inrow[1] = inrow[2] = NULL;
    pbm_readpbminit(ifd, &columns, &rows, &format) ;
 
+   overflow2(columns, scale);
    outrow = pbm_allocrow(columns*scale) ;
    MALLOCARRAY(flags, columns);
    if (flags == NULL) 
--- editor/pbmreduce.c
+++ editor/pbmreduce.c
@@ -93,6 +93,7 @@
 
     if ( halftone == QT_FS ) {
         /* Initialize Floyd-Steinberg. */
+	overflow_add(newcols, 2);
         MALLOCARRAY(thiserr, newcols + 2);
         MALLOCARRAY(nexterr, newcols + 2);
         if ( thiserr == NULL || nexterr == NULL )
--- editor/pnmcrop.c
+++ editor/pnmcrop.c
@@ -379,6 +379,8 @@
 
         xelrow = pnm_allocrow(cols);
 
+	overflow_add(right, 1);
+	overflow_add(bottom, 1);
         newcols = right - left + 1;
         newrows = bottom - top + 1;
         pnm_writepnminit(stdout, newcols, newrows, maxval, format, 0);
--- editor/pnmcut.c
+++ editor/pnmcut.c
@@ -373,6 +373,7 @@
                    toprow, leftcol, bottomrow, rightcol);
     }
 
+    overflow_add(rightcol, 1);
     output_cols = rightcol-leftcol+1;
     output_row = pnm_allocrow(output_cols);
     
--- editor/pnmgamma.c
+++ editor/pnmgamma.c
@@ -280,6 +280,7 @@
                   xelval **rtableP, xelval **gtableP, xelval **btableP) {
 
     /* Allocate space for the tables. */
+    overflow_add(maxval, 1);
     MALLOCARRAY(*rtableP, maxval+1);
     MALLOCARRAY(*gtableP, maxval+1);
     MALLOCARRAY(*btableP, maxval+1);
--- editor/pnmhisteq.c
+++ editor/pnmhisteq.c
@@ -210,6 +210,7 @@
        user has specified an input map file, read it in at
        this point. */
 
+    overflow_add(maxval, 1);
     lumahist = (long *) pm_allocrow(maxval + 1, sizeof(long));
     memset((char *) lumahist, 0, (maxval + 1) * sizeof(long));
 
--- editor/pnmindex.csh
+++ editor/pnmindex.csh
@@ -1,5 +1,8 @@
 #!/bin/csh -f
 #
+echo "Unsafe code, needs debugging, do not ship"
+exit 1
+#
 # pnmindex - build a visual index of a bunch of anymaps
 #
 # Copyright (C) 1991 by Jef Poskanzer.
--- editor/pnmpad.c
+++ editor/pnmpad.c
@@ -356,6 +356,8 @@
 
     computePadSizes(cmdline, cols, rows, &lpad, &rpad, &tpad, &bpad);
 
+    overflow_add(cols, lpad);
+    overflow_add(cols + lpad, rpad);
     newcols = cols + lpad + rpad;
     xelrow = pnm_allocrow(newcols);
     bgrow = pnm_allocrow(newcols);
--- editor/pnmpaste.c
+++ editor/pnmpaste.c
@@ -100,11 +100,16 @@
 	    "y is too large -- the second anymap has only %d rows",
 	    rows2 );
 
+    overflow_add(x, cols2);
+    overflow_add(y, rows2);
     if ( x < 0 )
 	x += cols2;
     if ( y < 0 )
 	y += rows2;
 
+    overflow_add(x, cols1);
+    overflow_add(y, rows1);
+
     if ( x + cols1 > cols2 )
 	pm_error( "x + width is too large by %d pixels", x + cols1 - cols2 );
     if ( y + rows1 > rows2 )
--- editor/pnmremap.c
+++ editor/pnmremap.c
@@ -228,6 +228,7 @@
 
     unsigned int const fserrSize = pamP->width + 2;
 
+    overflow_add(pamP->width, 2);
     MALLOCARRAY(fserrP->thiserr, pamP->depth);
     if (fserrP->thiserr == NULL)
         pm_error("Out of memory allocating Floyd-Steinberg structures");
@@ -267,6 +268,7 @@
 
     int col;
     
+    overflow_add(pamP->width, 2);
     for (col = 0; col < pamP->width + 2; ++col) {
         unsigned int plane;
         for (plane = 0; plane < pamP->depth; ++plane) 
--- editor/pnmrotate.c
+++ editor/pnmrotate.c
@@ -11,6 +11,7 @@
 */
 
 #include <math.h>
+#include <limits.h>
 
 #include "pnm.h"
 #include "shhopt.h"
@@ -563,8 +564,16 @@
     yshearfac = sin(cmdline.angle);
     if (yshearfac < 0.0)
         yshearfac = -yshearfac;
+	
+    if (rows * xshearfac + cols + 0.999999 >= INT_MAX)
+	pm_error("image too large");
+	
     tempcols = rows * xshearfac + cols + 0.999999;
     yshearjunk = (tempcols - cols) * yshearfac;
+
+    if (tempcols * yshearfac + rows + 0.999999 >= INT_MAX)
+	pm_error("image too large");
+
     newrows = tempcols * yshearfac + rows + 0.999999;
     x2shearjunk = (newrows - rows - yshearjunk) * xshearfac;
     newrows -= 2 * yshearjunk;
--- editor/pnmscalefixed.c
+++ editor/pnmscalefixed.c
@@ -209,6 +209,8 @@
                           const int rows, const int cols,
                           int * newrowsP, int * newcolsP) {
 
+    overflow2(rows, cols);
+
     if (cmdline.pixels) {
         if (rows * cols <= cmdline.pixels) {
             *newrowsP = rows;
@@ -260,6 +262,8 @@
 
     if (*newcolsP < 1) *newcolsP = 1;
     if (*newrowsP < 1) *newrowsP = 1;
+
+    overflow2(*newcolsP, *newrowsP);
 }        
 
 
@@ -441,6 +445,9 @@
        unfilled.  We can address that by stretching, whereas the other
        case would require throwing away some of the input.
     */
+
+    overflow2(newcols, SCALE);
+    overflow2(newrows, SCALE);
     sxscale = SCALE * newcols / cols;
     syscale = SCALE * newrows / rows;
 
--- editor/pnmshear.c
+++ editor/pnmshear.c
@@ -12,6 +12,7 @@
 
 #include <math.h>
 #include <string.h>
+#include <limits.h>
 
 #include "pnm.h"
 #include "shhopt.h"
@@ -198,6 +199,11 @@
     if ( shearfac < 0.0 )
         shearfac = -shearfac;
 
+    if(rows * shearfac >= INT_MAX-1)
+    	pm_error("image too large");
+
+    overflow_add(rows * shearfac, cols+1);
+
     newcols = rows * shearfac + cols + 0.999999;
 
     pnm_writepnminit( stdout, newcols, rows, newmaxval, newformat, 0 );
--- editor/ppmdither.c
+++ editor/ppmdither.c
@@ -111,6 +111,9 @@
             (dith_dim * sizeof(int *)) + /* pointers */
             (dith_dim * dith_dim * sizeof(int)); /* data */
 
+	overflow2(dith_dim, sizeof(int *));
+	overflow3(dith_dim, dith_dim, sizeof(int));
+	overflow_add(dith_dim * sizeof(int *), dith_dim * dith_dim * sizeof(int));
         dith_mat = (unsigned int **) malloc(dith_mat_sz);
 
         if (dith_mat == NULL) 
--- generator/pbmpage.c
+++ generator/pbmpage.c
@@ -15,6 +15,7 @@
 #include <math.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include "pbm.h"
 
 /* Support both US and A4. */
@@ -161,6 +162,9 @@
     /* We round the allocated row space up to a multiple of 8 so the ugly
        fast code below can work.
        */
+
+    overflow_add(Width, 7);
+
     pbmrow = pbm_allocrow(((Width+7)/8)*8);
     
     bitmap_cursor = 0;
--- generator/pbmtext.c
+++ generator/pbmtext.c
@@ -89,12 +89,14 @@
         
         for (i = 1; i < argc; i++) {
             if (i > 1) {
+                overflow_add(totaltextsize, 1);
                 totaltextsize += 1;
                 text = realloc(text, totaltextsize);
                 if (text == NULL)
                     pm_error("out of memory allocating space for input text");
                 strcat(text, " ");
             } 
+            overflow_add(totaltextsize, strlen(argv[i]));
             totaltextsize += strlen(argv[i]);
             text = realloc(text, totaltextsize);
             if (text == NULL)
@@ -594,7 +596,9 @@
         while (fgets(buf, sizeof(buf), stdin) != NULL) {
             fix_control_chars(buf, fn);
             if (lineCount >= maxlines) {
+	        overflow2(maxlines, 2);
                 maxlines *= 2;
+		overflow2(maxlines, sizeof(char*));
                 text_array = (char**) realloc((char*) text_array, 
                                               maxlines * sizeof(char*));
                 if (text_array == NULL)
@@ -680,6 +684,7 @@
             hmargin = fontP->maxwidth;
         } else {
             vmargin = fontP->maxheight;
+    	    overflow2(2, fontP->maxwidth);
             hmargin = 2 * fontP->maxwidth;
         }
     }
@@ -695,12 +700,19 @@
     } else
         lp = input_text;
     
+    overflow2(2, vmargin);
+    overflow2(lp.lineCount, fontP->maxheight);
+    overflow_add(vmargin * 2, lp.lineCount * fontP->maxheight);
+    overflow2(lp.lineCount-1, cmdline.lspace);
+    overflow_add(2 * vmargin + lp.lineCount * fontP->maxheight, (lp.lineCount-1) * cmdline.lspace);
     rows = 2 * vmargin + 
         lp.lineCount * fontP->maxheight + 
         (lp.lineCount-1) * cmdline.lspace;
 
     compute_image_width(lp, fontP, cmdline.space, &maxwidth, &maxleftb);
 
+    overflow2(2, hmargin);
+    overflow_add(2*hmargin, maxwidth);
     cols = 2 * hmargin + maxwidth;
     bits = pbm_allocarray(cols, rows);
 
--- generator/pgmcrater.c
+++ generator/pgmcrater.c
@@ -131,6 +131,7 @@
     /* Acquire the elevation array and initialise it to mean
        surface elevation. */
 
+    overflow2(SCRX, SCRY);
     MALLOCARRAY(aux, SCRX * SCRY);
     if (aux == NULL) 
         pm_error("out of memory allocating elevation array");
--- generator/pgmkernel.c
+++ generator/pgmkernel.c
@@ -68,6 +68,7 @@
     kycenter = (fysize - 1) / 2.0;
     ixsize = fxsize + 0.999;
     iysize = fysize + 0.999;
+    overflow2(ixsize, iysize);
     MALLOCARRAY(fkernel, ixsize * iysize);
     for (i = 0; i < iysize; i++) 
         for (j = 0; j < ixsize; j++) {
--- generator/ppmforge.c
+++ generator/ppmforge.c
@@ -418,7 +418,7 @@
 
     if (UINT_MAX / n < n)
         pm_error("arithmetic overflow squaring %u", n);
-    cp = malloc(n * n);
+    cp = malloc2(n,n);
     if (cp == NULL)
         pm_error("Unable to allocate %u bytes for cp array", n);
 
--- lib/libpam.c
+++ lib/libpam.c
@@ -273,7 +273,8 @@
        themselves.  Each tuple consists of 'depth' samples.  
     */
 
-    tuplerow = malloc(pamP->width * (sizeof(tuple *) + bytes_per_tuple));
+    overflow_add(sizeof(tuple *), bytes_per_tuple);
+    tuplerow = malloc2(pamP->width, sizeof(tuple *) + bytes_per_tuple);
     if (tuplerow == NULL)
         pm_error("Out of memory allocating space for a tuple row of\n"
                  "%d tuples by %d samples per tuple by %d bytes per sample.",
--- lib/libpammap.c
+++ lib/libpammap.c
@@ -315,7 +315,11 @@
        as a single malloc block and suballocate internally.
     */
     
-    pool = malloc(mainTableSize + size * tupleIntSize);
+    overflow2(pamP->depth, sizeof(sample));
+    overflow_add(pamP->depth*sizeof(sample),
+    		sizeof(struct tupleint) - sizeof(sample));
+    overflow_add(mainTableSize, size);
+    pool = malloc2(mainTableSize + size, tupleIntSize);
     
     retval = (tupletable) pool;
 
--- lib/libpbm1.c
+++ lib/libpbm1.c
@@ -58,6 +58,8 @@
         pm_message("pm_filepos passed to pm_check() is %u bytes",
                    sizeof(pm_filepos));
 #endif
+        overflow2(bytes_per_row, rows);
+
         pm_check(file, check_type, need_raster_size, retval_p);
     }
 }
--- lib/libpbmvms.c
+++ lib/libpbmvms.c
@@ -1,3 +1,5 @@
+#warning "NOT AUDITED"
+
 /***************************************************************************
   This file contains library routines needed to build Netpbm for VMS.
   However, as of 2000.05.26, when these were split out of libpbm1.c
--- lib/libpm.c
+++ lib/libpm.c
@@ -35,6 +35,7 @@
     /* This makes the the x64() functions available on AIX */
 
 #include <stdio.h>
+#include <limits.h>
 #include "version.h"
 #include "compile.h"
 #include "nstring.h"
@@ -122,7 +123,7 @@
 pm_allocrow(int const cols, int const size) {
     char * itrow;
 
-    itrow = malloc( cols * size );
+    itrow = malloc2( cols , size );
     if ( itrow == NULL )
         pm_error( "out of memory allocating a row" );
     return itrow;
@@ -158,11 +159,13 @@
     char** rowIndex;
     char * rowheap;
 
+
+    overflow_add(rows, 1);
     MALLOCARRAY(rowIndex, rows + 1);
     if ( rowIndex == NULL )
         pm_error("out of memory allocating row index (%u rows) for an array",
                  rows);
-    rowheap = malloc( rows * cols * size );
+    rowheap = malloc3( rows, cols, size );
     if ( rowheap == NULL ) {
         /* We couldn't get the whole heap in one block, so try fragmented
            format.
@@ -1014,7 +1017,7 @@
     
     long filepos;
 
-    pm_tell2(fileP, (pm_filepos *)&filepos, sizeof(filepos));
+    pm_tell2(fileP, (pm_filepos *)(void *)&filepos, sizeof(filepos));
 
     return filepos;
 }
@@ -1171,4 +1174,53 @@
 }
 
 
+/*
+ *	Maths wrapping
+ */
+
+void overflow2(int a, int b)
+{
+	if(a < 0 || b < 0)
+		pm_error("object too large");
+	if(b == 0)
+		return;
+	if(a > INT_MAX / b)
+		pm_error("object too large");
+}
+
+void overflow3(int a, int b, int c)
+{
+	overflow2(a,b);
+	overflow2(a*b, c);
+}
+
+void overflow_add(int a, int b)
+{
+	if( a > INT_MAX - b)
+		pm_error("object too large");
+}
+
+void *malloc2(int a, int b)
+{
+	overflow2(a, b);
+	if(a*b == 0)
+		pm_error("Zero byte allocation");
+	return malloc(a*b);
+}
+
+void *malloc3(int a, int b, int c)
+{
+	overflow3(a, b, c);
+	if(a*b*c == 0)
+		pm_error("Zero byte allocation");
+	return malloc(a*b*c);
+}
+
+void *realloc2(void * a, int b, int c)
+{
+	overflow2(b, c);
+	if(b*c == 0)
+		pm_error("Zero byte allocation");
+	return realloc(a, b*c);
+}
 
--- lib/pm.h
+++ lib/pm.h
@@ -161,6 +161,12 @@
 pm_closew (FILE* const f);
 
 
+void *malloc2(int, int);
+void *malloc3(int, int, int);
+void overflow2(int, int);
+void overflow3(int, int, int);
+void overflow_add(int, int);
+void *realloc2(void *, int, int);
 
 int
 pm_readbigshort(FILE *  const in, 
--- lib/util/mallocvar.h
+++ lib/util/mallocvar.h
@@ -51,7 +51,7 @@
 
 
 #define MALLOCARRAY(arrayName, nElements) \
-    mallocProduct((void **)&arrayName, nElements, sizeof(arrayName[0]))
+    mallocProduct((void **)(void *)&arrayName, nElements, sizeof(arrayName[0]))
 
 #define REALLOCARRAY(arrayName, nElements) \
     reallocProduct((void **)&arrayName, nElements, sizeof(arrayName[0]))
--- other/pnmcolormap.c
+++ other/pnmcolormap.c
@@ -795,6 +795,7 @@
             pamP->width = intsqrt;
         else 
             pamP->width = intsqrt + 1;
+            overflow_add(intsqrt, 1);
     }
     {
         unsigned int const intQuotient = colormapSize / pamP->width;
--- urt/README
+++ urt/README
@@ -18,3 +18,8 @@
 defines stdout as a variable, so that wouldn't compile.  So I changed
 it to NULL and added a line to rle_hdr_init to set that field to
 'stdout' dynamically.  2000.06.02 BJH.
+
+Redid the code to check for maths overflows and other crawly horrors.
+Removed pipe through and compress support (unsafe)
+
+Alan Cox <alan@redhat.com>
--- urt/Runput.c
+++ urt/Runput.c
@@ -17,6 +17,8 @@
  *
  *  Modified at BRL 16-May-88 by Mike Muuss to avoid Alliant STDC desire
  *  to have all "void" functions so declared.
+ *
+ *  2002-12-19: Fix maths wrapping bugs. Alan Cox <alan@redhat.com>
  */
 /* 
  * Runput.c - General purpose Run Length Encoding.
@@ -200,9 +202,11 @@
     if ( the_hdr->background != 0 )
     {
 	register int i;
-	register rle_pixel *background =
-	    (rle_pixel *)malloc( (unsigned)(the_hdr->ncolors + 1) );
+	register rle_pixel *background;
 	register int *bg_color;
+
+	overflow_add(the_hdr->ncolors,1);
+	background = (rle_pixel *)malloc( (unsigned)(the_hdr->ncolors + 1) );
 	/* 
 	 * If even number of bg color bytes, put out one more to get to 
 	 * 16 bit boundary.
@@ -222,7 +226,7 @@
 	/* Big-endian machines are harder */
 	register int i, nmap = (1 << the_hdr->cmaplen) *
 			       the_hdr->ncmap;
-	register char *h_cmap = (char *)malloc( nmap * 2 );
+	register char *h_cmap = (char *)malloc2( nmap, 2 );
 	if ( h_cmap == NULL )
 	{
 	    fprintf( stderr,
--- urt/rle.h
+++ urt/rle.h
@@ -14,6 +14,9 @@
  * If you modify this software, you should include a notice giving the
  * name of the person performing the modification, the date of modification,
  * and the reason for such modification.
+ *
+ *  2002-12-19: Fix maths wrapping bugs. Alan Cox <alan@redhat.com>
+ *  Header declarations needed
  */
 /* 
  * rle.h - Global declarations for Utah Raster Toolkit RLE programs.
@@ -169,6 +172,16 @@
  */
 extern rle_hdr rle_dflt_hdr;
 
+/*
+ * Provided by pm library
+ */
+
+extern void overflow_add(int, int);
+extern void overflow2(int, int);
+extern void overflow3(int, int, int);
+extern void *malloc2(int, int);
+extern void *malloc3(int, int, int);
+extern void *realloc2(void *, int, int);
 
 /* Declare RLE library routines. */
 
--- urt/rle_addhist.c
+++ urt/rle_addhist.c
@@ -14,6 +14,8 @@
  * If you modify this software, you should include a notice giving the
  * name of the person performing the modification, the date of modification,
  * and the reason for such modification.
+ *
+ *  2002-12-19: Fix maths wrapping bugs. Alan Cox <alan@redhat.com>
  */
 /* 
  * rle_addhist.c - Add to the HISTORY comment in header
@@ -69,18 +71,29 @@
 
 	length=0;
 	for(i=0;argv[i];i++)
+	{
+		overflow_add(length, strlen(argv[i]));
+		overflow_add(length+1, strlen(argv[i]));
 		length+= strlen(argv[i]) +1;					/* length of each arg plus space. */
-
+	}
 	(void)time (&temp);
 	timedate=ctime(&temp);
 	length+= strlen(timedate);						/* length of date and time in ASCII. */
 
+	overflow_add(strlen(padding), 4);
+	overflow_add(strlen(padding) + 4, strlen(histoire));
+	overflow_add(length, strlen(padding) + 4 + strlen(histoire));
 	length+= strlen(padding) + 3 + strlen(histoire) + 1;			/* length of padding, "on "  and length of history name plus "="*/
 	if(in_hdr)								/* if we are interested in the old comments... */
 		old=rle_getcom(histoire,in_hdr);				/* get old comment. */
 
-	if((old) && (*old)) length+= strlen(old);				/* add length if there. */
+	if((old) && (*old))
+	{
+		overflow_add(length, strlen(old));
+		length+= strlen(old);				/* add length if there. */
+	}
 
+	overflow_add(length, 1);
 	length++;								/*Cater for the null. */
 
 	if((newc=(char *)malloc((unsigned int) length)) == NULL)return;
@@ -95,5 +108,4 @@
 	(void)strcat(newc,padding);							/* to line up multiple histories.*/
 
 	(void)rle_putcom(newc,out_hdr);
-
 }
--- urt/rle_getrow.c
+++ urt/rle_getrow.c
@@ -17,6 +17,8 @@
  *
  *  Modified at BRL 16-May-88 by Mike Muuss to avoid Alliant STDC desire
  *  to have all "void" functions so declared.
+ *
+ *  2002-12-19: Fix maths wrapping bugs. Alan Cox <alan@redhat.com>
  */
 /* 
  * rle_getrow.c - Read an RLE file in.
--- urt/rle_hdr.c
+++ urt/rle_hdr.c
@@ -14,6 +14,8 @@
  * If you modify this software, you should include a notice giving the
  * name of the person performing the modification, the date of modification,
  * and the reason for such modification.
+ *
+ *  2002-12-19: Fix maths wrapping bugs. Alan Cox <alan@redhat.com>
  */
 /* 
  * rle_hdr.c - Functions to manipulate rle_hdr structures.
@@ -77,7 +79,10 @@
     /* Fill in with copies of the strings. */
     if ( the_hdr->cmd != pgmname )
     {
-	char *tmp = (char *)malloc( strlen( pgmname ) + 1 );
+	char *tmp ;
+
+	overflow_add(strlen(pgmname), 1);
+	tmp = malloc( strlen( pgmname ) + 1 );
 	RLE_CHECK_ALLOC( pgmname, tmp, 0 );
 	strcpy( tmp, pgmname );
 	the_hdr->cmd = tmp;
@@ -85,7 +90,9 @@
 
     if ( the_hdr->file_name != fname )
     {
-	char *tmp = (char *)malloc( strlen( fname ) + 1 );
+	char *tmp;
+	overflow_add(strlen(fname), 1);
+	tmp = malloc( strlen( fname ) + 1 );
 	RLE_CHECK_ALLOC( pgmname, tmp, 0 );
 	strcpy( tmp, fname );
 	the_hdr->file_name = tmp;
@@ -150,6 +157,7 @@
     if ( to_hdr->bg_color )
     {
 	int size = to_hdr->ncolors * sizeof(int);
+	overflow2(to_hdr->ncolors, sizeof(int));
 	to_hdr->bg_color = (int *)malloc( size );
 	RLE_CHECK_ALLOC( to_hdr->cmd, to_hdr->bg_color, "background color" );
 	memcpy( to_hdr->bg_color, from_hdr->bg_color, size );
@@ -158,7 +166,7 @@
     if ( to_hdr->cmap )
     {
 	int size = to_hdr->ncmap * (1 << to_hdr->cmaplen) * sizeof(rle_map);
-	to_hdr->cmap = (rle_map *)malloc( size );
+	to_hdr->cmap = (rle_map *)malloc3( to_hdr->ncmap, 1<<to_hdr->cmaplen, sizeof(rle_map));
 	RLE_CHECK_ALLOC( to_hdr->cmd, to_hdr->cmap, "color map" );
 	memcpy( to_hdr->cmap, from_hdr->cmap, size );
     }
@@ -171,11 +179,16 @@
 	int size = 0;
 	CONST_DECL char **cp;
 	for ( cp=to_hdr->comments; *cp; cp++ )
+	{
+	    overflow_add(size, 1);
 	    size++;		/* Count the comments. */
+ 	}
 	/* Check if there are really any comments. */
 	if ( size )
 	{
+	    overflow_add(size, 1);
 	    size++;		/* Copy the NULL pointer, too. */
+	    overflow2(size, sizeof(char *));
 	    size *= sizeof(char *);
 	    to_hdr->comments = (CONST_DECL char **)malloc( size );
 	    RLE_CHECK_ALLOC( to_hdr->cmd, to_hdr->comments, "comments" );
--- urt/rle_open_f.c
+++ urt/rle_open_f.c
@@ -6,6 +6,9 @@
  * 		University of Michigan
  * Date:	11/14/89
  * Copyright (c) 1990, University of Michigan
+ *
+ *  2002-12-19: Fix maths wrapping bugs. Alan Cox <alan@redhat.com>
+ *  Killed of crazy unsafe pipe/compress stuff
  */
 
 #include "rle.h"
@@ -184,7 +187,7 @@
 	    
         cp = file_name + strlen( (char*) file_name ) - 2;
         /* Pipe case. */
-        if ( *file_name == '|' )
+        if ( *file_name == '|' && 0 /* BOLLOCKS ARE WE DOING THIS ANY MORE */)
         {
             int thepid;		/* PID from my_popen */
             if ( (fp = my_popen( file_name + 1, mode, &thepid )) == NULL )
@@ -199,9 +202,10 @@
         }
 
         /* Compress case. */
-        else if ( cp > file_name && *cp == '.' && *(cp + 1) == 'Z' )
+        else if (/* SMOKING SOMETHING */ 0 &&  cp > file_name && *cp == '.' && *(cp + 1) == 'Z' )
         {
             int thepid;		/* PID from my_popen. */
+	    overflow_add(20, strlen(file_name));
             combuf = (char *)malloc( 20 + strlen( file_name ) );
             if ( combuf == NULL )
             {
--- urt/rle_putcom.c
+++ urt/rle_putcom.c
@@ -14,6 +14,8 @@
  * If you modify this software, you should include a notice giving the
  * name of the person performing the modification, the date of modification,
  * and the reason for such modification.
+ *
+ *  2002-12-19: Fix maths wrapping bugs. Alan Cox <alan@redhat.com>
  */
 /* 
  * rle_putcom.c - Add a picture comment to the header struct.
@@ -89,19 +91,22 @@
 
     if ( the_hdr->comments == NULL )
     {
-	the_hdr->comments = (CONST_DECL char **)malloc( 2 * sizeof(char *) );
+	the_hdr->comments = (CONST_DECL char **)malloc2( 2, sizeof(char *) );
 	the_hdr->comments[0] = value;
 	the_hdr->comments[1] = NULL;
     }
     else
     {
 	for ( i = 2, cp = the_hdr->comments; *cp != NULL; i++, cp++ )
+	{
+	    overflow_add(i, 1);
 	    if ( match( value, *cp ) != NULL )
 	    {
 		v = *cp;
 		*cp = value;
 		return v;
 	    }
+	}
 	/* Not found */
 	/* Can't realloc because somebody else might be pointing to this
 	 * comments block.  Of course, if this were true, then the
@@ -111,7 +116,7 @@
 	 * could copy the pointers, too.
 	 */
 	old_comments = the_hdr->comments;
-	the_hdr->comments = (CONST_DECL char **)malloc(i * sizeof(char *) );
+	the_hdr->comments = (CONST_DECL char **)malloc2(i , sizeof(char *) );
 	the_hdr->comments[--i] = NULL;
 	the_hdr->comments[--i] = value;
 	for ( i--; i >= 0; i-- )
--- urt/scanargs.c
+++ urt/scanargs.c
@@ -38,6 +38,8 @@
  *
  *  Modified at BRL 16-May-88 by Mike Muuss to avoid Alliant STDC desire
  *  to have all "void" functions so declared.
+ *
+ *  2002-12-19: Fix maths wrapping bugs. Alan Cox <alan@redhat.com>
  */
 
 #include "rle.h"
@@ -65,8 +67,8 @@
 /* 
  * Storage allocation macros
  */
-#define NEW( type, cnt )	(type *) malloc( (cnt) * sizeof( type ) )
-#define RENEW( type, ptr, cnt )	(type *) realloc( ptr, (cnt) * sizeof( type ) )
+#define NEW( type, cnt )	(type *) malloc2( (cnt) , sizeof( type ) )
+#define RENEW( type, ptr, cnt )	(type *) realloc2( ptr, (cnt), sizeof( type ) )
 
 #if defined(c_plusplus) && !defined(USE_PROTOTYPES)
 #define USE_PROTOTYPES
