From f13cf46b6ecb97503afcfa6f41a18d6697076179 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 8 Dec 2020 16:09:17 +0100 Subject: [PATCH] TIFFReadDirEntryArrayWithLimit(): properly read from offline tag value when we clamp the number of strips to 1. Fixes regression of commit 7057734d986001b7fd6d2afde9667da7754ff2cc on reading a file with StripByteCounts with 1 element (broken) and StripOffsets with 896 elements, and where StripOffsets[0] is correct $ tiffdump foo.tif Magic: 0x4949 Version: 0x2a Directory 0: offset 25725448 (0x1888a08) next 0 (0) SubFileType (254) LONG (4) 1<0> ImageWidth (256) LONG (4) 1<640> ImageLength (257) LONG (4) 1<20098> BitsPerSample (258) SHORT (3) 1<16> Photometric (262) SHORT (3) 1<1> SamplesPerPixel (277) SHORT (3) 1<1> ResolutionUnit (296) SHORT (3) 1<2> StripByteCounts (279) LONG (4) 1<1806> StripOffsets (273) LONG (4) 896<8 648 1288 1928 2568 3208 3848 4488 5128 5768 6408 7048 7688 8328 8968 9608 10248 10888 11528 12168 12808 13448 14088 14728 ...> --- libtiff/tif_dirread.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/libtiff/tif_dirread.c b/libtiff/tif_dirread.c index e9fe5c35..ba127ca9 100644 --- a/libtiff/tif_dirread.c +++ b/libtiff/tif_dirread.c @@ -838,6 +838,7 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryArrayWithLimit( uint32 datasize; void* data; uint64 target_count64; + int original_datasize_clamped; typesize=TIFFDataWidth(direntry->tdir_type); target_count64 = (direntry->tdir_count > maxcount) ? @@ -850,6 +851,12 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryArrayWithLimit( } (void) desttypesize; + /* We just want to know if the original tag size is more than 4 bytes + * (classic TIFF) or 8 bytes (BigTIFF) + */ + original_datasize_clamped = + ((direntry->tdir_count > 10) ? 10 : (int)direntry->tdir_count) * typesize; + /* * As a sanity check, make sure we have no more than a 2GB tag array * in either the current data type or the dest data type. This also @@ -881,7 +888,7 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryArrayWithLimit( } if (!(tif->tif_flags&TIFF_BIGTIFF)) { - if (datasize<=4) + if (original_datasize_clamped<=4) _TIFFmemcpy(data,&direntry->tdir_offset,datasize); else { @@ -902,7 +909,7 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryArrayWithLimit( } else { - if (datasize<=8) + if (original_datasize_clamped<=8) _TIFFmemcpy(data,&direntry->tdir_offset,datasize); else {