about summary refs log tree commit diff
path: root/converter/pgm
diff options
context:
space:
mode:
authorgiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2010-03-02 21:55:18 +0000
committergiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2010-03-02 21:55:18 +0000
commitbf76a94423bbb9f4fb66ffea261f677702e0d4f4 (patch)
tree4e958d9c00851af13a0beabd03d3b3ad09639ef2 /converter/pgm
parente509cd6d53d19162754cc73485e3435051557952 (diff)
downloadnetpbm-mirror-bf76a94423bbb9f4fb66ffea261f677702e0d4f4.tar.gz
netpbm-mirror-bf76a94423bbb9f4fb66ffea261f677702e0d4f4.tar.xz
netpbm-mirror-bf76a94423bbb9f4fb66ffea261f677702e0d4f4.zip
Fix arithmetic overflow with image dimensions represented by 16 bit integers
git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@1136 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'converter/pgm')
-rw-r--r--converter/pgm/pgmtolispm.c171
1 files changed, 90 insertions, 81 deletions
diff --git a/converter/pgm/pgmtolispm.c b/converter/pgm/pgmtolispm.c
index abb85494..4da9ae88 100644
--- a/converter/pgm/pgmtolispm.c
+++ b/converter/pgm/pgmtolispm.c
@@ -14,82 +14,62 @@
 **   usually a color image; but a color map is not written in the file, so we
 **   treat this as a graymap instead.  To convert a color image to Lispm 
 **   format, you must convert it to a pgm, and hand-edit a color map...  Ick.
+**
+** Feb 2010 afu
+** Added dimension check to prevent short int from overflowing
+** Changed code style (ANSI-style function definitions, etc.)
 */
 
 #include <stdio.h>
 #include "pgm.h"
 
 #define LISPM_MAGIC  "This is a BitMap file"
+#define INT16MAX 32767
 
-static void putinit ARGS(( int cols, int rows, int depth ));
-static int depth_to_word_size ARGS(( int depth ));
-static void putval ARGS(( gray b ));
-static void putrest ARGS(( void ));
-static void putitem ARGS(( void ));
-
-int
-main( argc, argv )
-    int argc;
-    char* argv[];
-    {
-    FILE* ifp;
-    gray *grayrow;
-    register gray* gP;
-    int rows, cols, depth, format, padright, row, col;
-    gray maxval;
-
-
-    pgm_init( &argc, argv );
-
-    if ( argc > 2 )
-	pm_usage( "[pgmfile]" );
-    if ( argc == 2 )
-	ifp = pm_openr( argv[1] );
-    else
-	ifp = stdin;
-
-    pgm_readpgminit( ifp, &cols, &rows, &maxval, &format );
-    grayrow = pgm_allocrow( cols );
-    depth = pm_maxvaltobits( maxval );
-
-    /* Compute padding to round cols up to the nearest multiple of 32. */
-    padright = ( ( cols + 31 ) / 32 ) * 32 - cols;
-
-    putinit( cols, rows, depth );
-    for ( row = 0; row < rows; ++row )
-	{
-	pgm_readpgmrow( ifp, grayrow, cols, maxval, format );
-        for ( col = 0, gP = grayrow; col < cols; ++col, ++gP )
-	    putval( *gP );
-	for ( col = 0; col < padright; ++col )
-	    putval( 0 );
-        }
-
-    pm_close( ifp );
-
-    putrest( );
-
-    exit( 0 );
-    }
 
 static unsigned int item;
 static unsigned int bitsperitem, maxbitsperitem, bitshift;
 
+static int
+depth_to_word_size (int const depth) {
+/* Lispm architecture specific - if a bitmap is written    */
+/* out with a depth of 5, it really has a depth of 8, and  */
+/* is stored that way in the file.                         */
+
+    if (depth==0 || depth==1)   return ( 1);
+    else if (depth ==  2)       return ( 2);
+    else if (depth <=  4)       return ( 4);
+    else if (depth <=  8)       return ( 8);
+    else if (depth <= 16)       return (16);
+    else if (depth <= 32)       return (32);
+    else {
+      pm_error( "depth was %d, which is not in the range 1-32", depth );
+      return(-1);  /* Should never reach here */
+  }
+}
+
+
 static void
