diff --git a/Makefile.am b/Makefile.am index fa8bf4c..418a3b9 100644 --- a/Makefile.am +++ b/Makefile.am @@ -25,7 +25,7 @@ docdir = $(LIBTIFF_DOCDIR) -AUTOMAKE_OPTIONS = 1.11 dist-zip foreign +AUTOMAKE_OPTIONS = 1.12 dist-zip foreign ACLOCAL_AMFLAGS = -I m4 docfiles = \ diff --git a/contrib/addtiffo/tif_overview.c b/contrib/addtiffo/tif_overview.c index 03b3573..c61ffbb 100644 --- a/contrib/addtiffo/tif_overview.c +++ b/contrib/addtiffo/tif_overview.c @@ -65,8 +65,6 @@ # define MAX(a,b) ((a>b) ? a : b) #endif -#define TIFF_DIR_MAX 65534 - void TIFFBuildOverviews( TIFF *, int, int *, int, const char *, int (*)(double,void*), void * ); @@ -93,7 +91,6 @@ uint32 TIFF_WriteOverview( TIFF *hTIFF, uint32 nXSize, uint32 nYSize, { toff_t nBaseDirOffset; toff_t nOffset; - tdir_t iNumDir; (void) bUseSubIFDs; @@ -150,16 +147,7 @@ uint32 TIFF_WriteOverview( TIFF *hTIFF, uint32 nXSize, uint32 nYSize, return 0; TIFFWriteDirectory( hTIFF ); - iNumDir = TIFFNumberOfDirectories(hTIFF); - if( iNumDir > TIFF_DIR_MAX ) - { - TIFFErrorExt( TIFFClientdata(hTIFF), - "TIFF_WriteOverview", - "File `%s' has too many directories.\n", - TIFFFileName(hTIFF) ); - exit(-1); - } - TIFFSetDirectory( hTIFF, (tdir_t) (iNumDir - 1) ); + TIFFSetDirectory( hTIFF, (tdir_t) (TIFFNumberOfDirectories(hTIFF)-1) ); nOffset = TIFFCurrentDirOffset( hTIFF ); diff --git a/html/man/Makefile.am b/html/man/Makefile.am index 8a64925..3ed00d4 100644 --- a/html/man/Makefile.am +++ b/html/man/Makefile.am @@ -90,6 +90,7 @@ docfiles = \ tiffcrop.1.html \ tiffdither.1.html \ tiffdump.1.html \ + tiffgt.1.html \ tiffinfo.1.html \ tiffmedian.1.html \ tiffset.1.html \ diff --git a/libtiff/tif_aux.c b/libtiff/tif_aux.c index 38a98b6..10b8d00 100644 --- a/libtiff/tif_aux.c +++ b/libtiff/tif_aux.c @@ -59,57 +59,18 @@ _TIFFMultiply64(TIFF* tif, uint64 first, uint64 second, const char* where) return bytes; } -tmsize_t -_TIFFMultiplySSize(TIFF* tif, tmsize_t first, tmsize_t second, const char* where) -{ - if( first <= 0 || second <= 0 ) - { - if( tif != NULL && where != NULL ) - { - TIFFErrorExt(tif->tif_clientdata, where, - "Invalid argument to _TIFFMultiplySSize() in %s", where); - } - return 0; - } - - if( first > TIFF_TMSIZE_T_MAX / second ) - { - if( tif != NULL && where != NULL ) - { - TIFFErrorExt(tif->tif_clientdata, where, - "Integer overflow in %s", where); - } - return 0; - } - return first * second; -} - -tmsize_t _TIFFCastUInt64ToSSize(TIFF* tif, uint64 val, const char* module) -{ - if( val > (uint64)TIFF_TMSIZE_T_MAX ) - { - if( tif != NULL && module != NULL ) - { - TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow"); - } - return 0; - } - return (tmsize_t)val; -} - void* _TIFFCheckRealloc(TIFF* tif, void* buffer, tmsize_t nmemb, tmsize_t elem_size, const char* what) { void* cp = NULL; - tmsize_t count = _TIFFMultiplySSize(tif, nmemb, elem_size, NULL); + tmsize_t bytes = nmemb * elem_size; + /* - * Check for integer overflow. + * XXX: Check for integer overflow. */ - if (count != 0) - { - cp = _TIFFrealloc(buffer, count); - } + if (nmemb && elem_size && bytes / elem_size == nmemb) + cp = _TIFFrealloc(buffer, bytes); if (cp == NULL) { TIFFErrorExt(tif->tif_clientdata, tif->tif_name, diff --git a/libtiff/tif_dir.c b/libtiff/tif_dir.c index c36a5f3..f00f808 100644 --- a/libtiff/tif_dir.c +++ b/libtiff/tif_dir.c @@ -1067,9 +1067,6 @@ _TIFFVGetField(TIFF* tif, uint32 tag, va_list ap) if (td->td_samplesperpixel - td->td_extrasamples > 1) { *va_arg(ap, uint16**) = td->td_transferfunction[1]; *va_arg(ap, uint16**) = td->td_transferfunction[2]; - } else { - *va_arg(ap, uint16**) = NULL; - *va_arg(ap, uint16**) = NULL; } break; case TIFFTAG_REFERENCEBLACKWHITE: diff --git a/libtiff/tif_dirread.c b/libtiff/tif_dirread.c index 80aaf8d..5e62e81 100644 --- a/libtiff/tif_dirread.c +++ b/libtiff/tif_dirread.c @@ -167,7 +167,6 @@ static int TIFFFetchStripThing(TIFF* tif, TIFFDirEntry* dir, uint32 nstrips, uin static int TIFFFetchSubjectDistance(TIFF*, TIFFDirEntry*); static void ChopUpSingleUncompressedStrip(TIFF*); static uint64 TIFFReadUInt64(const uint8 *value); -static int _TIFFGetMaxColorChannels(uint16 photometric); static int _TIFFFillStrilesInternal( TIFF *tif, int loadStripByteCount ); @@ -3508,35 +3507,6 @@ static void TIFFReadDirEntryOutputErr(TIFF* tif, enum TIFFReadDirEntryErr err, c } /* - * Return the maximum number of color channels specified for a given photometric - * type. 0 is returned if photometric type isn't supported or no default value - * is defined by the specification. - */ -static int _TIFFGetMaxColorChannels( uint16 photometric ) -{ - switch (photometric) { - case PHOTOMETRIC_PALETTE: - case PHOTOMETRIC_MINISWHITE: - case PHOTOMETRIC_MINISBLACK: - return 1; - case PHOTOMETRIC_YCBCR: - case PHOTOMETRIC_RGB: - case PHOTOMETRIC_CIELAB: - return 3; - case PHOTOMETRIC_SEPARATED: - case PHOTOMETRIC_MASK: - return 4; - case PHOTOMETRIC_LOGL: - case PHOTOMETRIC_LOGLUV: - case PHOTOMETRIC_CFA: - case PHOTOMETRIC_ITULAB: - case PHOTOMETRIC_ICCLAB: - default: - return 0; - } -} - -/* * Read the next TIFF directory from a file and convert it to the internal * format. We read directories sequentially. */ @@ -3552,7 +3522,6 @@ TIFFReadDirectory(TIFF* tif) uint32 fii=FAILED_FII; toff_t nextdiroff; int bitspersample_read = FALSE; - int color_channels; tif->tif_diroff=tif->tif_nextdiroff; if (!TIFFCheckDirOffset(tif,tif->tif_nextdiroff)) @@ -4057,37 +4026,6 @@ TIFFReadDirectory(TIFF* tif) } } } - - /* - * Make sure all non-color channels are extrasamples. - * If it's not the case, define them as such. - */ - color_channels = _TIFFGetMaxColorChannels(tif->tif_dir.td_photometric); - if (color_channels && tif->tif_dir.td_samplesperpixel - tif->tif_dir.td_extrasamples > color_channels) { - uint16 old_extrasamples; - uint16 *new_sampleinfo; - - TIFFWarningExt(tif->tif_clientdata,module, "Sum of Photometric type-related " - "color channels and ExtraSamples doesn't match SamplesPerPixel. " - "Defining non-color channels as ExtraSamples."); - - old_extrasamples = tif->tif_dir.td_extrasamples; - tif->tif_dir.td_extrasamples = (tif->tif_dir.td_samplesperpixel - color_channels); - - // sampleinfo should contain information relative to these new extra samples - new_sampleinfo = (uint16*) _TIFFcalloc(tif->tif_dir.td_extrasamples, sizeof(uint16)); - if (!new_sampleinfo) { - TIFFErrorExt(tif->tif_clientdata, module, "Failed to allocate memory for " - "temporary new sampleinfo array (%d 16 bit elements)", - tif->tif_dir.td_extrasamples); - goto bad; - } - - memcpy(new_sampleinfo, tif->tif_dir.td_sampleinfo, old_extrasamples * sizeof(uint16)); - _TIFFsetShortArray(&tif->tif_dir.td_sampleinfo, new_sampleinfo, tif->tif_dir.td_extrasamples); - _TIFFfree(new_sampleinfo); - } - /* * Verify Palette image has a Colormap. */ diff --git a/libtiff/tif_dirwrite.c b/libtiff/tif_dirwrite.c index 5d0a669..c68d6d2 100644 --- a/libtiff/tif_dirwrite.c +++ b/libtiff/tif_dirwrite.c @@ -697,11 +697,8 @@ TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64* pdiroff) } break; default: - TIFFErrorExt(tif->tif_clientdata,module, - "Cannot write tag %d (%s)", - TIFFFieldTag(o), - o->field_name ? o->field_name : "unknown"); - goto bad; + assert(0); /* we should never get here */ + break; } } } diff --git a/libtiff/tif_getimage.c b/libtiff/tif_getimage.c index c6edd27..fc554cc 100644 --- a/libtiff/tif_getimage.c +++ b/libtiff/tif_getimage.c @@ -757,8 +757,9 @@ gtTileSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) uint32 leftmost_tw; tilesize = TIFFTileSize(tif); - bufsize = _TIFFMultiplySSize(tif, alpha?4:3,tilesize, "gtTileSeparate"); + bufsize = TIFFSafeMultiply(tmsize_t,alpha?4:3,tilesize); if (bufsize == 0) { + TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Integer overflow in %s", "gtTileSeparate"); return (0); } @@ -951,23 +952,16 @@ gtStripContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) fromskew = (w < imagewidth ? imagewidth - w : 0); for (row = 0; row < h; row += nrow) { - uint32 temp; rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip; nrow = (row + rowstoread > h ? h - row : rowstoread); nrowsub = nrow; if ((nrowsub%subsamplingver)!=0) nrowsub+=subsamplingver-nrowsub%subsamplingver; - temp = (row + img->row_offset)%rowsperstrip + nrowsub; - if( scanline > 0 && temp > (size_t)(TIFF_TMSIZE_T_MAX / scanline) ) - { - TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Integer overflow in gtStripContig"); - return 0; - } if (_TIFFReadEncodedStripAndAllocBuffer(tif, TIFFComputeStrip(tif,row+img->row_offset, 0), (void**)(&buf), maxstripsize, - temp * scanline)==(tmsize_t)(-1) + ((row + img->row_offset)%rowsperstrip + nrowsub) * scanline)==(tmsize_t)(-1) && (buf == NULL || img->stoponerr)) { ret = 0; @@ -1027,8 +1021,9 @@ gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) uint16 colorchannels; stripsize = TIFFStripSize(tif); - bufsize = _TIFFMultiplySSize(tif,alpha?4:3,stripsize, "gtStripSeparate"); + bufsize = TIFFSafeMultiply(tmsize_t,alpha?4:3,stripsize); if (bufsize == 0) { + TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Integer overflow in %s", "gtStripSeparate"); return (0); } @@ -1060,22 +1055,15 @@ gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) fromskew = (w < imagewidth ? imagewidth - w : 0); for (row = 0; row < h; row += nrow) { - uint32 temp; rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip; nrow = (row + rowstoread > h ? h - row : rowstoread); offset_row = row + img->row_offset; - temp = (row + img->row_offset)%rowsperstrip + nrow; - if( scanline > 0 && temp > (size_t)(TIFF_TMSIZE_T_MAX / scanline) ) - { - TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Integer overflow in gtStripSeparate"); - return 0; - } if( buf == NULL ) { if (_TIFFReadEncodedStripAndAllocBuffer( tif, TIFFComputeStrip(tif, offset_row, 0), (void**) &buf, bufsize, - temp * scanline)==(tmsize_t)(-1) + ((row + img->row_offset)%rowsperstrip + nrow) * scanline)==(tmsize_t)(-1) && (buf == NULL || img->stoponerr)) { ret = 0; @@ -1095,7 +1083,7 @@ gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) } } else if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 0), - p0, temp * scanline)==(tmsize_t)(-1) + p0, ((row + img->row_offset)%rowsperstrip + nrow) * scanline)==(tmsize_t)(-1) && img->stoponerr) { ret = 0; @@ -1103,7 +1091,7 @@ gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) } if (colorchannels > 1 && TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 1), - p1, temp * scanline) == (tmsize_t)(-1) + p1, ((row + img->row_offset)%rowsperstrip + nrow) * scanline) == (tmsize_t)(-1) && img->stoponerr) { ret = 0; @@ -1111,7 +1099,7 @@ gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) } if (colorchannels > 1 && TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 2), - p2, temp * scanline) == (tmsize_t)(-1) + p2, ((row + img->row_offset)%rowsperstrip + nrow) * scanline) == (tmsize_t)(-1) && img->stoponerr) { ret = 0; @@ -1120,7 +1108,7 @@ gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) if (alpha) { if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, colorchannels), - pa, temp * scanline)==(tmsize_t)(-1) + pa, ((row + img->row_offset)%rowsperstrip + nrow) * scanline)==(tmsize_t)(-1) && img->stoponerr) { ret = 0; diff --git a/libtiff/tif_jbig.c b/libtiff/tif_jbig.c index 8136c77..7a14dd9 100644 --- a/libtiff/tif_jbig.c +++ b/libtiff/tif_jbig.c @@ -53,18 +53,17 @@ static int JBIGDecode(TIFF* tif, uint8* buffer, tmsize_t size, uint16 s) struct jbg_dec_state decoder; int decodeStatus = 0; unsigned char* pImage = NULL; - unsigned long decodedSize; - (void) s; + (void) size, (void) s; if (isFillOrder(tif, tif->tif_dir.td_fillorder)) { - TIFFReverseBits(tif->tif_rawcp, tif->tif_rawcc); + TIFFReverseBits(tif->tif_rawdata, tif->tif_rawdatasize); } jbg_dec_init(&decoder); #if defined(HAVE_JBG_NEWLEN) - jbg_newlen(tif->tif_rawcp, (size_t)tif->tif_rawcc); + jbg_newlen(tif->tif_rawdata, (size_t)tif->tif_rawdatasize); /* * I do not check the return status of jbg_newlen because even if this * function fails it does not necessarily mean that decoding the image @@ -77,8 +76,8 @@ static int JBIGDecode(TIFF* tif, uint8* buffer, tmsize_t size, uint16 s) */ #endif /* HAVE_JBG_NEWLEN */ - decodeStatus = jbg_dec_in(&decoder, (unsigned char*)tif->tif_rawcp, - (size_t)tif->tif_rawcc, NULL); + decodeStatus = jbg_dec_in(&decoder, (unsigned char*)tif->tif_rawdata, + (size_t)tif->tif_rawdatasize, NULL); if (JBG_EOK != decodeStatus) { /* @@ -99,28 +98,9 @@ static int JBIGDecode(TIFF* tif, uint8* buffer, tmsize_t size, uint16 s) return 0; } - decodedSize = jbg_dec_getsize(&decoder); - if( (tmsize_t)decodedSize < size ) - { - TIFFWarningExt(tif->tif_clientdata, "JBIG", - "Only decoded %lu bytes, whereas %lu requested", - decodedSize, (unsigned long)size); - } - else if( (tmsize_t)decodedSize > size ) - { - TIFFErrorExt(tif->tif_clientdata, "JBIG", - "Decoded %lu bytes, whereas %lu were requested", - decodedSize, (unsigned long)size); - jbg_dec_free(&decoder); - return 0; - } pImage = jbg_dec_getimage(&decoder, 0); - _TIFFmemcpy(buffer, pImage, decodedSize); + _TIFFmemcpy(buffer, pImage, jbg_dec_getsize(&decoder)); jbg_dec_free(&decoder); - - tif->tif_rawcp += tif->tif_rawcc; - tif->tif_rawcc = 0; - return 1; } diff --git a/libtiff/tif_luv.c b/libtiff/tif_luv.c index c4cb73a..4b25244 100644 --- a/libtiff/tif_luv.c +++ b/libtiff/tif_luv.c @@ -1264,10 +1264,16 @@ LogL16GuessDataFmt(TIFFDirectory *td) return (SGILOGDATAFMT_UNKNOWN); } + +#define TIFF_SIZE_T_MAX ((size_t) ~ ((size_t)0)) +#define TIFF_TMSIZE_T_MAX (tmsize_t)(TIFF_SIZE_T_MAX >> 1) + static tmsize_t multiply_ms(tmsize_t m1, tmsize_t m2) { - return _TIFFMultiplySSize(NULL, m1, m2, NULL); + if( m1 == 0 || m2 > TIFF_TMSIZE_T_MAX / m1 ) + return 0; + return m1 * m2; } static int diff --git a/libtiff/tif_lzw.c b/libtiff/tif_lzw.c index 186ea3c..bc8f9c8 100644 --- a/libtiff/tif_lzw.c +++ b/libtiff/tif_lzw.c @@ -604,7 +604,6 @@ LZWDecodeCompat(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s) char *tp; unsigned char *bp; int code, nbits; - int len; long nextbits, nextdata, nbitsmask; code_t *codep, *free_entp, *maxcodep, *oldcodep; @@ -756,18 +755,13 @@ LZWDecodeCompat(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s) } while (--occ); break; } - len = codep->length; - tp = op + len; + assert(occ >= codep->length); + op += codep->length; + occ -= codep->length; + tp = op; do { - int t; - --tp; - t = codep->value; - codep = codep->next; - *tp = (char)t; - } while (codep && tp > op); - assert(occ >= len); - op += len; - occ -= len; + *--tp = codep->value; + } while( (codep = codep->next) != NULL ); } else { *op++ = (char)code; occ--; diff --git a/libtiff/tif_pixarlog.c b/libtiff/tif_pixarlog.c index 8e9eaa1..979858d 100644 --- a/libtiff/tif_pixarlog.c +++ b/libtiff/tif_pixarlog.c @@ -636,10 +636,15 @@ PixarLogGuessDataFmt(TIFFDirectory *td) return guess; } +#define TIFF_SIZE_T_MAX ((size_t) ~ ((size_t)0)) +#define TIFF_TMSIZE_T_MAX (tmsize_t)(TIFF_SIZE_T_MAX >> 1) + static tmsize_t multiply_ms(tmsize_t m1, tmsize_t m2) { - return _TIFFMultiplySSize(NULL, m1, m2, NULL); + if( m1 == 0 || m2 > TIFF_TMSIZE_T_MAX / m1 ) + return 0; + return m1 * m2; } static tmsize_t diff --git a/libtiff/tif_print.c b/libtiff/tif_print.c index b9b53a0..24d4b98 100644 --- a/libtiff/tif_print.c +++ b/libtiff/tif_print.c @@ -546,7 +546,7 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags) uint16 i; fprintf(fd, " %2ld: %5u", l, td->td_transferfunction[0][l]); - for (i = 1; i < td->td_samplesperpixel - td->td_extrasamples && i < 3; i++) + for (i = 1; i < td->td_samplesperpixel; i++) fprintf(fd, " %5u", td->td_transferfunction[i][l]); fputc('\n', fd); @@ -667,13 +667,13 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags) #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) fprintf(fd, " %3lu: [%8I64u, %8I64u]\n", (unsigned long) s, - td->td_stripoffset ? (unsigned __int64) td->td_stripoffset[s] : 0, - td->td_stripbytecount ? (unsigned __int64) td->td_stripbytecount[s] : 0); + (unsigned __int64) td->td_stripoffset[s], + (unsigned __int64) td->td_stripbytecount[s]); #else fprintf(fd, " %3lu: [%8llu, %8llu]\n", (unsigned long) s, - td->td_stripoffset ? (unsigned long long) td->td_stripoffset[s] : 0, - td->td_stripbytecount ? (unsigned long long) td->td_stripbytecount[s] : 0); + (unsigned long long) td->td_stripoffset[s], + (unsigned long long) td->td_stripbytecount[s]); #endif } } diff --git a/libtiff/tif_read.c b/libtiff/tif_read.c index 9a0e6e9..2ba985a 100644 --- a/libtiff/tif_read.c +++ b/libtiff/tif_read.c @@ -31,6 +31,9 @@ #include "tiffiop.h" #include +#define TIFF_SIZE_T_MAX ((size_t) ~ ((size_t)0)) +#define TIFF_TMSIZE_T_MAX (tmsize_t)(TIFF_SIZE_T_MAX >> 1) + int TIFFFillStrip(TIFF* tif, uint32 strip); int TIFFFillTile(TIFF* tif, uint32 tile); static int TIFFStartStrip(TIFF* tif, uint32 strip); @@ -48,8 +51,6 @@ TIFFReadRawTile1(TIFF* tif, uint32 tile, void* buf, tmsize_t size, const char* m #define THRESHOLD_MULTIPLIER 10 #define MAX_THRESHOLD (THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * INITIAL_THRESHOLD) -#define TIFF_INT64_MAX ((((int64)0x7FFFFFFF) << 32) | 0xFFFFFFFF) - /* Read 'size' bytes in tif_rawdata buffer starting at offset 'rawdata_offset' * Returns 1 in case of success, 0 otherwise. */ static int TIFFReadAndRealloc( TIFF* tif, tmsize_t size, @@ -347,12 +348,6 @@ TIFFSeek(TIFF* tif, uint32 row, uint16 sample ) return 0; whole_strip = tif->tif_dir.td_stripbytecount[strip] < 10 || isMapped(tif); - if( td->td_compression == COMPRESSION_JBIG ) - { - /* Ideally plugins should have a way to declare they don't support - * chunk strip */ - whole_strip = 1; - } #else whole_strip = 1; #endif @@ -734,8 +729,23 @@ TIFFReadRawStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size) return ((tmsize_t)(-1)); } bytecount = td->td_stripbytecount[strip]; - bytecountm = _TIFFCastUInt64ToSSize(tif, bytecount, module); - if (bytecountm == 0) { + if ((int64)bytecount <= 0) { +#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) + TIFFErrorExt(tif->tif_clientdata, module, + "%I64u: Invalid strip byte count, strip %lu", + (unsigned __int64) bytecount, + (unsigned long) strip); +#else + TIFFErrorExt(tif->tif_clientdata, module, + "%llu: Invalid strip byte count, strip %lu", + (unsigned long long) bytecount, + (unsigned long) strip); +#endif + return ((tmsize_t)(-1)); + } + bytecountm = (tmsize_t)bytecount; + if ((uint64)bytecountm!=bytecount) { + TIFFErrorExt(tif->tif_clientdata, module, "Integer overflow"); return ((tmsize_t)(-1)); } if (size != (tmsize_t)(-1) && size < bytecountm) @@ -759,7 +769,7 @@ TIFFFillStrip(TIFF* tif, uint32 strip) if ((tif->tif_flags&TIFF_NOREADRAW)==0) { uint64 bytecount = td->td_stripbytecount[strip]; - if( bytecount == 0 || bytecount > (uint64)TIFF_INT64_MAX ) { + if ((int64)bytecount <= 0) { #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) TIFFErrorExt(tif->tif_clientdata, module, "Invalid strip byte count %I64u, strip %lu", @@ -786,7 +796,7 @@ TIFFFillStrip(TIFF* tif, uint32 strip) (bytecount - 4096) / 10 > (uint64)stripsize ) { uint64 newbytecount = (uint64)stripsize * 10 + 4096; - if( newbytecount == 0 || newbytecount > (uint64)TIFF_INT64_MAX ) + if( (int64)newbytecount >= 0 ) { #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) TIFFWarningExt(tif->tif_clientdata, module, @@ -1181,8 +1191,10 @@ TIFFReadRawTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size) bytecount64 = td->td_stripbytecount[tile]; if (size != (tmsize_t)(-1) && (uint64)size < bytecount64) bytecount64 = (uint64)size; - bytecountm = _TIFFCastUInt64ToSSize(tif, bytecount64, module); - if( bytecountm == 0 ) { + bytecountm = (tmsize_t)bytecount64; + if ((uint64)bytecountm!=bytecount64) + { + TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow"); return ((tmsize_t)(-1)); } return (TIFFReadRawTile1(tif, tile, buf, bytecountm, module)); @@ -1204,7 +1216,7 @@ TIFFFillTile(TIFF* tif, uint32 tile) if ((tif->tif_flags&TIFF_NOREADRAW)==0) { uint64 bytecount = td->td_stripbytecount[tile]; - if( bytecount == 0 || bytecount > (uint64)TIFF_INT64_MAX ) { + if ((int64)bytecount <= 0) { #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) TIFFErrorExt(tif->tif_clientdata, module, "%I64u: Invalid tile byte count, tile %lu", @@ -1231,7 +1243,7 @@ TIFFFillTile(TIFF* tif, uint32 tile) (bytecount - 4096) / 10 > (uint64)stripsize ) { uint64 newbytecount = (uint64)stripsize * 10 + 4096; - if( newbytecount == 0 || newbytecount > (uint64)TIFF_INT64_MAX ) + if( (int64)newbytecount >= 0 ) { #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) TIFFWarningExt(tif->tif_clientdata, module, diff --git a/libtiff/tif_strip.c b/libtiff/tif_strip.c index 321ad6b..6e9f2ef 100644 --- a/libtiff/tif_strip.c +++ b/libtiff/tif_strip.c @@ -131,8 +131,15 @@ TIFFVStripSize(TIFF* tif, uint32 nrows) { static const char module[] = "TIFFVStripSize"; uint64 m; + tmsize_t n; m=TIFFVStripSize64(tif,nrows); - return _TIFFCastUInt64ToSSize(tif, m, module); + n=(tmsize_t)m; + if ((uint64)n!=m) + { + TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow"); + n=0; + } + return(n); } /* @@ -206,8 +213,15 @@ TIFFStripSize(TIFF* tif) { static const char module[] = "TIFFStripSize"; uint64 m; + tmsize_t n; m=TIFFStripSize64(tif); - return _TIFFCastUInt64ToSSize(tif, m, module); + n=(tmsize_t)m; + if ((uint64)n!=m) + { + TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow"); + n=0; + } + return(n); } /* @@ -318,8 +332,14 @@ TIFFScanlineSize(TIFF* tif) { static const char module[] = "TIFFScanlineSize"; uint64 m; + tmsize_t n; m=TIFFScanlineSize64(tif); - return _TIFFCastUInt64ToSSize(tif, m, module); + n=(tmsize_t)m; + if ((uint64)n!=m) { + TIFFErrorExt(tif->tif_clientdata,module,"Integer arithmetic overflow"); + n=0; + } + return(n); } /* @@ -348,8 +368,15 @@ TIFFRasterScanlineSize(TIFF* tif) { static const char module[] = "TIFFRasterScanlineSize"; uint64 m; + tmsize_t n; m=TIFFRasterScanlineSize64(tif); - return _TIFFCastUInt64ToSSize(tif, m, module); + n=(tmsize_t)m; + if ((uint64)n!=m) + { + TIFFErrorExt(tif->tif_clientdata,module,"Integer arithmetic overflow"); + n=0; + } + return(n); } /* vim: set ts=8 sts=8 sw=8 noet: */ diff --git a/libtiff/tif_tile.c b/libtiff/tif_tile.c index 7d05750..388e168 100644 --- a/libtiff/tif_tile.c +++ b/libtiff/tif_tile.c @@ -183,8 +183,15 @@ TIFFTileRowSize(TIFF* tif) { static const char module[] = "TIFFTileRowSize"; uint64 m; + tmsize_t n; m=TIFFTileRowSize64(tif); - return _TIFFCastUInt64ToSSize(tif, m, module); + n=(tmsize_t)m; + if ((uint64)n!=m) + { + TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow"); + n=0; + } + return(n); } /* @@ -243,8 +250,15 @@ TIFFVTileSize(TIFF* tif, uint32 nrows) { static const char module[] = "TIFFVTileSize"; uint64 m; + tmsize_t n; m=TIFFVTileSize64(tif,nrows); - return _TIFFCastUInt64ToSSize(tif, m, module); + n=(tmsize_t)m; + if ((uint64)n!=m) + { + TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow"); + n=0; + } + return(n); } /* @@ -260,8 +274,15 @@ TIFFTileSize(TIFF* tif) { static const char module[] = "TIFFTileSize"; uint64 m; + tmsize_t n; m=TIFFTileSize64(tif); - return _TIFFCastUInt64ToSSize(tif, m, module); + n=(tmsize_t)m; + if ((uint64)n!=m) + { + TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow"); + n=0; + } + return(n); } /* diff --git a/libtiff/tiffiop.h b/libtiff/tiffiop.h index d4b8631..daa291c 100644 --- a/libtiff/tiffiop.h +++ b/libtiff/tiffiop.h @@ -72,16 +72,12 @@ extern int snprintf(char* str, size_t size, const char* format, ...); #endif #define streq(a,b) (strcmp(a,b) == 0) -#define strneq(a,b,n) (strncmp(a,b,n) == 0) #ifndef TRUE #define TRUE 1 #define FALSE 0 #endif -#define TIFF_SIZE_T_MAX ((size_t) ~ ((size_t)0)) -#define TIFF_TMSIZE_T_MAX (tmsize_t)(TIFF_SIZE_T_MAX >> 1) - typedef struct client_info { struct client_info *next; void *data; @@ -263,7 +259,7 @@ struct tiff { #define TIFFhowmany8_64(x) (((x)&0x07)?((uint64)(x)>>3)+1:(uint64)(x)>>3) #define TIFFroundup_64(x, y) (TIFFhowmany_64(x,y)*(y)) -/* Safe multiply which returns zero if there is an *unsigned* integer overflow. This macro is not safe for *signed* integer types */ +/* Safe multiply which returns zero if there is an integer overflow */ #define TIFFSafeMultiply(t,v,m) ((((t)(m) != (t)0) && (((t)(((v)*(m))/(m))) == (t)(v))) ? (t)((v)*(m)) : (t)0) #define TIFFmax(A,B) ((A)>(B)?(A):(B)) @@ -369,8 +365,6 @@ extern TIFFErrorHandlerExt _TIFFerrorHandlerExt; extern uint32 _TIFFMultiply32(TIFF*, uint32, uint32, const char*); extern uint64 _TIFFMultiply64(TIFF*, uint64, uint64, const char*); -extern tmsize_t _TIFFMultiplySSize(TIFF*, tmsize_t, tmsize_t, const char*); -extern tmsize_t _TIFFCastUInt64ToSSize(TIFF*, uint64, const char*); extern void* _TIFFCheckMalloc(TIFF*, tmsize_t, tmsize_t, const char*); extern void* _TIFFCheckRealloc(TIFF*, void*, tmsize_t, tmsize_t, const char*); diff --git a/test/Makefile.am b/test/Makefile.am index 227f228..2052487 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -23,7 +23,7 @@ # Process this file with automake to produce Makefile.in. -AUTOMAKE_OPTIONS = 1.11 color-tests parallel-tests foreign +AUTOMAKE_OPTIONS = 1.12 color-tests parallel-tests foreign LIBTIFF = $(top_builddir)/libtiff/libtiff.la diff --git a/tools/ppm2tiff.c b/tools/ppm2tiff.c index a02e865..91415e9 100644 --- a/tools/ppm2tiff.c +++ b/tools/ppm2tiff.c @@ -72,16 +72,15 @@ BadPPM(char* file) exit(-2); } - -#define TIFF_SIZE_T_MAX ((size_t) ~ ((size_t)0)) -#define TIFF_TMSIZE_T_MAX (tmsize_t)(TIFF_SIZE_T_MAX >> 1) - static tmsize_t multiply_ms(tmsize_t m1, tmsize_t m2) { - if( m1 == 0 || m2 > TIFF_TMSIZE_T_MAX / m1 ) - return 0; - return m1 * m2; + tmsize_t bytes = m1 * m2; + + if (m1 && bytes / m1 != m2) + bytes = 0; + + return bytes; } int @@ -285,8 +284,6 @@ main(int argc, char* argv[]) if (TIFFWriteScanline(out, buf, row, 0) < 0) break; } - if (in != stdin) - fclose(in); (void) TIFFClose(out); if (buf) _TIFFfree(buf); diff --git a/tools/tiff2bw.c b/tools/tiff2bw.c index 1f3bb2c..dad54af 100644 --- a/tools/tiff2bw.c +++ b/tools/tiff2bw.c @@ -40,7 +40,9 @@ #endif #include "tiffio.h" -#include "tiffiop.h" + +#define streq(a,b) (strcmp((a),(b)) == 0) +#define strneq(a,b,n) (strncmp(a,b,n) == 0) /* x% weighting -> fraction of full color */ #define PCT(x) (((x)*256+50)/100) @@ -221,11 +223,6 @@ main(int argc, char* argv[]) TIFFSetField(out, TIFFTAG_IMAGEDESCRIPTION, thing); TIFFSetField(out, TIFFTAG_SOFTWARE, "tiff2bw"); outbuf = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(out)); - if( !outbuf ) - { - fprintf(stderr, "Out of memory\n"); - goto tiff2bw_error; - } TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(out, rowsperstrip)); @@ -249,11 +246,6 @@ main(int argc, char* argv[]) #undef CVT } inbuf = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(in)); - if( !inbuf ) - { - fprintf(stderr, "Out of memory\n"); - goto tiff2bw_error; - } for (row = 0; row < h; row++) { if (TIFFReadScanline(in, inbuf, row, 0) < 0) break; @@ -264,11 +256,6 @@ main(int argc, char* argv[]) break; case pack(PHOTOMETRIC_RGB, PLANARCONFIG_CONTIG): inbuf = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(in)); - if( !inbuf ) - { - fprintf(stderr, "Out of memory\n"); - goto tiff2bw_error; - } for (row = 0; row < h; row++) { if (TIFFReadScanline(in, inbuf, row, 0) < 0) break; @@ -278,16 +265,8 @@ main(int argc, char* argv[]) } break; case pack(PHOTOMETRIC_RGB, PLANARCONFIG_SEPARATE): - { - tmsize_t inbufsize; rowsize = TIFFScanlineSize(in); - inbufsize = TIFFSafeMultiply(tmsize_t, 3, rowsize); - inbuf = (unsigned char *)_TIFFmalloc(inbufsize); - if( !inbuf ) - { - fprintf(stderr, "Out of memory\n"); - goto tiff2bw_error; - } + inbuf = (unsigned char *)_TIFFmalloc(3*rowsize); for (row = 0; row < h; row++) { for (s = 0; s < 3; s++) if (TIFFReadScanline(in, @@ -299,7 +278,6 @@ main(int argc, char* argv[]) break; } break; - } } #undef pack if (inbuf) diff --git a/tools/tiff2pdf.c b/tools/tiff2pdf.c index a15a3ef..454befb 100644 --- a/tools/tiff2pdf.c +++ b/tools/tiff2pdf.c @@ -68,8 +68,6 @@ extern int getopt(int, char**, char*); #define PS_UNIT_SIZE 72.0F -#define TIFF_DIR_MAX 65534 - /* This type is of PDF color spaces. */ typedef enum { T2P_CS_BILEVEL = 0x01, /* Bilevel, black and white */ @@ -239,7 +237,7 @@ typedef struct { float tiff_whitechromaticities[2]; float tiff_primarychromaticities[6]; float tiff_referenceblackwhite[2]; - uint16* tiff_transferfunction[3]; + float* tiff_transferfunction[3]; int pdf_image_interpolate; /* 0 (default) : do not interpolate, 1 : interpolate */ uint16 tiff_transferfunctioncount; @@ -1049,18 +1047,8 @@ void t2p_read_tiff_init(T2P* t2p, TIFF* input){ uint16 pagen=0; uint16 paged=0; uint16 xuint16=0; - uint16 tiff_transferfunctioncount=0; - uint16* tiff_transferfunction[3]; directorycount=TIFFNumberOfDirectories(input); - if(directorycount > TIFF_DIR_MAX) { - TIFFError( - TIFF2PDF_MODULE, - "TIFF contains too many directories, %s", - TIFFFileName(input)); - t2p->t2p_error = T2P_ERR_ERROR; - return; - } t2p->tiff_pages = (T2P_PAGE*) _TIFFmalloc(TIFFSafeMultiply(tmsize_t,directorycount,sizeof(T2P_PAGE))); if(t2p->tiff_pages==NULL){ TIFFError( @@ -1159,48 +1147,26 @@ void t2p_read_tiff_init(T2P* t2p, TIFF* input){ } #endif if (TIFFGetField(input, TIFFTAG_TRANSFERFUNCTION, - &(tiff_transferfunction[0]), - &(tiff_transferfunction[1]), - &(tiff_transferfunction[2]))) { - - if((tiff_transferfunction[1] != (uint16*) NULL) && - (tiff_transferfunction[2] != (uint16*) NULL) - ) { - tiff_transferfunctioncount=3; - } else { - tiff_transferfunctioncount=1; - } + &(t2p->tiff_transferfunction[0]), + &(t2p->tiff_transferfunction[1]), + &(t2p->tiff_transferfunction[2]))) { + if((t2p->tiff_transferfunction[1] != (float*) NULL) && + (t2p->tiff_transferfunction[2] != (float*) NULL) && + (t2p->tiff_transferfunction[1] != + t2p->tiff_transferfunction[0])) { + t2p->tiff_transferfunctioncount = 3; + t2p->tiff_pages[i].page_extra += 4; + t2p->pdf_xrefcount += 4; + } else { + t2p->tiff_transferfunctioncount = 1; + t2p->tiff_pages[i].page_extra += 2; + t2p->pdf_xrefcount += 2; + } + if(t2p->pdf_minorversion < 2) + t2p->pdf_minorversion = 2; } else { - tiff_transferfunctioncount=0; + t2p->tiff_transferfunctioncount=0; } - - if (i > 0){ - if (tiff_transferfunctioncount != t2p->tiff_transferfunctioncount){ - TIFFError( - TIFF2PDF_MODULE, - "Different transfer function on page %d", - i); - t2p->t2p_error = T2P_ERR_ERROR; - return; - } - } - - t2p->tiff_transferfunctioncount = tiff_transferfunctioncount; - t2p->tiff_transferfunction[0] = tiff_transferfunction[0]; - t2p->tiff_transferfunction[1] = tiff_transferfunction[1]; - t2p->tiff_transferfunction[2] = tiff_transferfunction[2]; - if(tiff_transferfunctioncount == 3){ - t2p->tiff_pages[i].page_extra += 4; - t2p->pdf_xrefcount += 4; - if(t2p->pdf_minorversion < 2) - t2p->pdf_minorversion = 2; - } else if (tiff_transferfunctioncount == 1){ - t2p->tiff_pages[i].page_extra += 2; - t2p->pdf_xrefcount += 2; - if(t2p->pdf_minorversion < 2) - t2p->pdf_minorversion = 2; - } - if( TIFFGetField( input, TIFFTAG_ICCPROFILE, @@ -1861,9 +1827,10 @@ void t2p_read_tiff_data(T2P* t2p, TIFF* input){ &(t2p->tiff_transferfunction[0]), &(t2p->tiff_transferfunction[1]), &(t2p->tiff_transferfunction[2]))) { - if((t2p->tiff_transferfunction[1] != (uint16*) NULL) && - (t2p->tiff_transferfunction[2] != (uint16*) NULL) - ) { + if((t2p->tiff_transferfunction[1] != (float*) NULL) && + (t2p->tiff_transferfunction[2] != (float*) NULL) && + (t2p->tiff_transferfunction[1] != + t2p->tiff_transferfunction[0])) { t2p->tiff_transferfunctioncount=3; } else { t2p->tiff_transferfunctioncount=1; @@ -3020,7 +2987,6 @@ tsize_t t2p_readwrite_pdf_image_tile(T2P* t2p, TIFF* input, TIFF* output, ttile_ "for t2p_readwrite_pdf_image_tile, %s", (unsigned long) t2p->tiff_datasize, TIFFFileName(input)); - _TIFFfree(buffer); t2p->t2p_error = T2P_ERR_ERROR; return(0); } @@ -3748,11 +3714,11 @@ t2p_sample_rgbaa_to_rgb(tdata_t data, uint32 samplecount) { uint32 i; - /* For the 3 first samples, there is overlapping between souce and - destination, so use memmove(). - See http://bugzilla.maptools.org/show_bug.cgi?id=2577 */ - for(i = 0; i < 3 && i < samplecount; i++) - memmove((uint8*)data + i * 3, (uint8*)data + i * 4, 3); + /* For the 3 first samples, there is overlapping between souce and + destination, so use memmove(). + See http://bugzilla.maptools.org/show_bug.cgi?id=2577 */ + for(i = 0; i < 3 && i < samplecount; i++) + memmove((uint8*)data + i * 3, (uint8*)data + i * 4, 3); for(; i < samplecount; i++) memcpy((uint8*)data + i * 3, (uint8*)data + i * 4, 3); diff --git a/tools/tiffcp.c b/tools/tiffcp.c index 96f1472..489459a 100644 --- a/tools/tiffcp.c +++ b/tools/tiffcp.c @@ -43,7 +43,6 @@ #include #include #include -#include #include @@ -1392,7 +1391,7 @@ DECLAREreadFunc(readSeparateTilesIntoBuffer) int status = 1; uint32 imagew = TIFFRasterScanlineSize(in); uint32 tilew = TIFFTileRowSize(in); - int iskew; + int iskew = imagew - tilew*spp; tsize_t tilesize = TIFFTileSize(in); tdata_t tilebuf; uint8* bufp = (uint8*) buf; @@ -1400,12 +1399,6 @@ DECLAREreadFunc(readSeparateTilesIntoBuffer) uint32 row; uint16 bps = 0, bytes_per_sample; - if (tilew && spp > (INT_MAX / tilew)) - { - TIFFError(TIFFFileName(in), "Error, cannot handle that much samples per tile row (Tile Width * Samples/Pixel)"); - return 0; - } - iskew = imagew - tilew*spp; tilebuf = _TIFFmalloc(tilesize); if (tilebuf == 0) return 0; diff --git a/tools/tiffcrop.c b/tools/tiffcrop.c index 3862b1c..c69177e 100644 --- a/tools/tiffcrop.c +++ b/tools/tiffcrop.c @@ -150,6 +150,11 @@ extern int getopt(int argc, char * const argv[], const char *optstring); #define TIFF_UINT32_MAX 0xFFFFFFFFU +#ifndef streq +#define streq(a,b) (strcmp((a),(b)) == 0) +#endif +#define strneq(a,b,n) (strncmp((a),(b),(n)) == 0) + #define TRUE 1 #define FALSE 0 @@ -212,8 +217,6 @@ extern int getopt(int argc, char * const argv[], const char *optstring); #define DUMP_TEXT 1 #define DUMP_RAW 2 -#define TIFF_DIR_MAX 65534 - /* Offsets into buffer for margins and fixed width and length segments */ struct offset { uint32 tmargin; @@ -2230,7 +2233,7 @@ main(int argc, char* argv[]) pageNum = -1; else total_images = 0; - /* Read multiple input files and write to output file(s) */ + /* read multiple input files and write to output file(s) */ while (optind < argc - 1) { in = TIFFOpen (argv[optind], "r"); @@ -2238,14 +2241,7 @@ main(int argc, char* argv[]) return (-3); /* If only one input file is specified, we can use directory count */ - total_images = TIFFNumberOfDirectories(in); - if (total_images > TIFF_DIR_MAX) - { - TIFFError (TIFFFileName(in), "File contains too many directories"); - if (out != NULL) - (void) TIFFClose(out); - return (1); - } + total_images = TIFFNumberOfDirectories(in); if (image_count == 0) { dirnum = 0;