diff options
author | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2010-03-02 21:55:18 +0000 |
---|---|---|
committer | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2010-03-02 21:55:18 +0000 |
commit | bf76a94423bbb9f4fb66ffea261f677702e0d4f4 (patch) | |
tree | 4e958d9c00851af13a0beabd03d3b3ad09639ef2 /converter/pgm | |
parent | e509cd6d53d19162754cc73485e3435051557952 (diff) | |
download | netpbm-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.c | 171 |
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 ); } |