-putinit( cols, rows, depth )
-    int cols, rows, depth;
+putinit( int const cols, int const rows, int const depth )
     {
     int i;
-    int cols32 = ( ( cols + 31 ) / 32 ) * 32;	/* Lispms are able to write bit files that are not mod32 wide, but we   */
-						/* don't.  This should be ok, since bit arrays which are not mod32 wide */
-    printf(LISPM_MAGIC);			/* are pretty useless on a lispm (can't hand them to bitblt).		*/
+    int const cols32 = ( ( cols + 31 ) / 32 ) * 32;
+  /* Lispms are able to write bit files that are not mod32 wide, but we   */
+  /* don't.  This should be ok, since bit arrays which are not mod32 wide */
+  /* are pretty useless on a lispm (can't hand them to bitblt).           */
+
+    if( rows>INT16MAX || cols>INT16MAX || cols32>INT16MAX )
+      pm_error ("Input image is too large.");
+
+    printf(LISPM_MAGIC);
+
     pm_writelittleshort( stdout, cols );
     pm_writelittleshort( stdout, rows );
     pm_writelittleshort( stdout, cols32 );
     putchar(depth & 0xFF);
 
     for ( i = 0; i < 9; ++i )
-	putchar( 0 );	/* pad bytes */
+        putchar( 0 );   /* pad bytes */
 
     item = 0;
     bitsperitem = 0;
@@ -97,46 +77,75 @@ putinit( cols, rows, depth )
     bitshift = 0;
     }
 
-static int
-depth_to_word_size (depth)	/* Lispm architecture specific - if a bitmap is written    */
-  int depth;			/* out with a depth of 5, it really has a depth of 8, and  */
-{				/* is stored that way in the file.			   */
-    if (depth==0 || depth==1)	return ( 1);
-    else if (depth ==  2)	return ( 2);
-    else if (depth <=  4)	return ( 4);
-    else if (depth <=  8)	return ( 8);
-    else if (depth <= 16)	return (16);
-    else if (depth <= 32)	return (32);
-    else {
-      pm_error( "depth was %d, which is not in the range 1-32", depth );
-      return(-1);  /* Should never reach here */
-  }
-}
-
+static void
+putitem( )
+    {
+    pm_writelittlelong( stdout, ~item );
+    item = 0;
+    bitsperitem = 0;
+    bitshift = 0;
+    }
 
 
 static void
-putval( gray b )
+putval( gray const b )
     {
     if ( bitsperitem == 32 )
-	putitem( );
+        putitem( );
     item = item | ( b << bitshift );
     bitsperitem = bitsperitem + maxbitsperitem;
     bitshift = bitshift + maxbitsperitem;
     }
 
+
+
 static void
 putrest( )
     {
     if ( bitsperitem > 0 )
-	putitem( );
+        putitem( );
     }
 
-static void
-putitem( )
+
+int
+main( int argc, char * argv[] )
     {
-    pm_writelittlelong( stdout, ~item );
-    item = 0;
-    bitsperitem = 0;
-    bitshift = 0;
+    FILE* ifp;
+    gray *grayrow;
+    register gray* gP;
+    int rows, cols, depth, format, padright, row, col;
+    gray maxval;
+
+
+    pgm_init( &argc, argv );
+
+    if ( argc > 2 )
+        pm_usage( "[pgmfile]" );
+    if ( argc == 2 )
+        ifp = pm_openr( argv[1] );
+    else
+        ifp = stdin;
+
+    pgm_readpgminit( ifp, &cols, &rows, &maxval, &format );
+    grayrow = pgm_allocrow( cols );
+    depth = pm_maxvaltobits( maxval );
+
+    /* Compute padding to round cols up to the nearest multiple of 32. */
+    padright = ( ( cols + 31 ) / 32 ) * 32 - cols;
+
+    putinit( cols, rows, depth );
+    for ( row = 0; row < rows; ++row )
+        {
+        pgm_readpgmrow( ifp, grayrow, cols, maxval, format );
+        for ( col = 0, gP = grayrow; col < cols; ++col, ++gP )
+            putval( *gP );
+        for ( col = 0; col < padright; ++col )
+            putval( 0 );
+        }
+
+    pm_close( ifp );
+
+    putrest( );
+
+    exit( 0 );
     }