| diff --git a/third_party/libtiff/tif_dir.c b/third_party/libtiff/tif_dir.c |
| index 81b849374..72148411f 100644 |
| --- a/third_party/libtiff/tif_dir.c |
| +++ b/third_party/libtiff/tif_dir.c |
| @@ -31,6 +31,7 @@ |
| * (and also some miscellaneous stuff) |
| */ |
| #include "tiffiop.h" |
| +#include <float.h> |
| |
| /* |
| * These are used in the backwards compatibility code... |
| @@ -154,6 +155,15 @@ bad: |
| return (0); |
| } |
| |
| +static float TIFFClampDoubleToFloat( double val ) |
| +{ |
| + if( val > FLT_MAX ) |
| + return FLT_MAX; |
| + if( val < -FLT_MAX ) |
| + return -FLT_MAX; |
| + return (float)val; |
| +} |
| + |
| static int |
| _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap) |
| { |
| @@ -312,13 +322,13 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap) |
| dblval = va_arg(ap, double); |
| if( dblval < 0 ) |
| goto badvaluedouble; |
| - td->td_xresolution = (float) dblval; |
| + td->td_xresolution = TIFFClampDoubleToFloat( dblval ); |
| break; |
| case TIFFTAG_YRESOLUTION: |
| dblval = va_arg(ap, double); |
| if( dblval < 0 ) |
| goto badvaluedouble; |
| - td->td_yresolution = (float) dblval; |
| + td->td_yresolution = TIFFClampDoubleToFloat( dblval ); |
| break; |
| case TIFFTAG_PLANARCONFIG: |
| v = (uint16) va_arg(ap, uint16_vap); |
| @@ -327,10 +337,10 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap) |
| td->td_planarconfig = (uint16) v; |
| break; |
| case TIFFTAG_XPOSITION: |
| - td->td_xposition = (float) va_arg(ap, double); |
| + td->td_xposition = TIFFClampDoubleToFloat( va_arg(ap, double) ); |
| break; |
| case TIFFTAG_YPOSITION: |
| - td->td_yposition = (float) va_arg(ap, double); |
| + td->td_yposition = TIFFClampDoubleToFloat( va_arg(ap, double) ); |
| break; |
| case TIFFTAG_RESOLUTIONUNIT: |
| v = (uint16) va_arg(ap, uint16_vap); |
| diff --git a/third_party/libtiff/tif_dirread.c b/third_party/libtiff/tif_dirread.c |
| index 7dbcf6d86..0926e1625 100644 |
| --- a/third_party/libtiff/tif_dirread.c |
| +++ b/third_party/libtiff/tif_dirread.c |
| @@ -40,6 +40,7 @@ |
| */ |
| |
| #include "tiffiop.h" |
| +#include <float.h> |
| |
| #define IGNORE 0 /* tag placeholder used below */ |
| #define FAILED_FII ((uint32) -1) |
| @@ -2405,7 +2406,14 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryFloatArray(TIFF* tif, TIFFDirEnt |
| ma=(double*)origdata; |
| mb=data; |
| for (n=0; n<count; n++) |
| - *mb++=(float)(*ma++); |
| + { |
| + double val = *ma++; |
| + if( val > FLT_MAX ) |
| + val = FLT_MAX; |
| + else if( val < -FLT_MAX ) |
| + val = -FLT_MAX; |
| + *mb++=(float)val; |
| + } |
| } |
| break; |
| } |
| @@ -2871,7 +2879,10 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedRational(TIFF* tif, TIFFD |
| m.l = direntry->tdir_offset.toff_long8; |
| if (tif->tif_flags&TIFF_SWAB) |
| TIFFSwabArrayOfLong(m.i,2); |
| - if (m.i[0]==0) |
| + /* Not completely sure what we should do when m.i[1]==0, but some */ |
| + /* sanitizers do not like division by 0.0: */ |
| + /* http://bugzilla.maptools.org/show_bug.cgi?id=2644 */ |
| + if (m.i[0]==0 || m.i[1]==0) |
| *value=0.0; |
| else |
| *value=(double)m.i[0]/(double)m.i[1]; |
| @@ -2899,7 +2910,10 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedSrational(TIFF* tif, TIFF |
| m.l=direntry->tdir_offset.toff_long8; |
| if (tif->tif_flags&TIFF_SWAB) |
| TIFFSwabArrayOfLong(m.i,2); |
| - if ((int32)m.i[0]==0) |
| + /* Not completely sure what we should do when m.i[1]==0, but some */ |
| + /* sanitizers do not like division by 0.0: */ |
| + /* http://bugzilla.maptools.org/show_bug.cgi?id=2644 */ |
| + if ((int32)m.i[0]==0 || m.i[1]==0) |
| *value=0.0; |
| else |
| *value=(double)((int32)m.i[0])/(double)m.i[1]; |
| diff --git a/third_party/libtiff/tif_dirwrite.c b/third_party/libtiff/tif_dirwrite.c |
| index d34f6f611..f4d8034ec 100644 |
| --- a/third_party/libtiff/tif_dirwrite.c |
| +++ b/third_party/libtiff/tif_dirwrite.c |
| @@ -30,6 +30,7 @@ |
| * Directory Write Support Routines. |
| */ |
| #include "tiffiop.h" |
| +#include <float.h> |
| |
| #ifdef HAVE_IEEEFP |
| #define TIFFCvtNativeToIEEEFloat(tif, n, fp) |
| @@ -939,6 +940,69 @@ bad: |
| return(0); |
| } |
| |
| +static float TIFFClampDoubleToFloat( double val ) |
| +{ |
| + if( val > FLT_MAX ) |
| + return FLT_MAX; |
| + if( val < -FLT_MAX ) |
| + return -FLT_MAX; |
| + return (float)val; |
| +} |
| + |
| +static int8 TIFFClampDoubleToInt8( double val ) |
| +{ |
| + if( val > 127 ) |
| + return 127; |
| + if( val < -128 || val != val ) |
| + return -128; |
| + return (int8)val; |
| +} |
| + |
| +static int16 TIFFClampDoubleToInt16( double val ) |
| +{ |
| + if( val > 32767 ) |
| + return 32767; |
| + if( val < -32768 || val != val ) |
| + return -32768; |
| + return (int16)val; |
| +} |
| + |
| +static int32 TIFFClampDoubleToInt32( double val ) |
| +{ |
| + if( val > 0x7FFFFFFF ) |
| + return 0x7FFFFFFF; |
| + if( val < -0x7FFFFFFF-1 || val != val ) |
| + return -0x7FFFFFFF-1; |
| + return (int32)val; |
| +} |
| + |
| +static uint8 TIFFClampDoubleToUInt8( double val ) |
| +{ |
| + if( val < 0 ) |
| + return 0; |
| + if( val > 255 || val != val ) |
| + return 255; |
| + return (uint8)val; |
| +} |
| + |
| +static uint16 TIFFClampDoubleToUInt16( double val ) |
| +{ |
| + if( val < 0 ) |
| + return 0; |
| + if( val > 65535 || val != val ) |
| + return 65535; |
| + return (uint16)val; |
| +} |
| + |
| +static uint32 TIFFClampDoubleToUInt32( double val ) |
| +{ |
| + if( val < 0 ) |
| + return 0; |
| + if( val > 0xFFFFFFFFU || val != val ) |
| + return 0xFFFFFFFFU; |
| + return (uint32)val; |
| +} |
| + |
| static int |
| TIFFWriteDirectoryTagSampleformatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value) |
| { |
| @@ -959,7 +1023,7 @@ TIFFWriteDirectoryTagSampleformatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* di |
| if (tif->tif_dir.td_bitspersample<=32) |
| { |
| for (i = 0; i < count; ++i) |
| - ((float*)conv)[i] = (float)value[i]; |
| + ((float*)conv)[i] = TIFFClampDoubleToFloat(value[i]); |
| ok = TIFFWriteDirectoryTagFloatArray(tif,ndir,dir,tag,count,(float*)conv); |
| } |
| else |
| @@ -971,19 +1035,19 @@ TIFFWriteDirectoryTagSampleformatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* di |
| if (tif->tif_dir.td_bitspersample<=8) |
| { |
| for (i = 0; i < count; ++i) |
| - ((int8*)conv)[i] = (int8)value[i]; |
| + ((int8*)conv)[i] = TIFFClampDoubleToInt8(value[i]); |
| ok = TIFFWriteDirectoryTagSbyteArray(tif,ndir,dir,tag,count,(int8*)conv); |
| } |
| else if (tif->tif_dir.td_bitspersample<=16) |
| { |
| for (i = 0; i < count; ++i) |
| - ((int16*)conv)[i] = (int16)value[i]; |
| + ((int16*)conv)[i] = TIFFClampDoubleToInt16(value[i]); |
| ok = TIFFWriteDirectoryTagSshortArray(tif,ndir,dir,tag,count,(int16*)conv); |
| } |
| else |
| { |
| for (i = 0; i < count; ++i) |
| - ((int32*)conv)[i] = (int32)value[i]; |
| + ((int32*)conv)[i] = TIFFClampDoubleToInt32(value[i]); |
| ok = TIFFWriteDirectoryTagSlongArray(tif,ndir,dir,tag,count,(int32*)conv); |
| } |
| break; |
| @@ -991,19 +1055,19 @@ TIFFWriteDirectoryTagSampleformatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* di |
| if (tif->tif_dir.td_bitspersample<=8) |
| { |
| for (i = 0; i < count; ++i) |
| - ((uint8*)conv)[i] = (uint8)value[i]; |
| + ((uint8*)conv)[i] = TIFFClampDoubleToUInt8(value[i]); |
| ok = TIFFWriteDirectoryTagByteArray(tif,ndir,dir,tag,count,(uint8*)conv); |
| } |
| else if (tif->tif_dir.td_bitspersample<=16) |
| { |
| for (i = 0; i < count; ++i) |
| - ((uint16*)conv)[i] = (uint16)value[i]; |
| + ((uint16*)conv)[i] = TIFFClampDoubleToUInt16(value[i]); |
| ok = TIFFWriteDirectoryTagShortArray(tif,ndir,dir,tag,count,(uint16*)conv); |
| } |
| else |
| { |
| for (i = 0; i < count; ++i) |
| - ((uint32*)conv)[i] = (uint32)value[i]; |
| + ((uint32*)conv)[i] = TIFFClampDoubleToUInt32(value[i]); |
| ok = TIFFWriteDirectoryTagLongArray(tif,ndir,dir,tag,count,(uint32*)conv); |
| } |
| break; |
| @@ -2094,15 +2158,25 @@ TIFFWriteDirectoryTagCheckedSlong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* d |
| static int |
| TIFFWriteDirectoryTagCheckedRational(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value) |
| { |
| + static const char module[] = "TIFFWriteDirectoryTagCheckedRational"; |
| uint32 m[2]; |
| - assert(value>=0.0); |
| assert(sizeof(uint32)==4); |
| - if (value<=0.0) |
| + if( value < 0 ) |
| + { |
| + TIFFErrorExt(tif->tif_clientdata,module,"Negative value is illegal"); |
| + return 0; |
| + } |
| + else if( value != value ) |
| + { |
| + TIFFErrorExt(tif->tif_clientdata,module,"Not-a-number value is illegal"); |
| + return 0; |
| + } |
| + else if (value==0.0) |
| { |
| m[0]=0; |
| m[1]=1; |
| } |
| - else if (value==(double)(uint32)value) |
| + else if (value <= 0xFFFFFFFFU && value==(double)(uint32)value) |
| { |
| m[0]=(uint32)value; |
| m[1]=1; |
| @@ -2143,12 +2217,13 @@ TIFFWriteDirectoryTagCheckedRationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* |
| } |
| for (na=value, nb=m, nc=0; nc<count; na++, nb+=2, nc++) |
| { |
| - if (*na<=0.0) |
| + if (*na<=0.0 || *na != *na) |
| { |
| nb[0]=0; |
| nb[1]=1; |
| } |
| - else if (*na==(float)(uint32)(*na)) |
| + else if (*na >= 0 && *na <= (float)0xFFFFFFFFU && |
| + *na==(float)(uint32)(*na)) |
| { |
| nb[0]=(uint32)(*na); |
| nb[1]=1; |
| diff --git a/third_party/libtiff/tif_jpeg.c b/third_party/libtiff/tif_jpeg.c |
| index abd0b0aa2..4f154a7c2 100644 |
| --- a/third_party/libtiff/tif_jpeg.c |
| +++ b/third_party/libtiff/tif_jpeg.c |
| @@ -1634,6 +1634,20 @@ JPEGSetupEncode(TIFF* tif) |
| case PHOTOMETRIC_YCBCR: |
| sp->h_sampling = td->td_ycbcrsubsampling[0]; |
| sp->v_sampling = td->td_ycbcrsubsampling[1]; |
| + if( sp->h_sampling == 0 || sp->v_sampling == 0 ) |
| + { |
| + TIFFErrorExt(tif->tif_clientdata, module, |
| + "Invalig horizontal/vertical sampling value"); |
| + return (0); |
| + } |
| + if( td->td_bitspersample > 16 ) |
| + { |
| + TIFFErrorExt(tif->tif_clientdata, module, |
| + "BitsPerSample %d not allowed for JPEG", |
| + td->td_bitspersample); |
| + return (0); |
| + } |
| + |
| /* |
| * A ReferenceBlackWhite field *must* be present since the |
| * default value is inappropriate for YCbCr. Fill in the |
| diff --git a/third_party/libtiff/tif_read.c b/third_party/libtiff/tif_read.c |
| index 47686a473..c916ac8ac 100644 |
| --- a/third_party/libtiff/tif_read.c |
| +++ b/third_party/libtiff/tif_read.c |
| @@ -420,16 +420,25 @@ TIFFReadRawStrip1(TIFF* tif, uint32 strip, void* buf, tmsize_t size, |
| return ((tmsize_t)(-1)); |
| } |
| } else { |
| - tmsize_t ma,mb; |
| + tmsize_t ma; |
| tmsize_t n; |
| - ma=(tmsize_t)td->td_stripoffset[strip]; |
| - mb=ma+size; |
| - if ((td->td_stripoffset[strip] > (uint64)TIFF_TMSIZE_T_MAX)||(ma>tif->tif_size)) |
| + if ((td->td_stripoffset[strip] > (uint64)TIFF_TMSIZE_T_MAX)|| |
| + ((ma=(tmsize_t)td->td_stripoffset[strip])>tif->tif_size)) |
| + { |
| n=0; |
| - else if ((mb<ma)||(mb<size)||(mb>tif->tif_size)) |
| - n=tif->tif_size-ma; |
| + } |
| + else if( ma > TIFF_TMSIZE_T_MAX - size ) |
| + { |
| + n=0; |
| + } |
| else |
| - n=size; |
| + { |
| + tmsize_t mb=ma+size; |
| + if (mb>tif->tif_size) |
| + n=tif->tif_size-ma; |
| + else |
| + n=size; |
| + } |
| if (n!=size) { |
| #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) |
| TIFFErrorExt(tif->tif_clientdata, module, |