-/* $Id: tif_dirread.c,v 1.174 2012-02-01 02:24:47 fwarmerdam Exp $ */
+/* $Id: tif_dirread.c,v 1.191 2015-09-05 20:31:41 bfriesen Exp $ */
/*
* Copyright (c) 1988-1997 Sam Leffler
break;
}
_TIFFfree(origdata);
- if (err!=TIFFReadDirEntryErrOk)
- {
- _TIFFfree(data);
- return(err);
- }
*value=data;
return(TIFFReadDirEntryErrOk);
}
break;
}
_TIFFfree(origdata);
- if (err!=TIFFReadDirEntryErrOk)
- {
- _TIFFfree(data);
- return(err);
- }
*value=data;
return(TIFFReadDirEntryErrOk);
}
break;
}
_TIFFfree(origdata);
- if (err!=TIFFReadDirEntryErrOk)
- {
- _TIFFfree(data);
- return(err);
- }
*value=data;
return(TIFFReadDirEntryErrOk);
}
break;
}
_TIFFfree(origdata);
- if (err!=TIFFReadDirEntryErrOk)
- {
- _TIFFfree(data);
- return(err);
- }
*value=data;
return(TIFFReadDirEntryErrOk);
}
/*
* Largest 32-bit unsigned integer value.
*/
-#if defined(__WIN32__) && defined(_MSC_VER)
-# define TIFF_UINT32_MAX 0xFFFFFFFFI64
-#else
-# define TIFF_UINT32_MAX 0xFFFFFFFFLL
-#endif
+#define TIFF_UINT32_MAX 0xFFFFFFFFU
static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeLongLong8(uint64 value)
static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeLongSlong8(int64 value)
{
- if ((value<0) || (value > TIFF_UINT32_MAX))
+ if ((value < 0) || (value > (int64) TIFF_UINT32_MAX))
return(TIFFReadDirEntryErrRange);
else
return(TIFFReadDirEntryErrOk);
return(TIFFReadDirEntryErrOk);
}
+/* Check that the 8-byte unsigned value can fit in a 4-byte unsigned range */
static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeSlongLong8(uint64 value)
{
- if (value > 0x7FFFFFFFUL)
+ if (value > 0x7FFFFFFF)
return(TIFFReadDirEntryErrRange);
else
return(TIFFReadDirEntryErrOk);
}
+/* Check that the 8-byte signed value can fit in a 4-byte signed range */
static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeSlongSlong8(int64 value)
{
- if ((value < 0L-0x80000000L) || (value > 0x7FFFFFFFL))
+ if ((value < 0-((int64) 0x7FFFFFFF+1)) || (value > 0x7FFFFFFF))
return(TIFFReadDirEntryErrRange);
else
return(TIFFReadDirEntryErrOk);
/*
* Largest 64-bit signed integer value.
*/
-#if defined(__WIN32__) && defined(_MSC_VER)
-# define TIFF_INT64_MAX 0x7FFFFFFFFFFFFFFFI64
-#else
-# define TIFF_INT64_MAX 0x7FFFFFFFFFFFFFFFLL
-#endif
+#define TIFF_INT64_MAX ((int64)(((uint64) ~0) >> 1))
static enum TIFFReadDirEntryErr
TIFFReadDirEntryCheckRangeSlong8Long8(uint64 value)
if (!ReadOK(tif,dest,size))
return(TIFFReadDirEntryErrIo);
} else {
- tmsize_t ma,mb;
- ma=(tmsize_t)offset;
+ size_t ma,mb;
+ ma=(size_t)offset;
mb=ma+size;
- if (((uint64)ma!=offset)||(mb<ma)||(mb<size)||(mb>tif->tif_size))
+ if (((uint64)ma!=offset)
+ || (mb < ma)
+ || (mb - ma != (size_t) size)
+ || (mb < (size_t)size)
+ || (mb > (size_t)tif->tif_size)
+ )
return(TIFFReadDirEntryErrIo);
_TIFFmemcpy(dest,tif->tif_base+ma,size);
}
} else {
switch (err) {
case TIFFReadDirEntryErrCount:
- TIFFErrorExt(tif->tif_clientdata, module,
+ TIFFWarningExt(tif->tif_clientdata, module,
"Incorrect count for \"%s\"; tag ignored",
tagname);
break;
const TIFFField* fip;
uint32 fii=FAILED_FII;
toff_t nextdiroff;
+ int bitspersample_read = FALSE;
+
tif->tif_diroff=tif->tif_nextdiroff;
if (!TIFFCheckDirOffset(tif,tif->tif_nextdiroff))
return 0; /* last offset or bad offset (IFD looping) */
}
if (!TIFFSetField(tif,dp->tdir_tag,value))
goto bad;
+ if( dp->tdir_tag == TIFFTAG_BITSPERSAMPLE )
+ bitspersample_read = TRUE;
}
break;
case TIFFTAG_SMINSAMPLEVALUE:
uint32 countrequired;
uint32 incrementpersample;
uint16* value=NULL;
+ /* It would be dangerous to instanciate those tag values */
+ /* since if td_bitspersample has not yet been read (due to */
+ /* unordered tags), it could be read afterwards with a */
+ /* values greater than the default one (1), which may cause */
+ /* crashes in user code */
+ if( !bitspersample_read )
+ {
+ fip = TIFFFieldWithTag(tif,dp->tdir_tag);
+ TIFFWarningExt(tif->tif_clientdata,module,
+ "Ignoring %s since BitsPerSample tag not found",
+ fip ? fip->field_name : "unknown tagname");
+ continue;
+ }
countpersample=(1L<<tif->tif_dir.td_bitspersample);
if ((dp->tdir_tag==TIFFTAG_TRANSFERFUNCTION)&&(dp->tdir_count==(uint64)countpersample))
{
TIFFDirectory *td = &tif->tif_dir;
uint32 strip;
- _TIFFFillStriles( tif );
+ if( !_TIFFFillStriles( tif ) )
+ return -1;
if (td->td_stripbytecount)
_TIFFfree(td->td_stripbytecount);
if (diroff == 0) /* no more directories */
return 0;
+ if (tif->tif_dirnumber == 65535) {
+ TIFFErrorExt(tif->tif_clientdata, "TIFFCheckDirOffset",
+ "Cannot handle more than 65535 TIFF directories");
+ return 0;
+ }
for (n = 0; n < tif->tif_dirnumber && tif->tif_dirlist; n++) {
if (tif->tif_dirlist[n] == diroff)
tif->tif_dirnumber, 2 * sizeof(uint64), "for IFD list");
if (!new_dirlist)
return 0;
- tif->tif_dirlistsize = 2 * tif->tif_dirnumber;
+ if( tif->tif_dirnumber >= 32768 )
+ tif->tif_dirlistsize = 65535;
+ else
+ tif->tif_dirlistsize = 2 * tif->tif_dirnumber;
tif->tif_dirlist = new_dirlist;
}
return 0;
}
fip=tif->tif_fields[fii];
+ assert(fip != NULL); /* should not happen */
assert(fip->set_field_type!=TIFF_SETGET_OTHER); /* if so, we shouldn't arrive here but deal with this in specialized code */
assert(fip->set_field_type!=TIFF_SETGET_INT); /* if so, we shouldn't arrive here as this is only the case for pseudo-tags */
err=TIFFReadDirEntryErrOk;
break;
case TIFF_SETGET_UINT8:
{
- uint8 data;
+ uint8 data=0;
assert(fip->field_readcount==1);
assert(fip->field_passcount==0);
err=TIFFReadDirEntryByte(tif,dp,&data);
uint16* data;
assert(fip->field_readcount==2);
assert(fip->field_passcount==0);
- if (dp->tdir_count!=2)
+ if (dp->tdir_count!=2) {
+ TIFFWarningExt(tif->tif_clientdata,module,
+ "incorrect count for field \"%s\", expected 2, got %d",
+ fip->field_name,(int)dp->tdir_count);
return(0);
+ }
err=TIFFReadDirEntryShortArray(tif,dp,&data);
if (err==TIFFReadDirEntryErrOk)
{
uint8* data;
assert(fip->field_readcount>=1);
assert(fip->field_passcount==0);
- if (dp->tdir_count!=(uint64)fip->field_readcount)
- /* corrupt file */;
+ if (dp->tdir_count!=(uint64)fip->field_readcount) {
+ TIFFWarningExt(tif->tif_clientdata,module,
+ "incorrect count for field \"%s\", expected %d, got %d",
+ fip->field_name,(int) fip->field_readcount, (int)dp->tdir_count);
+ return 0;
+ }
else
{
err=TIFFReadDirEntryByteArray(tif,dp,&data);
}
if (err!=TIFFReadDirEntryErrOk)
{
- TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown tagname",recover);
+ TIFFReadDirEntryOutputErr(tif,err,module,fip->field_name,recover);
return(0);
}
return(1);