| diff --git a/third_party/libtiff/tif_dirread.c b/third_party/libtiff/tif_dirread.c |
| index 7dd944483..d50b39a80 100644 |
| --- a/third_party/libtiff/tif_dirread.c |
| +++ b/third_party/libtiff/tif_dirread.c |
| @@ -790,44 +790,43 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryArray(TIFF* tif, TIFFDirEntry* d |
| *count=(uint32)direntry->tdir_count; |
| datasize=(*count)*typesize; |
| assert((tmsize_t)datasize>0); |
| - data=_TIFFCheckMalloc(tif, *count, typesize, "ReadDirEntryArray"); |
| - if (data==0) |
| - return(TIFFReadDirEntryErrAlloc); |
| + const uint32 small_alloc_threshold=(tif->tif_flags&TIFF_BIGTIFF)? 8 : 4; |
| + if (datasize <= small_alloc_threshold) |
| + { |
| + data=_TIFFCheckMalloc(tif, *count, typesize, "ReadDirEntryArray"); |
| + if (data==0) |
| + return(TIFFReadDirEntryErrAlloc); |
| + _TIFFmemcpy(data,&direntry->tdir_offset,datasize); |
| + *value=data; |
| + return(TIFFReadDirEntryErrOk); |
| + } |
| + uint64 offset; |
| if (!(tif->tif_flags&TIFF_BIGTIFF)) |
| { |
| - if (datasize<=4) |
| - _TIFFmemcpy(data,&direntry->tdir_offset,datasize); |
| - else |
| - { |
| - enum TIFFReadDirEntryErr err; |
| - uint32 offset = direntry->tdir_offset.toff_long; |
| - if (tif->tif_flags&TIFF_SWAB) |
| - TIFFSwabLong(&offset); |
| - err=TIFFReadDirEntryData(tif,(uint64)offset,(tmsize_t)datasize,data); |
| - if (err!=TIFFReadDirEntryErrOk) |
| - { |
| - _TIFFfree(data); |
| - return(err); |
| - } |
| - } |
| + uint32 small_offset=direntry->tdir_offset.toff_long; |
| + if (tif->tif_flags&TIFF_SWAB) |
| + TIFFSwabLong(&small_offset); |
| + offset=(uint64)small_offset; |
| } |
| else |
| { |
| - if (datasize<=8) |
| - _TIFFmemcpy(data,&direntry->tdir_offset,datasize); |
| - else |
| - { |
| - enum TIFFReadDirEntryErr err; |
| - uint64 offset = direntry->tdir_offset.toff_long8; |
| - if (tif->tif_flags&TIFF_SWAB) |
| - TIFFSwabLong8(&offset); |
| - err=TIFFReadDirEntryData(tif,offset,(tmsize_t)datasize,data); |
| - if (err!=TIFFReadDirEntryErrOk) |
| - { |
| - _TIFFfree(data); |
| - return(err); |
| - } |
| - } |
| + offset = direntry->tdir_offset.toff_long8; |
| + if (tif->tif_flags&TIFF_SWAB) |
| + TIFFSwabLong8(&offset); |
| + } |
| + if ((uint64)(-1) - offset < datasize) |
| + return(TIFFReadDirEntryErrIo); |
| + const uint64 size=isMapped(tif)? (uint64)tif->tif_size : TIFFGetFileSize(tif); |
| + if (offset + datasize > size) |
| + return(TIFFReadDirEntryErrIo); |
| + data=_TIFFCheckMalloc(tif, *count, typesize, "ReadDirEntryArray"); |
| + if (data==0) |
| + return(TIFFReadDirEntryErrAlloc); |
| + enum TIFFReadDirEntryErr err=TIFFReadDirEntryData(tif,offset,(tmsize_t)datasize,data); |
| + if (err!=TIFFReadDirEntryErrOk) |
| + { |
| + _TIFFfree(data); |
| + return(err); |
| } |
| *value=data; |
| return(TIFFReadDirEntryErrOk); |