Upstream-Status: Backport Signed-off-by: Yue Tao Signed-off-by: Wenzong Fan Index: tools/ppm2tiff.c =================================================================== RCS file: /cvs/maptools/cvsroot/libtiff/tools/ppm2tiff.c,v retrieving revision 1.16 retrieving revision 1.18 diff -u -r1.16 -r1.18 --- a/tools/ppm2tiff.c 10 Apr 2010 19:22:34 -0000 1.16 +++ b/tools/ppm2tiff.c 10 Dec 2012 18:19:11 -0000 1.18 @@ -1,4 +1,4 @@ -/* $Id: ppm2tiff.c,v 1.16 2010-04-10 19:22:34 bfriesen Exp $ */ +/* $Id: ppm2tiff.c,v 1.18 2012-12-10 18:19:11 tgl Exp $ */ /* * Copyright (c) 1991-1997 Sam Leffler @@ -72,6 +72,17 @@ exit(-2); } +static tmsize_t +multiply_ms(tmsize_t m1, tmsize_t m2) +{ + tmsize_t bytes = m1 * m2; + + if (m1 && bytes / m1 != m2) + bytes = 0; + + return bytes; +} + int main(int argc, char* argv[]) { @@ -79,7 +90,7 @@ uint32 rowsperstrip = (uint32) -1; double resolution = -1; unsigned char *buf = NULL; - tsize_t linebytes = 0; + tmsize_t linebytes = 0; uint16 spp = 1; uint16 bpp = 8; TIFF *out; @@ -89,6 +100,7 @@ int c; extern int optind; extern char* optarg; + tmsize_t scanline_size; if (argc < 2) { fprintf(stderr, "%s: Too few arguments\n", argv[0]); @@ -221,7 +233,8 @@ } switch (bpp) { case 1: - linebytes = (spp * w + (8 - 1)) / 8; + /* if round-up overflows, result will be zero, OK */ + linebytes = (multiply_ms(spp, w) + (8 - 1)) / 8; if (rowsperstrip == (uint32) -1) { TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, h); } else { @@ -230,15 +243,31 @@ } break; case 8: - linebytes = spp * w; + linebytes = multiply_ms(spp, w); TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(out, rowsperstrip)); break; } - if (TIFFScanlineSize(out) > linebytes) + if (linebytes == 0) { + fprintf(stderr, "%s: scanline size overflow\n", infile); + (void) TIFFClose(out); + exit(-2); + } + scanline_size = TIFFScanlineSize(out); + if (scanline_size == 0) { + /* overflow - TIFFScanlineSize already printed a message */ + (void) TIFFClose(out); + exit(-2); + } + if (scanline_size < linebytes) buf = (unsigned char *)_TIFFmalloc(linebytes); else - buf = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(out)); + buf = (unsigned char *)_TIFFmalloc(scanline_size); + if (buf == NULL) { + fprintf(stderr, "%s: Not enough memory\n", infile); + (void) TIFFClose(out); + exit(-2); + } if (resolution > 0) { TIFFSetField(out, TIFFTAG_XRESOLUTION, resolution); TIFFSetField(out, TIFFTAG_YRESOLUTION, resolution);