From ba1fb21bc61a2075c7fd058e7f7ba5caf7d2f400 Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Tue, 5 Nov 2019 09:58:05 +0100 Subject: Update bundled libtiff to version 4.1.0 [ChangeLog][Third-Party Code] Bundled libtiff was updated to version 4.1.0 Change-Id: I3e841863c5cf8588bf62b6520f34e64909394998 Reviewed-by: Allan Sandfeld Jensen Reviewed-by: Liang Qi --- src/3rdparty/libtiff/libtiff/tif_read.c | 226 ++++++++++++++++++++++---------- 1 file changed, 157 insertions(+), 69 deletions(-) (limited to 'src/3rdparty/libtiff/libtiff/tif_read.c') diff --git a/src/3rdparty/libtiff/libtiff/tif_read.c b/src/3rdparty/libtiff/libtiff/tif_read.c index aa31054..527fadd 100644 --- a/src/3rdparty/libtiff/libtiff/tif_read.c +++ b/src/3rdparty/libtiff/libtiff/tif_read.c @@ -60,6 +60,22 @@ static int TIFFReadAndRealloc( TIFF* tif, tmsize_t size, #endif tmsize_t already_read = 0; + +#if SIZEOF_SIZE_T != 8 + /* On 32 bit processes, if the request is large enough, check against */ + /* file size */ + if( size > 1000 * 1000 * 1000 ) + { + uint64 filesize = TIFFGetFileSize(tif); + if( (uint64)size >= filesize ) + { + TIFFErrorExt(tif->tif_clientdata, module, + "Chunk size requested is larger than file size."); + return 0; + } + } +#endif + /* On 64 bit processes, read first a maximum of 1 MB, then 10 MB, etc */ /* so as to avoid allocating too much memory in case the file is too */ /* short. We could ask for the file size, but this might be */ @@ -102,6 +118,11 @@ static int TIFFReadAndRealloc( TIFF* tif, tmsize_t size, } tif->tif_rawdata = new_rawdata; } + if( tif->tif_rawdata == NULL ) + { + /* should not happen in practice but helps CoverityScan */ + return 0; + } bytes_read = TIFFReadFile(tif, tif->tif_rawdata + rawdata_offset + already_read, to_read); @@ -169,17 +190,14 @@ TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart ) tmsize_t to_read; tmsize_t read_ahead_mod; /* tmsize_t bytecountm; */ - - if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount) - return 0; - + /* * Expand raw data buffer, if needed, to hold data * strip coming from file (perhaps should set upper * bound on the size of a buffer we'll use?). */ - /* bytecountm=(tmsize_t) td->td_stripbytecount[strip]; */ + /* bytecountm=(tmsize_t) TIFFGetStrileByteCount(tif, strip); */ /* Not completely sure where the * 2 comes from, but probably for */ /* an exponentional growth strategy of tif_rawdatasize */ @@ -223,7 +241,7 @@ TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart ) /* ** Seek to the point in the file where more data should be read. */ - read_offset = td->td_stripoffset[strip] + read_offset = TIFFGetStrileOffset(tif, strip) + tif->tif_rawdataoff + tif->tif_rawdataloaded; if (!SeekOK(tif, read_offset)) { @@ -240,10 +258,10 @@ TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart ) to_read = read_ahead_mod - unused_data; else to_read = tif->tif_rawdatasize - unused_data; - if( (uint64) to_read > td->td_stripbytecount[strip] + if( (uint64) to_read > TIFFGetStrileByteCount(tif, strip) - tif->tif_rawdataoff - tif->tif_rawdataloaded ) { - to_read = (tmsize_t) td->td_stripbytecount[strip] + to_read = (tmsize_t) TIFFGetStrileByteCount(tif, strip) - tif->tif_rawdataoff - tif->tif_rawdataloaded; } @@ -282,7 +300,7 @@ TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart ) /* For JPEG, if there are multiple scans (can generally be known */ /* with the read_ahead used), we need to read the whole strip */ if( tif->tif_dir.td_compression==COMPRESSION_JPEG && - (uint64)tif->tif_rawcc < td->td_stripbytecount[strip] ) + (uint64)tif->tif_rawcc < TIFFGetStrileByteCount(tif, strip) ) { if( TIFFJPEGIsFullStripRequired(tif) ) { @@ -341,9 +359,7 @@ TIFFSeek(TIFF* tif, uint32 row, uint16 sample ) * read it a few lines at a time? */ #if defined(CHUNKY_STRIP_READ_SUPPORT) - if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount) - return 0; - whole_strip = tif->tif_dir.td_stripbytecount[strip] < 10 + whole_strip = TIFFGetStrileByteCount(tif, strip) < 10 || isMapped(tif); if( td->td_compression == COMPRESSION_LERC || td->td_compression == COMPRESSION_JBIG ) @@ -396,7 +412,7 @@ TIFFSeek(TIFF* tif, uint32 row, uint16 sample ) else if( !whole_strip ) { if( ((tif->tif_rawdata + tif->tif_rawdataloaded) - tif->tif_rawcp) < read_ahead - && (uint64) tif->tif_rawdataoff+tif->tif_rawdataloaded < td->td_stripbytecount[strip] ) + && (uint64) tif->tif_rawdataoff+tif->tif_rawdataloaded < TIFFGetStrileByteCount(tif, strip) ) { if( !TIFFFillStripPartial(tif,strip,read_ahead,0) ) return 0; @@ -593,16 +609,11 @@ static tmsize_t TIFFReadRawStrip1(TIFF* tif, uint32 strip, void* buf, tmsize_t size, const char* module) { - TIFFDirectory *td = &tif->tif_dir; - - if (!_TIFFFillStriles( tif )) - return ((tmsize_t)(-1)); - assert((tif->tif_flags&TIFF_NOREADRAW)==0); if (!isMapped(tif)) { tmsize_t cc; - if (!SeekOK(tif, td->td_stripoffset[strip])) { + if (!SeekOK(tif, TIFFGetStrileOffset(tif, strip))) { TIFFErrorExt(tif->tif_clientdata, module, "Seek error at scanline %lu, strip %lu", (unsigned long) tif->tif_row, (unsigned long) strip); @@ -628,8 +639,8 @@ TIFFReadRawStrip1(TIFF* tif, uint32 strip, void* buf, tmsize_t size, } else { tmsize_t ma = 0; tmsize_t n; - if ((td->td_stripoffset[strip] > (uint64)TIFF_TMSIZE_T_MAX)|| - ((ma=(tmsize_t)td->td_stripoffset[strip])>tif->tif_size)) + if ((TIFFGetStrileOffset(tif, strip) > (uint64)TIFF_TMSIZE_T_MAX)|| + ((ma=(tmsize_t)TIFFGetStrileOffset(tif, strip))>tif->tif_size)) { n=0; } @@ -673,12 +684,10 @@ static tmsize_t TIFFReadRawStripOrTile2(TIFF* tif, uint32 strip_or_tile, int is_strip, tmsize_t size, const char* module) { - TIFFDirectory *td = &tif->tif_dir; - assert( !isMapped(tif) ); assert((tif->tif_flags&TIFF_NOREADRAW)==0); - if (!SeekOK(tif, td->td_stripoffset[strip_or_tile])) { + if (!SeekOK(tif, TIFFGetStrileOffset(tif, strip_or_tile))) { if( is_strip ) { TIFFErrorExt(tif->tif_clientdata, module, @@ -714,7 +723,7 @@ TIFFReadRawStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size) { static const char module[] = "TIFFReadRawStrip"; TIFFDirectory *td = &tif->tif_dir; - uint64 bytecount; + uint64 bytecount64; tmsize_t bytecountm; if (!TIFFCheckRead(tif, 0)) @@ -732,16 +741,23 @@ TIFFReadRawStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size) "Compression scheme does not support access to raw uncompressed data"); return ((tmsize_t)(-1)); } - bytecount = td->td_stripbytecount[strip]; - bytecountm = _TIFFCastUInt64ToSSize(tif, bytecount, module); - if (bytecountm == 0) { + bytecount64 = TIFFGetStrileByteCount(tif, strip); + if (size != (tmsize_t)(-1) && (uint64)size <= bytecount64) + bytecountm = size; + else + bytecountm = _TIFFCastUInt64ToSSize(tif, bytecount64, module); + if( bytecountm == 0 ) { return ((tmsize_t)(-1)); } - if (size != (tmsize_t)(-1) && size < bytecountm) - bytecountm = size; return (TIFFReadRawStrip1(tif, strip, buf, bytecountm, module)); } +TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW +static uint64 NoSantizeSubUInt64(uint64 a, uint64 b) +{ + return a - b; +} + /* * Read the specified strip and setup for decoding. The data buffer is * expanded, as necessary, to hold the strip's data. @@ -752,12 +768,9 @@ TIFFFillStrip(TIFF* tif, uint32 strip) static const char module[] = "TIFFFillStrip"; TIFFDirectory *td = &tif->tif_dir; - if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount) - return 0; - if ((tif->tif_flags&TIFF_NOREADRAW)==0) { - uint64 bytecount = td->td_stripbytecount[strip]; + uint64 bytecount = TIFFGetStrileByteCount(tif, strip); if( bytecount == 0 || bytecount > (uint64)TIFF_INT64_MAX ) { #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) TIFFErrorExt(tif->tif_clientdata, module, @@ -810,13 +823,13 @@ TIFFFillStrip(TIFF* tif, uint32 strip) * We must check for overflow, potentially causing * an OOB read. Instead of simple * - * td->td_stripoffset[strip]+bytecount > tif->tif_size + * TIFFGetStrileOffset(tif, strip)+bytecount > tif->tif_size * * comparison (which can overflow) we do the following * two comparisons: */ if (bytecount > (uint64)tif->tif_size || - td->td_stripoffset[strip] > (uint64)tif->tif_size - bytecount) { + TIFFGetStrileOffset(tif, strip) > (uint64)tif->tif_size - bytecount) { /* * This error message might seem strange, but * it's what would happen if a read were done @@ -828,7 +841,7 @@ TIFFFillStrip(TIFF* tif, uint32 strip) "Read error on strip %lu; " "got %I64u bytes, expected %I64u", (unsigned long) strip, - (unsigned __int64) tif->tif_size - td->td_stripoffset[strip], + (unsigned __int64) NoSantizeSubUInt64(tif->tif_size, TIFFGetStrileOffset(tif, strip)), (unsigned __int64) bytecount); #else TIFFErrorExt(tif->tif_clientdata, module, @@ -836,7 +849,7 @@ TIFFFillStrip(TIFF* tif, uint32 strip) "Read error on strip %lu; " "got %llu bytes, expected %llu", (unsigned long) strip, - (unsigned long long) tif->tif_size - td->td_stripoffset[strip], + (unsigned long long) NoSantizeSubUInt64(tif->tif_size, TIFFGetStrileOffset(tif, strip)), (unsigned long long) bytecount); #endif tif->tif_curstrip = NOSTRIP; @@ -865,7 +878,7 @@ TIFFFillStrip(TIFF* tif, uint32 strip) } tif->tif_flags &= ~TIFF_MYBUFFER; tif->tif_rawdatasize = (tmsize_t)bytecount; - tif->tif_rawdata = tif->tif_base + (tmsize_t)td->td_stripoffset[strip]; + tif->tif_rawdata = tif->tif_base + (tmsize_t)TIFFGetStrileOffset(tif, strip); tif->tif_rawdataoff = 0; tif->tif_rawdataloaded = (tmsize_t) bytecount; @@ -1080,16 +1093,11 @@ _TIFFReadEncodedTileAndAllocBuffer(TIFF* tif, uint32 tile, static tmsize_t TIFFReadRawTile1(TIFF* tif, uint32 tile, void* buf, tmsize_t size, const char* module) { - TIFFDirectory *td = &tif->tif_dir; - - if (!_TIFFFillStriles( tif )) - return ((tmsize_t)(-1)); - assert((tif->tif_flags&TIFF_NOREADRAW)==0); if (!isMapped(tif)) { tmsize_t cc; - if (!SeekOK(tif, td->td_stripoffset[tile])) { + if (!SeekOK(tif, TIFFGetStrileOffset(tif, tile))) { TIFFErrorExt(tif->tif_clientdata, module, "Seek error at row %lu, col %lu, tile %lu", (unsigned long) tif->tif_row, @@ -1119,9 +1127,9 @@ TIFFReadRawTile1(TIFF* tif, uint32 tile, void* buf, tmsize_t size, const char* m } else { tmsize_t ma,mb; tmsize_t n; - ma=(tmsize_t)td->td_stripoffset[tile]; + ma=(tmsize_t)TIFFGetStrileOffset(tif, tile); mb=ma+size; - if ((td->td_stripoffset[tile] > (uint64)TIFF_TMSIZE_T_MAX)||(ma>tif->tif_size)) + if ((TIFFGetStrileOffset(tif, tile) > (uint64)TIFF_TMSIZE_T_MAX)||(ma>tif->tif_size)) n=0; else if ((mbtif->tif_size)) n=tif->tif_size-ma; @@ -1177,11 +1185,12 @@ TIFFReadRawTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size) "Compression scheme does not support access to raw uncompressed data"); return ((tmsize_t)(-1)); } - bytecount64 = td->td_stripbytecount[tile]; - if (size != (tmsize_t)(-1) && (uint64)size < bytecount64) - bytecount64 = (uint64)size; - bytecountm = _TIFFCastUInt64ToSSize(tif, bytecount64, module); - if( bytecountm == 0 ) { + bytecount64 = TIFFGetStrileByteCount(tif, tile); + if (size != (tmsize_t)(-1) && (uint64)size <= bytecount64) + bytecountm = size; + else + bytecountm = _TIFFCastUInt64ToSSize(tif, bytecount64, module); + if( bytecountm == 0 ) { return ((tmsize_t)(-1)); } return (TIFFReadRawTile1(tif, tile, buf, bytecountm, module)); @@ -1197,12 +1206,9 @@ TIFFFillTile(TIFF* tif, uint32 tile) static const char module[] = "TIFFFillTile"; TIFFDirectory *td = &tif->tif_dir; - if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount) - return 0; - if ((tif->tif_flags&TIFF_NOREADRAW)==0) { - uint64 bytecount = td->td_stripbytecount[tile]; + uint64 bytecount = TIFFGetStrileByteCount(tif, tile); if( bytecount == 0 || bytecount > (uint64)TIFF_INT64_MAX ) { #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) TIFFErrorExt(tif->tif_clientdata, module, @@ -1255,13 +1261,13 @@ TIFFFillTile(TIFF* tif, uint32 tile) * We must check for overflow, potentially causing * an OOB read. Instead of simple * - * td->td_stripoffset[tile]+bytecount > tif->tif_size + * TIFFGetStrileOffset(tif, tile)+bytecount > tif->tif_size * * comparison (which can overflow) we do the following * two comparisons: */ if (bytecount > (uint64)tif->tif_size || - td->td_stripoffset[tile] > (uint64)tif->tif_size - bytecount) { + TIFFGetStrileOffset(tif, tile) > (uint64)tif->tif_size - bytecount) { tif->tif_curtile = NOTILE; return (0); } @@ -1290,7 +1296,7 @@ TIFFFillTile(TIFF* tif, uint32 tile) tif->tif_rawdatasize = (tmsize_t)bytecount; tif->tif_rawdata = - tif->tif_base + (tmsize_t)td->td_stripoffset[tile]; + tif->tif_base + (tmsize_t)TIFFGetStrileOffset(tif, tile); tif->tif_rawdataoff = 0; tif->tif_rawdataloaded = (tmsize_t) bytecount; tif->tif_flags |= TIFF_BUFFERMMAP; @@ -1349,7 +1355,8 @@ TIFFFillTile(TIFF* tif, uint32 tile) tif->tif_rawdataoff = 0; tif->tif_rawdataloaded = bytecountm; - if (!isFillOrder(tif, td->td_fillorder) && + if (tif->tif_rawdata != NULL && + !isFillOrder(tif, td->td_fillorder) && (tif->tif_flags & TIFF_NOBITREV) == 0) TIFFReverseBits(tif->tif_rawdata, tif->tif_rawdataloaded); @@ -1416,9 +1423,6 @@ TIFFStartStrip(TIFF* tif, uint32 strip) { TIFFDirectory *td = &tif->tif_dir; - if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount) - return 0; - if ((tif->tif_flags & TIFF_CODERSETUP) == 0) { if (!(*tif->tif_setupdecode)(tif)) return (0); @@ -1439,7 +1443,7 @@ TIFFStartStrip(TIFF* tif, uint32 strip) if( tif->tif_rawdataloaded > 0 ) tif->tif_rawcc = tif->tif_rawdataloaded; else - tif->tif_rawcc = (tmsize_t)td->td_stripbytecount[strip]; + tif->tif_rawcc = (tmsize_t)TIFFGetStrileByteCount(tif, strip); } return ((*tif->tif_predecode)(tif, (uint16)(strip / td->td_stripsperimage))); @@ -1456,9 +1460,6 @@ TIFFStartTile(TIFF* tif, uint32 tile) TIFFDirectory *td = &tif->tif_dir; uint32 howmany32; - if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount) - return 0; - if ((tif->tif_flags & TIFF_CODERSETUP) == 0) { if (!(*tif->tif_setupdecode)(tif)) return (0); @@ -1489,7 +1490,7 @@ TIFFStartTile(TIFF* tif, uint32 tile) if( tif->tif_rawdataloaded > 0 ) tif->tif_rawcc = tif->tif_rawdataloaded; else - tif->tif_rawcc = (tmsize_t)td->td_stripbytecount[tile]; + tif->tif_rawcc = (tmsize_t)TIFFGetStrileByteCount(tif, tile); } return ((*tif->tif_predecode)(tif, (uint16)(tile/td->td_stripsperimage))); @@ -1504,13 +1505,100 @@ TIFFCheckRead(TIFF* tif, int tiles) } if (tiles ^ isTiled(tif)) { TIFFErrorExt(tif->tif_clientdata, tif->tif_name, tiles ? - "Can not read tiles from a stripped image" : + "Can not read tiles from a striped image" : "Can not read scanlines from a tiled image"); return (0); } return (1); } +/* Use the provided input buffer (inbuf, insize) and decompress it into + * (outbuf, outsize). + * This function replaces the use of TIFFReadEncodedStrip()/TIFFReadEncodedTile() + * when the user can provide the buffer for the input data, for example when + * he wants to avoid libtiff to read the strile offset/count values from the + * [Strip|Tile][Offsets/ByteCounts] array. + * inbuf content must be writable (if bit reversal is needed) + * Returns 1 in case of success, 0 otherwise. + */ +int TIFFReadFromUserBuffer(TIFF* tif, uint32 strile, + void* inbuf, tmsize_t insize, + void* outbuf, tmsize_t outsize) +{ + static const char module[] = "TIFFReadFromUserBuffer"; + TIFFDirectory *td = &tif->tif_dir; + int ret = 1; + uint32 old_tif_flags = tif->tif_flags; + tmsize_t old_rawdatasize = tif->tif_rawdatasize; + void* old_rawdata = tif->tif_rawdata; + + if (tif->tif_mode == O_WRONLY) { + TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "File not open for reading"); + return 0; + } + if (tif->tif_flags&TIFF_NOREADRAW) + { + TIFFErrorExt(tif->tif_clientdata, module, + "Compression scheme does not support access to raw uncompressed data"); + return 0; + } + + tif->tif_flags &= ~TIFF_MYBUFFER; + tif->tif_flags |= TIFF_BUFFERMMAP; + tif->tif_rawdatasize = insize; + tif->tif_rawdata = inbuf; + tif->tif_rawdataoff = 0; + tif->tif_rawdataloaded = insize; + + if (!isFillOrder(tif, td->td_fillorder) && + (tif->tif_flags & TIFF_NOBITREV) == 0) + { + TIFFReverseBits(inbuf, insize); + } + + if( TIFFIsTiled(tif) ) + { + if( !TIFFStartTile(tif, strile) || + !(*tif->tif_decodetile)(tif, (uint8*) outbuf, outsize, + (uint16)(strile/td->td_stripsperimage)) ) + { + ret = 0; + } + } + else + { + uint32 rowsperstrip=td->td_rowsperstrip; + uint32 stripsperplane; + if (rowsperstrip>td->td_imagelength) + rowsperstrip=td->td_imagelength; + stripsperplane= TIFFhowmany_32_maxuint_compat(td->td_imagelength, rowsperstrip); + if( !TIFFStartStrip(tif, strile) || + !(*tif->tif_decodestrip)(tif, (uint8*) outbuf, outsize, + (uint16)(strile/stripsperplane)) ) + { + ret = 0; + } + } + if( ret ) + { + (*tif->tif_postdecode)(tif, (uint8*) outbuf, outsize); + } + + if (!isFillOrder(tif, td->td_fillorder) && + (tif->tif_flags & TIFF_NOBITREV) == 0) + { + TIFFReverseBits(inbuf, insize); + } + + tif->tif_flags = old_tif_flags; + tif->tif_rawdatasize = old_rawdatasize; + tif->tif_rawdata = old_rawdata; + tif->tif_rawdataoff = 0; + tif->tif_rawdataloaded = 0; + + return ret; +} + void _TIFFNoPostDecode(TIFF* tif, uint8* buf, tmsize_t cc) { -- cgit v1.2.3