summaryrefslogtreecommitdiff
path: root/third_party/libtiff/tif_dirread.c
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/libtiff/tif_dirread.c')
-rw-r--r--third_party/libtiff/tif_dirread.c65
1 files changed, 32 insertions, 33 deletions
diff --git a/third_party/libtiff/tif_dirread.c b/third_party/libtiff/tif_dirread.c
index 7dd9444834..d50b39a809 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);