diff --git a/ChangeLog b/ChangeLog index 57f483fc..9513bc7a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,13 @@ 2015-05-28 Bob Friesenhahn + * tools/bmp2tiff.c (main): Fix Coverity 1024225 "Untrusted value + as argument". + (main): Fix Coverity 1024678 "Unchecked return value from + library". + (main): Fix Coverity 1024679 "Unchecked return value from + library". + (main): Fix Coverity 1214160 "Ignoring number of bytes read". + * contrib/addtiffo/tif_ovrcache.c (TIFFCreateOvrCache): Fix Coverity 298615 "Resource leak". diff --git a/tools/bmp2tiff.c b/tools/bmp2tiff.c index 48fcdc2a..d6c914de 100644 --- a/tools/bmp2tiff.c +++ b/tools/bmp2tiff.c @@ -1,4 +1,4 @@ -/* $Id: bmp2tiff.c,v 1.24 2014-12-21 15:15:32 erouault Exp $ +/* $Id: bmp2tiff.c,v 1.25 2015-05-29 02:37:56 bfriesen Exp $ * * Project: libtiff tools * Purpose: Convert Windows BMP files in TIFF. @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -291,29 +292,50 @@ main(int argc, char* argv[]) return -1; } - read(fd, file_hdr.bType, 2); + if (read(fd, file_hdr.bType, 2) != 2) { + TIFFError(infilename, "Failed to read from file (%s)", + strerror(errno)); + goto bad; + } if(file_hdr.bType[0] != 'B' || file_hdr.bType[1] != 'M') { TIFFError(infilename, "File is not BMP"); goto bad; } -/* -------------------------------------------------------------------- */ -/* Read the BMPFileHeader. We need iOffBits value only */ -/* -------------------------------------------------------------------- */ - lseek(fd, 10, SEEK_SET); - read(fd, &file_hdr.iOffBits, 4); + /* -------------------------------------------------------------------- */ + /* Read the BMPFileHeader. We need iOffBits value only */ + /* -------------------------------------------------------------------- */ + if (lseek(fd, 10, SEEK_SET) == (off_t)-1) { + TIFFError(infilename, "Failed to seek to offset"); + goto bad; + } + if (read(fd, &file_hdr.iOffBits, 4) != 4) { + TIFFError(infilename, "Failed to read from file (%s)", + strerror(errno)); + goto bad; + } #ifdef WORDS_BIGENDIAN TIFFSwabLong(&file_hdr.iOffBits); #endif - fstat(fd, &instat); + if (fstat(fd, &instat) == -1) { + TIFFError(infilename, "Failed obtain file information"); + goto bad; + } file_hdr.iSize = instat.st_size; -/* -------------------------------------------------------------------- */ -/* Read the BMPInfoHeader. */ -/* -------------------------------------------------------------------- */ + /* -------------------------------------------------------------------- */ + /* Read the BMPInfoHeader. */ + /* -------------------------------------------------------------------- */ - lseek(fd, BFH_SIZE, SEEK_SET); - read(fd, &info_hdr.iSize, 4); + if (lseek(fd, BFH_SIZE, SEEK_SET) == (off_t)-1) { + TIFFError(infilename, "Failed to seek to offset"); + goto bad; + } + if (read(fd, &info_hdr.iSize, 4) != 4) { + TIFFError(infilename, "Failed to read from file (%s)", + strerror(errno)); + goto bad; + } #ifdef WORDS_BIGENDIAN TIFFSwabLong(&info_hdr.iSize); #endif @@ -331,16 +353,20 @@ main(int argc, char* argv[]) if (bmp_type == BMPT_WIN4 || bmp_type == BMPT_WIN5 || bmp_type == BMPT_OS22) { - read(fd, &info_hdr.iWidth, 4); - read(fd, &info_hdr.iHeight, 4); - read(fd, &info_hdr.iPlanes, 2); - read(fd, &info_hdr.iBitCount, 2); - read(fd, &info_hdr.iCompression, 4); - read(fd, &info_hdr.iSizeImage, 4); - read(fd, &info_hdr.iXPelsPerMeter, 4); - read(fd, &info_hdr.iYPelsPerMeter, 4); - read(fd, &info_hdr.iClrUsed, 4); - read(fd, &info_hdr.iClrImportant, 4); + if ((read(fd, &info_hdr.iWidth, 4) != 4) || + (read(fd, &info_hdr.iHeight, 4) != 4) || + (read(fd, &info_hdr.iPlanes, 2) != 2) || + (read(fd, &info_hdr.iBitCount, 2) != 2) || + (read(fd, &info_hdr.iCompression, 4) != 4) || + (read(fd, &info_hdr.iSizeImage, 4) != 4) || + (read(fd, &info_hdr.iXPelsPerMeter, 4) != 4) || + (read(fd, &info_hdr.iYPelsPerMeter, 4) != 4) || + (read(fd, &info_hdr.iClrUsed, 4) != 4) || + (read(fd, &info_hdr.iClrImportant, 4) != 4)) { + TIFFError(infilename, "Failed to read from file (%s)", + strerror(errno)); + goto bad; + } #ifdef WORDS_BIGENDIAN TIFFSwabLong((uint32*) &info_hdr.iWidth); TIFFSwabLong((uint32*) &info_hdr.iHeight); @@ -361,28 +387,44 @@ main(int argc, char* argv[]) * FIXME: different info in different documents * regarding this! */ - n_clr_elems = 3; + n_clr_elems = 3; } if (bmp_type == BMPT_OS21) { int16 iShort; - read(fd, &iShort, 2); + if ( read(fd, &iShort, 2) != 2 ) { + TIFFError(infilename, "Failed to read from file (%s)", + strerror(errno)); + goto bad; + } #ifdef WORDS_BIGENDIAN TIFFSwabShort((uint16*) &iShort); #endif info_hdr.iWidth = iShort; - read(fd, &iShort, 2); + if ( read(fd, &iShort, 2) != 2 ) { + TIFFError(infilename, "Failed to read from file (%s)", + strerror(errno)); + goto bad; + } #ifdef WORDS_BIGENDIAN TIFFSwabShort((uint16*) &iShort); #endif info_hdr.iHeight = iShort; - read(fd, &iShort, 2); + if (read(fd, &iShort, 2) != 2 ) { + TIFFError(infilename, "Failed to read from file (%s)", + strerror(errno)); + goto bad; + } #ifdef WORDS_BIGENDIAN TIFFSwabShort((uint16*) &iShort); #endif info_hdr.iPlanes = iShort; - read(fd, &iShort, 2); + if ( read(fd, &iShort, 2) != 2 ) { + TIFFError(infilename, "Failed to read from file (%s)", + strerror(errno)); + goto bad; + } #ifdef WORDS_BIGENDIAN TIFFSwabShort((uint16*) &iShort); #endif @@ -394,25 +436,25 @@ main(int argc, char* argv[]) if (info_hdr.iBitCount != 1 && info_hdr.iBitCount != 4 && info_hdr.iBitCount != 8 && info_hdr.iBitCount != 16 && info_hdr.iBitCount != 24 && info_hdr.iBitCount != 32) { - TIFFError(infilename, - "Cannot process BMP file with bit count %d", - info_hdr.iBitCount); - close(fd); - return 0; + TIFFError(infilename, + "Cannot process BMP file with bit count %d", + info_hdr.iBitCount); + close(fd); + return 0; } width = info_hdr.iWidth; length = (info_hdr.iHeight > 0) ? info_hdr.iHeight : -info_hdr.iHeight; - if( width <= 0 || length <= 0 ) - { - TIFFError(infilename, - "Invalid dimensions of BMP file" ); - close(fd); - return -1; - } + if( width <= 0 || length <= 0 ) + { + TIFFError(infilename, + "Invalid dimensions of BMP file" ); + close(fd); + return -1; + } switch (info_hdr.iBitCount) - { + { case 1: case 4: case 8: @@ -421,28 +463,36 @@ main(int argc, char* argv[]) photometric = PHOTOMETRIC_PALETTE; /* Allocate memory for colour table and read it. */ if (info_hdr.iClrUsed) - clr_tbl_size = - ((uint32)(1< ((uint32) ~0) >> 1) || + (uncompr_size == 0) || + (uncompr_size > ((uint32) ~0) >> 1) ) { + TIFFError(infilename, + "Invalid dimensions of BMP file" ); + close(fd); + return -1; + } comprbuf = (unsigned char *) _TIFFmalloc( compr_size ); if (!comprbuf) { TIFFError(infilename, - "Can't allocate space for compressed scanline buffer"); + "Can't allocate space for compressed scanline buffer"); goto bad3; } uncomprbuf = (unsigned char *)_TIFFmalloc(uncompr_size); if (!uncomprbuf) { TIFFError(infilename, - "Can't allocate space for uncompressed scanline buffer"); + "Can't allocate space for uncompressed scanline buffer"); goto bad3; } - lseek(fd, file_hdr.iOffBits, SEEK_SET); - read(fd, comprbuf, compr_size); + if (lseek(fd, file_hdr.iOffBits, SEEK_SET) == (off_t)-1) { + TIFFError(infilename, "Failed to seek to offset"); + goto bad3; + } + if ( read(fd, comprbuf, compr_size) != (long) compr_size ) { + TIFFError(infilename, "Failed to read from file (%s)", + strerror(errno)); + goto bad; + } i = 0; j = 0; if (info_hdr.iBitCount == 8) { /* RLE8 */ - while(j < uncompr_size && i < compr_size) { - if ( comprbuf[i] ) { - runlength = comprbuf[i++]; - while( runlength > 0 - && j < uncompr_size - && i < compr_size ) { - uncomprbuf[j++] = comprbuf[i]; - runlength--; - } - i++; - } else { - i++; - if (comprbuf[i] == 0) /* Next scanline */ - i++; - else if (comprbuf[i] == 1) /* End of image */ - break; - else if (comprbuf[i] == 2) { /* Move to... */ - i++; - if (i < compr_size - 1) { - j+=comprbuf[i]+comprbuf[i+1]*width; - i += 2; - } - else - break; - } else { /* Absolute mode */ - runlength = comprbuf[i++]; - for (k = 0; k < runlength && j < uncompr_size && i < compr_size; k++) - uncomprbuf[j++] = comprbuf[i++]; - if ( k & 0x01 ) - i++; - } - } - } + while(j < uncompr_size && i < compr_size) { + if ( comprbuf[i] ) { + runlength = comprbuf[i++]; + while( runlength > 0 + && j < uncompr_size + && i < compr_size ) { + uncomprbuf[j++] = comprbuf[i]; + runlength--; + } + i++; + } else { + i++; + if (comprbuf[i] == 0) /* Next scanline */ + i++; + else if (comprbuf[i] == 1) /* End of image */ + break; + else if (comprbuf[i] == 2) { /* Move to... */ + i++; + if (i < compr_size - 1) { + j+=comprbuf[i]+comprbuf[i+1]*width; + i += 2; + } + else + break; + } else { /* Absolute mode */ + runlength = comprbuf[i++]; + for (k = 0; k < runlength && j < uncompr_size && i < compr_size; k++) + uncomprbuf[j++] = comprbuf[i++]; + if ( k & 0x01 ) + i++; + } + } + } } else { /* RLE4 */ - while( j < uncompr_size && i < compr_size ) { - if ( comprbuf[i] ) { - runlength = comprbuf[i++]; - while( runlength > 0 && j < uncompr_size && i < compr_size ) { - if ( runlength & 0x01 ) - uncomprbuf[j++] = (comprbuf[i] & 0xF0) >> 4; - else - uncomprbuf[j++] = comprbuf[i] & 0x0F; - runlength--; - } - i++; - } else { - i++; - if (comprbuf[i] == 0) /* Next scanline */ - i++; - else if (comprbuf[i] == 1) /* End of image */ - break; - else if (comprbuf[i] == 2) { /* Move to... */ - i++; - if (i < compr_size - 1) { - j+=comprbuf[i]+comprbuf[i+1]*width; - i += 2; - } - else - break; - } else { /* Absolute mode */ - runlength = comprbuf[i++]; - for (k = 0; k < runlength && j < uncompr_size && i < compr_size; k++) { - if (k & 0x01) - uncomprbuf[j++] = comprbuf[i++] & 0x0F; - else - uncomprbuf[j++] = (comprbuf[i] & 0xF0) >> 4; - } - if (k & 0x01) - i++; - } - } - } + while( j < uncompr_size && i < compr_size ) { + if ( comprbuf[i] ) { + runlength = comprbuf[i++]; + while( runlength > 0 && j < uncompr_size && i < compr_size ) { + if ( runlength & 0x01 ) + uncomprbuf[j++] = (comprbuf[i] & 0xF0) >> 4; + else + uncomprbuf[j++] = comprbuf[i] & 0x0F; + runlength--; + } + i++; + } else { + i++; + if (comprbuf[i] == 0) /* Next scanline */ + i++; + else if (comprbuf[i] == 1) /* End of image */ + break; + else if (comprbuf[i] == 2) { /* Move to... */ + i++; + if (i < compr_size - 1) { + j+=comprbuf[i]+comprbuf[i+1]*width; + i += 2; + } + else + break; + } else { /* Absolute mode */ + runlength = comprbuf[i++]; + for (k = 0; k < runlength && j < uncompr_size && i < compr_size; k++) { + if (k & 0x01) + uncomprbuf[j++] = comprbuf[i++] & 0x0F; + else + uncomprbuf[j++] = (comprbuf[i] & 0xF0) >> 4; + } + if (k & 0x01) + i++; + } + } + } } _TIFFfree(comprbuf); for (row = 0; row < length; row++) { if (TIFFWriteScanline(out, - uncomprbuf + (length - row - 1) * width, - row, 0) < 0) { + uncomprbuf + (length - row - 1) * width, + row, 0) < 0) { TIFFError(infilename, - "scanline %lu: Write error.\n", + "scanline %lu: Write error.\n", (unsigned long) row); } } @@ -717,29 +782,29 @@ main(int argc, char* argv[]) } TIFFWriteDirectory(out); if (blue_tbl) { - _TIFFfree(blue_tbl); - blue_tbl=NULL; + _TIFFfree(blue_tbl); + blue_tbl=NULL; } if (green_tbl) { - _TIFFfree(green_tbl); - green_tbl=NULL; + _TIFFfree(green_tbl); + green_tbl=NULL; } if (red_tbl) { - _TIFFfree(red_tbl); - red_tbl=NULL; + _TIFFfree(red_tbl); + red_tbl=NULL; } } -bad3: + bad3: if (blue_tbl) _TIFFfree(blue_tbl); -bad2: + bad2: if (green_tbl) _TIFFfree(green_tbl); -bad1: + bad1: if (red_tbl) _TIFFfree(red_tbl); -bad: + bad: close(fd); if (out)