From baaf2d79c0e44c6ab399062fe417105acd932472 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Thu, 23 Apr 2015 21:56:40 +0000 Subject: Fix buffer overflow git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@2466 9d0c8265-081b-0410-96cb-a4ca84ce46f8 --- converter/ppm/ppmtorgb3.c | 197 ++++++++++++++++++++++++++++------------------ doc/HISTORY | 2 + 2 files changed, 123 insertions(+), 76 deletions(-) diff --git a/converter/ppm/ppmtorgb3.c b/converter/ppm/ppmtorgb3.c index 21d3346a..3d2f1c21 100644 --- a/converter/ppm/ppmtorgb3.c +++ b/converter/ppm/ppmtorgb3.c @@ -1,4 +1,4 @@ -/* ppmtorgb3.c - separate a portable pixmap into three portable graymaps +/* ppmtorgb3.c - separate a PPM image into 3 PGM images. ** ** Copyright (C) 1991 by Jef Poskanzer. ** @@ -11,89 +11,134 @@ */ #include +#include "pm_c_util.h" +#include "mallocvar.h" +#include "nstring.h" #include "ppm.h" #include "pgm.h" -int -main( argc, argv ) - int argc; - char* argv[]; + + +struct Cmdline { + const char * inputFileName; +}; + + + +static const char * +strippedOfExtension(const char * const arg) { + + char * buffer; + + MALLOCARRAY(buffer, strlen(arg) + 1); + + strcpy(buffer, arg); + { - FILE* ifp; - FILE* redfile; - FILE* grnfile; - FILE* blufile; - const char* basename; - char filename[100]; - char* cp; - pixel* pixelrow; - register pixel* pP; - gray* grayrow; - register gray* gP; - int rows, cols, format, row; - register int col; + char * const dotPos = strrchr(buffer, '.'); + if (dotPos) + *dotPos = '\0'; + } + return buffer; +} + + + +static void +openComponentOut(const char * const suffix, + const char * const baseName, + FILE ** const fpP) { + + const char * fileName; + + pm_asprintf(&fileName, "%s.%s", baseName, suffix); + + *fpP = pm_openw(fileName); + + pm_strfree(fileName); +} + + + +int +main(int argc, const char ** argv) { + + FILE * ifP; + FILE * redfP; + FILE * grnfP; + FILE * blufP; + pixel * pixelrow; + gray * grayrow; + int rows, cols; + int format; + unsigned int row; pixval maxval; + struct Cmdline cmdline; + const char * baseFileName; + + pm_proginit(&argc, argv); + if (argc-1 > 1) + pm_error("Too many arguments (%u). The only possible argument " + "is the input file name", argc-1); - ppm_init( &argc, argv ); + if (argc-1 < 1) + cmdline.inputFileName = "-"; + else + cmdline.inputFileName = argv[1]; - if ( argc > 2 ) - pm_usage( "[ppmfile]" ); + ifP = pm_openr(cmdline.inputFileName); - if ( argc == 2 ) - { - ifp = pm_openr( argv[1] ); - basename = argv[1]; - cp = strrchr( basename, '.' ); - if ( cp != NULL ) - *cp = '\0'; - } + if (streq(cmdline.inputFileName, "-")) + baseFileName = strdup("noname"); else - { - ifp = stdin; - basename = "noname"; - } - - ppm_readppminit( ifp, &cols, &rows, &maxval, &format ); - pixelrow = ppm_allocrow( cols ); - (void) strcpy( filename, basename ); - (void) strcat( filename, ".red" ); - redfile = pm_openw( filename ); - pgm_writepgminit( redfile, cols, rows, (gray) maxval, 0 ); - (void) strcpy( filename, basename ); - (void) strcat( filename, ".grn" ); - grnfile = pm_openw( filename ); - pgm_writepgminit( grnfile, cols, rows, (gray) maxval, 0 ); - (void) strcpy( filename, basename ); - (void) strcat( filename, ".blu" ); - blufile = pm_openw( filename ); - pgm_writepgminit( blufile, cols, rows, (gray) maxval, 0 ); - grayrow = pgm_allocrow( cols ); - - for ( row = 0; row < rows; ++row ) - { - ppm_readppmrow( ifp, pixelrow, cols, maxval, format ); - - for ( col = 0, pP = pixelrow, gP = grayrow; col < cols; - ++col, ++pP, ++gP ) - *gP = (gray) PPM_GETR( *pP ); - pgm_writepgmrow( redfile, grayrow, cols, maxval, 0 ); - - for ( col = 0, pP = pixelrow, gP = grayrow; col < cols; - ++col, ++pP, ++gP ) - *gP = (gray) PPM_GETG( *pP ); - pgm_writepgmrow( grnfile, grayrow, cols, maxval, 0 ); - - for ( col = 0, pP = pixelrow, gP = grayrow; col < cols; - ++col, ++pP, ++gP ) - *gP = (gray) PPM_GETB( *pP ); - pgm_writepgmrow( blufile, grayrow, cols, maxval, 0 ); - } - - pm_close( ifp ); - pm_close( redfile ); - pm_close( blufile ); - pm_close( grnfile ); - - exit( 0 ); + baseFileName = strippedOfExtension(cmdline.inputFileName); + + ppm_readppminit(ifP, &cols, &rows, &maxval, &format); + + pixelrow = ppm_allocrow(cols); + + openComponentOut("red", baseFileName, &redfP); + openComponentOut("grn", baseFileName, &grnfP); + openComponentOut("blu", baseFileName, &blufP); + + pgm_writepgminit(redfP, cols, rows, maxval, 0); + pgm_writepgminit(grnfP, cols, rows, maxval, 0); + pgm_writepgminit(blufP, cols, rows, maxval, 0); + + grayrow = pgm_allocrow(cols); + + for (row = 0; row < rows; ++row) { + unsigned int col; + + ppm_readppmrow(ifP, pixelrow, cols, maxval, format); + + for (col = 0; col < cols; ++col) + grayrow[col] = PPM_GETR(pixelrow[col]); + + pgm_writepgmrow(redfP, grayrow, cols, maxval, 0); + + for (col = 0; col < cols; ++col) + grayrow[col] = PPM_GETG(pixelrow[col]); + + pgm_writepgmrow(grnfP, grayrow, cols, maxval, 0); + + for (col = 0; col < cols; ++col) + grayrow[col] = PPM_GETB(pixelrow[col]); + + pgm_writepgmrow(blufP, grayrow, cols, maxval, 0); } + + pgm_freerow(grayrow); + ppm_freerow(pixelrow); + pm_strfree(baseFileName); + pm_close(ifP); + pm_close(blufP); + pm_close(grnfP); + pm_close(redfP); + + return 0; +} + + + diff --git a/doc/HISTORY b/doc/HISTORY index ff6f6f27..04724125 100644 --- a/doc/HISTORY +++ b/doc/HISTORY @@ -6,6 +6,8 @@ CHANGE HISTORY not yet BJH Release 10.71.00 + ppmtorgb3: Fix buffer overflow with long input file name. + ppmtoarbtxt: fix bug: wrong output when high numbers represent darker. Broken in Netpbm 10.69 (November 2014). -- cgit 1.4.1