[LIBTIFF] Update to version 4.0.9. CORE-14291
authorThomas Faber <thomas.faber@reactos.org>
Sun, 4 Feb 2018 15:21:58 +0000 (16:21 +0100)
committerThomas Faber <thomas.faber@reactos.org>
Mon, 5 Feb 2018 13:40:31 +0000 (14:40 +0100)
26 files changed:
dll/3rdparty/libtiff/libtiff.def
dll/3rdparty/libtiff/tif_aux.c
dll/3rdparty/libtiff/tif_color.c
dll/3rdparty/libtiff/tif_dir.c
dll/3rdparty/libtiff/tif_dirinfo.c
dll/3rdparty/libtiff/tif_dirread.c
dll/3rdparty/libtiff/tif_dirwrite.c
dll/3rdparty/libtiff/tif_error.c
dll/3rdparty/libtiff/tif_fax3.c
dll/3rdparty/libtiff/tif_getimage.c
dll/3rdparty/libtiff/tif_jbig.c
dll/3rdparty/libtiff/tif_jpeg.c
dll/3rdparty/libtiff/tif_jpeg_12.c
dll/3rdparty/libtiff/tif_luv.c
dll/3rdparty/libtiff/tif_lzw.c
dll/3rdparty/libtiff/tif_pixarlog.c
dll/3rdparty/libtiff/tif_predict.c
dll/3rdparty/libtiff/tif_read.c
dll/3rdparty/libtiff/tif_swab.c
dll/3rdparty/libtiff/tif_warning.c
sdk/include/reactos/libs/libtiff/tif_config.h
sdk/include/reactos/libs/libtiff/tif_dir.h
sdk/include/reactos/libs/libtiff/tiffconf.h
sdk/include/reactos/libs/libtiff/tiffio.h
sdk/include/reactos/libs/libtiff/tiffiop.h
sdk/include/reactos/libs/libtiff/tiffvers.h

index acf8609..341c719 100644 (file)
@@ -85,7 +85,9 @@ EXPORTS       TIFFAccessTagMethods
        TIFFReadRGBAImage
        TIFFReadRGBAImageOriented
        TIFFReadRGBAStrip
+       TIFFReadRGBAStripExt
        TIFFReadRGBATile
+       TIFFReadRGBATileExt
        TIFFReadRawStrip
        TIFFReadRawTile
        TIFFReadScanline
index 74602c2..1f29630 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: tif_aux.c,v 1.29 2016-11-11 20:45:53 erouault Exp $ */
+/* $Id: tif_aux.c,v 1.31 2017-11-17 20:21:00 erouault Exp $ */
 
 /*
  * Copyright (c) 1991-1997 Sam Leffler
@@ -31,7 +31,7 @@
  */
 
 #include <precomp.h>
-#include <tif_predict.h>
+#include "tif_predict.h"
 #include <math.h>
 
 uint32
@@ -360,6 +360,13 @@ _TIFFUInt64ToDouble(uint64 ui64)
        }
 }
 
+int _TIFFSeekOK(TIFF* tif, toff_t off)
+{
+    /* Huge offsets, especially -1 / UINT64_MAX, can cause issues */
+    /* See http://bugzilla.maptools.org/show_bug.cgi?id=2726 */
+    return off <= (~(uint64)0)/2 && TIFFSeekFile(tif,off,SEEK_SET)==off;
+}
+
 /* vim: set ts=8 sts=8 sw=8 noet: */
 /*
  * Local Variables:
index 5af9155..54d542c 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: tif_color.c,v 1.23 2017-05-13 18:17:34 erouault Exp $ */
+/* $Id: tif_color.c,v 1.24 2017-05-29 10:12:54 erouault Exp $ */
 
 /*
  * Copyright (c) 1988-1997 Sam Leffler
@@ -275,10 +275,10 @@ TIFFYCbCrToRGBInit(TIFFYCbCrToRGB* ycbcr, float *luma, float *refBlackWhite)
       for (i = 0, x = -128; i < 256; i++, x++) {
            int32 Cr = (int32)CLAMPw(Code2V(x, refBlackWhite[4] - 128.0F,
                            refBlackWhite[5] - 128.0F, 127),
-                            -128.0F * 64, 128.0F * 64);
+                            -128.0F * 32, 128.0F * 32);
            int32 Cb = (int32)CLAMPw(Code2V(x, refBlackWhite[2] - 128.0F,
                            refBlackWhite[3] - 128.0F, 127),
-                            -128.0F * 64, 128.0F * 64);
+                            -128.0F * 32, 128.0F * 32);
 
            ycbcr->Cr_r_tab[i] = (int32)((D1*Cr + ONE_HALF)>>SHIFT);
            ycbcr->Cb_b_tab[i] = (int32)((D3*Cb + ONE_HALF)>>SHIFT);
@@ -286,7 +286,7 @@ TIFFYCbCrToRGBInit(TIFFYCbCrToRGB* ycbcr, float *luma, float *refBlackWhite)
            ycbcr->Cb_g_tab[i] = D4*Cb + ONE_HALF;
            ycbcr->Y_tab[i] =
                    (int32)CLAMPw(Code2V(x + 128, refBlackWhite[0], refBlackWhite[1], 255),
-                                  -128.0F * 64, 128.0F * 64);
+                                  -128.0F * 32, 128.0F * 32);
       }
     }
 
index 782b136..e38bb23 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: tif_dir.c,v 1.130 2017-05-17 21:54:05 erouault Exp $ */
+/* $Id: tif_dir.c,v 1.131 2017-07-11 21:38:04 erouault Exp $ */
 
 /*
  * Copyright (c) 1988-1997 Sam Leffler
@@ -30,7 +30,6 @@
  * Directory Tag Get & Set Routines.
  * (and also some miscellaneous stuff)
  */
-
 #include <precomp.h>
 #include <float.h>
 
@@ -873,6 +872,8 @@ _TIFFVGetField(TIFF* tif, uint32 tag, va_list ap)
                 TIFFTagValue *tv = td->td_customValues + i;
                 if (tv->info->field_tag != tag)
                     continue;
+                if( tv->value == NULL )
+                    return 0;
                 val = *(uint16 *)tv->value;
                 /* Truncate to SamplesPerPixel, since the */
                 /* setting code for INKNAMES assume that there are SamplesPerPixel */
index c703551..bf1eebf 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: tif_dirinfo.c,v 1.126 2016-11-18 02:52:13 bfriesen Exp $ */
+/* $Id: tif_dirinfo.c,v 1.127 2017-06-01 12:44:04 erouault Exp $ */
 
 /*
  * Copyright (c) 1988-1997 Sam Leffler
@@ -29,7 +29,6 @@
  *
  * Core Directory Tag Support.
  */
-
 #include <precomp.h>
 //#include <stdlib.h>
 
@@ -957,6 +956,109 @@ TIFFMergeFieldInfo(TIFF* tif, const TIFFFieldInfo info[], uint32 n)
        return 0;
 }
 
+int
+_TIFFCheckFieldIsValidForCodec(TIFF *tif, ttag_t tag)
+{
+       /* Filter out non-codec specific tags */
+       switch (tag) {
+           /* Shared tags */
+           case TIFFTAG_PREDICTOR:
+           /* JPEG tags */
+           case TIFFTAG_JPEGTABLES:
+           /* OJPEG tags */
+           case TIFFTAG_JPEGIFOFFSET:
+           case TIFFTAG_JPEGIFBYTECOUNT:
+           case TIFFTAG_JPEGQTABLES:
+           case TIFFTAG_JPEGDCTABLES:
+           case TIFFTAG_JPEGACTABLES:
+           case TIFFTAG_JPEGPROC:
+           case TIFFTAG_JPEGRESTARTINTERVAL:
+           /* CCITT* */
+           case TIFFTAG_BADFAXLINES:
+           case TIFFTAG_CLEANFAXDATA:
+           case TIFFTAG_CONSECUTIVEBADFAXLINES:
+           case TIFFTAG_GROUP3OPTIONS:
+           case TIFFTAG_GROUP4OPTIONS:
+               break;
+           default:
+               return 1;
+       }
+       /* Check if codec specific tags are allowed for the current
+        * compression scheme (codec) */
+       switch (tif->tif_dir.td_compression) {
+           case COMPRESSION_LZW:
+               if (tag == TIFFTAG_PREDICTOR)
+                   return 1;
+               break;
+           case COMPRESSION_PACKBITS:
+               /* No codec-specific tags */
+               break;
+           case COMPRESSION_THUNDERSCAN:
+               /* No codec-specific tags */
+               break;
+           case COMPRESSION_NEXT:
+               /* No codec-specific tags */
+               break;
+           case COMPRESSION_JPEG:
+               if (tag == TIFFTAG_JPEGTABLES)
+                   return 1;
+               break;
+           case COMPRESSION_OJPEG:
+               switch (tag) {
+                   case TIFFTAG_JPEGIFOFFSET:
+                   case TIFFTAG_JPEGIFBYTECOUNT:
+                   case TIFFTAG_JPEGQTABLES:
+                   case TIFFTAG_JPEGDCTABLES:
+                   case TIFFTAG_JPEGACTABLES:
+                   case TIFFTAG_JPEGPROC:
+                   case TIFFTAG_JPEGRESTARTINTERVAL:
+                       return 1;
+               }
+               break;
+           case COMPRESSION_CCITTRLE:
+           case COMPRESSION_CCITTRLEW:
+           case COMPRESSION_CCITTFAX3:
+           case COMPRESSION_CCITTFAX4:
+               switch (tag) {
+                   case TIFFTAG_BADFAXLINES:
+                   case TIFFTAG_CLEANFAXDATA:
+                   case TIFFTAG_CONSECUTIVEBADFAXLINES:
+                       return 1;
+                   case TIFFTAG_GROUP3OPTIONS:
+                       if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX3)
+                           return 1;
+                       break;
+                   case TIFFTAG_GROUP4OPTIONS:
+                       if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX4)
+                           return 1;
+                       break;
+               }
+               break;
+           case COMPRESSION_JBIG:
+               /* No codec-specific tags */
+               break;
+           case COMPRESSION_DEFLATE:
+           case COMPRESSION_ADOBE_DEFLATE:
+               if (tag == TIFFTAG_PREDICTOR)
+                   return 1;
+               break;
+          case COMPRESSION_PIXARLOG:
+               if (tag == TIFFTAG_PREDICTOR)
+                   return 1;
+               break;
+           case COMPRESSION_SGILOG:
+           case COMPRESSION_SGILOG24:
+               /* No codec-specific tags */
+               break;
+           case COMPRESSION_LZMA:
+               if (tag == TIFFTAG_PREDICTOR)
+                   return 1;
+               break;
+
+       }
+       return 0;
+}
+
 /* vim: set ts=8 sts=8 sw=8 noet: */
 
 /*
index 71334a1..5352fcd 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: tif_dirread.c,v 1.208 2017-04-27 15:46:22 erouault Exp $ */
+/* $Id: tif_dirread.c,v 1.218 2017-09-09 21:44:42 erouault Exp $ */
 
 /*
  * Copyright (c) 1988-1997 Sam Leffler
@@ -41,6 +41,7 @@
 
 #include <precomp.h>
 #include <float.h>
+#include <stdlib.h>
 
 #define IGNORE 0          /* tag placeholder used below */
 #define FAILED_FII    ((uint32) -1)
@@ -636,6 +637,8 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryFloat(TIFF* tif, TIFFDirEntry* d
                                err=TIFFReadDirEntryCheckedDouble(tif,direntry,&m);
                                if (err!=TIFFReadDirEntryErrOk)
                                        return(err);
+                               if ((m > FLT_MAX) || (m < FLT_MIN))
+                                       return(TIFFReadDirEntryErrRange);
                                *value=(float)m;
                                return(TIFFReadDirEntryErrOk);
                        }
@@ -765,13 +768,80 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryIfd8(TIFF* tif, TIFFDirEntry* di
        }
 }
 
-static enum TIFFReadDirEntryErr TIFFReadDirEntryArray(TIFF* tif, TIFFDirEntry* direntry, uint32* count, uint32 desttypesize, void** value)
+
+#define INITIAL_THRESHOLD (1024 * 1024)
+#define THRESHOLD_MULTIPLIER 10
+#define MAX_THRESHOLD (THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * INITIAL_THRESHOLD)
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryDataAndRealloc(
+                    TIFF* tif, uint64 offset, tmsize_t size, void** pdest)
+{
+#if SIZEOF_VOIDP == 8 || SIZEOF_SIZE_T == 8
+        tmsize_t threshold = INITIAL_THRESHOLD;
+#endif
+        tmsize_t already_read = 0;
+
+        assert( !isMapped(tif) );
+
+        if (!SeekOK(tif,offset))
+                return(TIFFReadDirEntryErrIo);
+
+        /* On 64 bit processes, read first a maximum of 1 MB, then 10 MB, etc */
+        /* so as to avoid allocating too much memory in case the file is too */
+        /* short. We could ask for the file size, but this might be */
+        /* expensive with some I/O layers (think of reading a gzipped file) */
+        /* Restrict to 64 bit processes, so as to avoid reallocs() */
+        /* on 32 bit processes where virtual memory is scarce.  */
+        while( already_read < size )
+        {
+            void* new_dest;
+            tmsize_t bytes_read;
+            tmsize_t to_read = size - already_read;
+#if SIZEOF_VOIDP == 8 || SIZEOF_SIZE_T == 8
+            if( to_read >= threshold && threshold < MAX_THRESHOLD )
+            {
+                to_read = threshold;
+                threshold *= THRESHOLD_MULTIPLIER;
+            }
+#endif
+
+            new_dest = (uint8*) _TIFFrealloc(
+                            *pdest, already_read + to_read);
+            if( new_dest == NULL )
+            {
+                TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+                            "Failed to allocate memory for %s "
+                            "(%ld elements of %ld bytes each)",
+                            "TIFFReadDirEntryArray",
+                             (long) 1, (long) (already_read + to_read));
+                return TIFFReadDirEntryErrAlloc;
+            }
+            *pdest = new_dest;
+
+            bytes_read = TIFFReadFile(tif,
+                (char*)*pdest + already_read, to_read);
+            already_read += bytes_read;
+            if (bytes_read != to_read) {
+                return TIFFReadDirEntryErrIo;
+            }
+        }
+        return TIFFReadDirEntryErrOk;
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryArrayWithLimit(
+    TIFF* tif, TIFFDirEntry* direntry, uint32* count, uint32 desttypesize,
+    void** value, uint64 maxcount)
 {
        int typesize;
        uint32 datasize;
        void* data;
+        uint64 target_count64;
        typesize=TIFFDataWidth(direntry->tdir_type);
-       if ((direntry->tdir_count==0)||(typesize==0))
+
+        target_count64 = (direntry->tdir_count > maxcount) ?
+                maxcount : direntry->tdir_count;
+
+       if ((target_count64==0)||(typesize==0))
        {
                *value=0;
                return(TIFFReadDirEntryErrOk);
@@ -783,17 +853,30 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryArray(TIFF* tif, TIFFDirEntry* d
          * in either the current data type or the dest data type.  This also
          * avoids problems with overflow of tmsize_t on 32bit systems.
          */
-       if ((uint64)(2147483647/typesize)<direntry->tdir_count)
+       if ((uint64)(2147483647/typesize)<target_count64)
                return(TIFFReadDirEntryErrSizesan);
-       if ((uint64)(2147483647/desttypesize)<direntry->tdir_count)
+       if ((uint64)(2147483647/desttypesize)<target_count64)
                return(TIFFReadDirEntryErrSizesan);
 
-       *count=(uint32)direntry->tdir_count;
+       *count=(uint32)target_count64;
        datasize=(*count)*typesize;
        assert((tmsize_t)datasize>0);
-       data=_TIFFCheckMalloc(tif, *count, typesize, "ReadDirEntryArray");
-       if (data==0)
-               return(TIFFReadDirEntryErrAlloc);
+
+       if( isMapped(tif) && datasize > (uint32)tif->tif_size )
+               return TIFFReadDirEntryErrIo;
+
+       if( !isMapped(tif) &&
+               (((tif->tif_flags&TIFF_BIGTIFF) && datasize > 8) ||
+               (!(tif->tif_flags&TIFF_BIGTIFF) && datasize > 4)) )
+       {
+               data = NULL;
+       }
+       else
+       {
+               data=_TIFFCheckMalloc(tif, *count, typesize, "ReadDirEntryArray");
+               if (data==0)
+                       return(TIFFReadDirEntryErrAlloc);
+       }
        if (!(tif->tif_flags&TIFF_BIGTIFF))
        {
                if (datasize<=4)
@@ -804,7 +887,10 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryArray(TIFF* tif, TIFFDirEntry* d
                        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( isMapped(tif) )
+                               err=TIFFReadDirEntryData(tif,(uint64)offset,(tmsize_t)datasize,data);
+                       else
+                               err=TIFFReadDirEntryDataAndRealloc(tif,(uint64)offset,(tmsize_t)datasize,&data);
                        if (err!=TIFFReadDirEntryErrOk)
                        {
                                _TIFFfree(data);
@@ -822,7 +908,10 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryArray(TIFF* tif, TIFFDirEntry* d
                        uint64 offset = direntry->tdir_offset.toff_long8;
                        if (tif->tif_flags&TIFF_SWAB)
                                TIFFSwabLong8(&offset);
-                       err=TIFFReadDirEntryData(tif,offset,(tmsize_t)datasize,data);
+                       if( isMapped(tif) )
+                               err=TIFFReadDirEntryData(tif,(uint64)offset,(tmsize_t)datasize,data);
+                       else
+                               err=TIFFReadDirEntryDataAndRealloc(tif,(uint64)offset,(tmsize_t)datasize,&data);
                        if (err!=TIFFReadDirEntryErrOk)
                        {
                                _TIFFfree(data);
@@ -834,6 +923,12 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryArray(TIFF* tif, TIFFDirEntry* d
        return(TIFFReadDirEntryErrOk);
 }
 
+static enum TIFFReadDirEntryErr TIFFReadDirEntryArray(TIFF* tif, TIFFDirEntry* direntry, uint32* count, uint32 desttypesize, void** value)
+{
+    return TIFFReadDirEntryArrayWithLimit(tif, direntry, count,
+                                          desttypesize, value, ~((uint64)0));
+}
+
 static enum TIFFReadDirEntryErr TIFFReadDirEntryByteArray(TIFF* tif, TIFFDirEntry* direntry, uint8** value)
 {
        enum TIFFReadDirEntryErr err;
@@ -1863,7 +1958,8 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntrySlongArray(TIFF* tif, TIFFDirEnt
        return(TIFFReadDirEntryErrOk);
 }
 
-static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8Array(TIFF* tif, TIFFDirEntry* direntry, uint64** value)
+static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8ArrayWithLimit(
+        TIFF* tif, TIFFDirEntry* direntry, uint64** value, uint64 maxcount)
 {
        enum TIFFReadDirEntryErr err;
        uint32 count;
@@ -1883,7 +1979,7 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8Array(TIFF* tif, TIFFDirEnt
                default:
                        return(TIFFReadDirEntryErrType);
        }
-       err=TIFFReadDirEntryArray(tif,direntry,&count,8,&origdata);
+       err=TIFFReadDirEntryArrayWithLimit(tif,direntry,&count,8,&origdata,maxcount);
        if ((err!=TIFFReadDirEntryErrOk)||(origdata==0))
        {
                *value=0;
@@ -2029,6 +2125,11 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8Array(TIFF* tif, TIFFDirEnt
        return(TIFFReadDirEntryErrOk);
 }
 
+static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8Array(TIFF* tif, TIFFDirEntry* direntry, uint64** value)
+{
+    return TIFFReadDirEntryLong8ArrayWithLimit(tif, direntry, value, ~((uint64)0));
+}
+
 static enum TIFFReadDirEntryErr TIFFReadDirEntrySlong8Array(TIFF* tif, TIFFDirEntry* direntry, int64** value)
 {
        enum TIFFReadDirEntryErr err;
@@ -2731,7 +2832,7 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryPersampleShort(TIFF* tif, TIFFDi
        if (direntry->tdir_count<(uint64)tif->tif_dir.td_samplesperpixel)
                return(TIFFReadDirEntryErrCount);
        err=TIFFReadDirEntryShortArray(tif,direntry,&m);
-       if (err!=TIFFReadDirEntryErrOk)
+       if (err!=TIFFReadDirEntryErrOk || m == NULL)
                return(err);
        na=m;
        nb=tif->tif_dir.td_samplesperpixel;
@@ -3580,6 +3681,10 @@ TIFFReadDirectory(TIFF* tif)
                                                        goto bad;
                                                dp->tdir_tag=IGNORE;
                                                break;
+                                        default:
+                                            if( !_TIFFCheckFieldIsValidForCodec(tif, dp->tdir_tag) )
+                                                dp->tdir_tag=IGNORE;
+                                            break;
                                }
                        }
                }
@@ -3979,12 +4084,14 @@ TIFFReadDirectory(TIFF* tif)
                #define BYTECOUNTLOOKSBAD \
                    ( (tif->tif_dir.td_stripbytecount[0] == 0 && tif->tif_dir.td_stripoffset[0] != 0) || \
                      (tif->tif_dir.td_compression == COMPRESSION_NONE && \
-                      tif->tif_dir.td_stripbytecount[0] > TIFFGetFileSize(tif) - tif->tif_dir.td_stripoffset[0]) || \
+                      (tif->tif_dir.td_stripoffset[0] <= TIFFGetFileSize(tif) && \
+                       tif->tif_dir.td_stripbytecount[0] > TIFFGetFileSize(tif) - tif->tif_dir.td_stripoffset[0])) || \
                      (tif->tif_mode == O_RDONLY && \
                       tif->tif_dir.td_compression == COMPRESSION_NONE && \
                       tif->tif_dir.td_stripbytecount[0] < TIFFScanlineSize64(tif) * tif->tif_dir.td_imagelength) )
 
                } else if (tif->tif_dir.td_nstrips == 1
+                           && !(tif->tif_flags&TIFF_ISTILED)
                            && _TIFFFillStriles(tif)
                           && tif->tif_dir.td_stripoffset[0] != 0
                           && BYTECOUNTLOOKSBAD) {
@@ -4362,7 +4469,11 @@ EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16 dircount)
                        }
                        space+=datasize;
                }
-               space = filesize - space;
+               if( filesize < space )
+                    /* we should perhaps return in error ? */
+                    space = filesize;
+                else
+                    space = filesize - space;
                if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
                        space /= td->td_samplesperpixel;
                for (strip = 0; strip < td->td_nstrips; strip++)
@@ -5429,28 +5540,39 @@ TIFFFetchStripThing(TIFF* tif, TIFFDirEntry* dir, uint32 nstrips, uint64** lpp)
        static const char module[] = "TIFFFetchStripThing";
        enum TIFFReadDirEntryErr err;
        uint64* data;
-       err=TIFFReadDirEntryLong8Array(tif,dir,&data);
+       err=TIFFReadDirEntryLong8ArrayWithLimit(tif,dir,&data,nstrips);
        if (err!=TIFFReadDirEntryErrOk)
        {
                const TIFFField* fip = TIFFFieldWithTag(tif,dir->tdir_tag); 
                TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown tagname",0);
                return(0);
        }
-       if (dir->tdir_count!=(uint64)nstrips)
+       if (dir->tdir_count<(uint64)nstrips)
        {
                uint64* resizeddata;
+               const TIFFField* fip = TIFFFieldWithTag(tif,dir->tdir_tag);
+               const char* pszMax = getenv("LIBTIFF_STRILE_ARRAY_MAX_RESIZE_COUNT");
+               uint32 max_nstrips = 1000000;
+               if( pszMax )
+                       max_nstrips = (uint32) atoi(pszMax);
+               TIFFReadDirEntryOutputErr(tif,TIFFReadDirEntryErrCount,
+                           module,
+                           fip ? fip->field_name : "unknown tagname",
+                           ( nstrips <= max_nstrips ) );
+
+               if( nstrips > max_nstrips )
+               {
+                       _TIFFfree(data);
+                       return(0);
+               }
+
                resizeddata=(uint64*)_TIFFCheckMalloc(tif,nstrips,sizeof(uint64),"for strip array");
                if (resizeddata==0) {
                        _TIFFfree(data);
                        return(0);
                }
-               if (dir->tdir_count<(uint64)nstrips)
-               {
-                       _TIFFmemcpy(resizeddata,data,(uint32)dir->tdir_count*sizeof(uint64));
-                       _TIFFmemset(resizeddata+(uint32)dir->tdir_count,0,(nstrips-(uint32)dir->tdir_count)*sizeof(uint64));
-               }
-               else
-                       _TIFFmemcpy(resizeddata,data,nstrips*sizeof(uint64));
+                _TIFFmemcpy(resizeddata,data,(uint32)dir->tdir_count*sizeof(uint64));
+                _TIFFmemset(resizeddata+(uint32)dir->tdir_count,0,(nstrips-(uint32)dir->tdir_count)*sizeof(uint64));
                _TIFFfree(data);
                data=resizeddata;
        }
@@ -5538,6 +5660,11 @@ ChopUpSingleUncompressedStrip(TIFF* tif)
        uint64* newoffsets;
 
        bytecount = td->td_stripbytecount[0];
+        /* On a newly created file, just re-opened to be filled, we */
+        /* don't want strip chop to trigger as it is going to cause issues */
+        /* later ( StripOffsets and StripByteCounts improperly filled) . */
+        if( bytecount == 0 && tif->tif_mode != O_RDONLY )
+            return;
        offset = td->td_stripoffset[0];
        assert(td->td_planarconfig == PLANARCONFIG_CONTIG);
        if ((td->td_photometric == PHOTOMETRIC_YCBCR)&&
index 0deafbe..21f57a1 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: tif_dirwrite.c,v 1.85 2017-01-11 16:09:02 erouault Exp $ */
+/* $Id: tif_dirwrite.c,v 1.89 2017-08-23 13:33:42 erouault Exp $ */
 
 /*
  * Copyright (c) 1988-1997 Sam Leffler
@@ -29,7 +29,6 @@
  *
  * Directory Write Support Routines.
  */
-
 #include <precomp.h>
 #include <float.h>
 
@@ -822,7 +821,12 @@ TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64* pdiroff)
                        TIFFDirEntry* nb;
                        for (na=0, nb=dir; ; na++, nb++)
                        {
-                               assert(na<ndir);
+                               if( na == ndir )
+                                {
+                                    TIFFErrorExt(tif->tif_clientdata,module,
+                                                 "Cannot find SubIFD tag");
+                                    goto bad;
+                                }
                                if (nb->tdir_tag==TIFFTAG_SUBIFD)
                                        break;
                        }
@@ -1945,7 +1949,14 @@ TIFFWriteDirectoryTagSubifd(TIFF* tif, uint32* ndir, TIFFDirEntry* dir)
                for (p=0; p < tif->tif_dir.td_nsubifd; p++)
                {
                         assert(pa != 0);
-                       assert(*pa <= 0xFFFFFFFFUL);
+
+                        /* Could happen if an classicTIFF has a SubIFD of type LONG8 (which is illegal) */
+                        if( *pa > 0xFFFFFFFFUL)
+                        {
+                            TIFFErrorExt(tif->tif_clientdata,module,"Illegal value for SubIFD tag");
+                            _TIFFfree(o);
+                            return(0);
+                        }
                        *pb++=(uint32)(*pa++);
                }
                n=TIFFWriteDirectoryTagCheckedIfdArray(tif,ndir,dir,TIFFTAG_SUBIFD,tif->tif_dir.td_nsubifd,o);
@@ -2112,7 +2123,10 @@ TIFFWriteDirectoryTagCheckedLong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, ui
 {
        uint64 m;
        assert(sizeof(uint64)==8);
-       assert(tif->tif_flags&TIFF_BIGTIFF);
+       if( !(tif->tif_flags&TIFF_BIGTIFF) ) {
+               TIFFErrorExt(tif->tif_clientdata,"TIFFWriteDirectoryTagCheckedLong8","LONG8 not allowed for ClassicTIFF");
+               return(0);
+       }
        m=value;
        if (tif->tif_flags&TIFF_SWAB)
                TIFFSwabLong8(&m);
@@ -2125,7 +2139,10 @@ TIFFWriteDirectoryTagCheckedLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* di
 {
        assert(count<0x20000000);
        assert(sizeof(uint64)==8);
-       assert(tif->tif_flags&TIFF_BIGTIFF);
+       if( !(tif->tif_flags&TIFF_BIGTIFF) ) {
+               TIFFErrorExt(tif->tif_clientdata,"TIFFWriteDirectoryTagCheckedLong8Array","LONG8 not allowed for ClassicTIFF");
+               return(0);
+       }
        if (tif->tif_flags&TIFF_SWAB)
                TIFFSwabArrayOfLong8(value,count);
        return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_LONG8,count,count*8,value));
@@ -2137,7 +2154,10 @@ TIFFWriteDirectoryTagCheckedSlong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, u
 {
        int64 m;
        assert(sizeof(int64)==8);
-       assert(tif->tif_flags&TIFF_BIGTIFF);
+       if( !(tif->tif_flags&TIFF_BIGTIFF) ) {
+               TIFFErrorExt(tif->tif_clientdata,"TIFFWriteDirectoryTagCheckedSlong8","SLONG8 not allowed for ClassicTIFF");
+               return(0);
+       }
        m=value;
        if (tif->tif_flags&TIFF_SWAB)
                TIFFSwabLong8((uint64*)(&m));
@@ -2150,7 +2170,10 @@ TIFFWriteDirectoryTagCheckedSlong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* d
 {
        assert(count<0x20000000);
        assert(sizeof(int64)==8);
-       assert(tif->tif_flags&TIFF_BIGTIFF);
+       if( !(tif->tif_flags&TIFF_BIGTIFF) ) {
+               TIFFErrorExt(tif->tif_clientdata,"TIFFWriteDirectoryTagCheckedSlong8Array","SLONG8 not allowed for ClassicTIFF");
+               return(0);
+       }
        if (tif->tif_flags&TIFF_SWAB)
                TIFFSwabArrayOfLong8((uint64*)value,count);
        return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SLONG8,count,count*8,value));
index 10b8afd..a8f1af8 100644 (file)
@@ -1,4 +1,4 @@
-/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_error.c,v 1.5 2010-03-10 18:56:48 bfriesen Exp $ */
+/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_error.c,v 1.6 2017-07-04 12:54:42 erouault Exp $ */
 
 /*
  * Copyright (c) 1988-1997 Sam Leffler
@@ -27,7 +27,6 @@
 /*
  * TIFF Library.
  */
-
 #include <precomp.h>
 
 TIFFErrorHandlerExt _TIFFerrorHandlerExt = NULL;
@@ -52,24 +51,32 @@ void
 TIFFError(const char* module, const char* fmt, ...)
 {
        va_list ap;
-       va_start(ap, fmt);
-       if (_TIFFerrorHandler)
+       if (_TIFFerrorHandler) {
+               va_start(ap, fmt);      
                (*_TIFFerrorHandler)(module, fmt, ap);
-       if (_TIFFerrorHandlerExt)
+               va_end(ap);
+       }
+       if (_TIFFerrorHandlerExt) {
+               va_start(ap, fmt);
                (*_TIFFerrorHandlerExt)(0, module, fmt, ap);
-       va_end(ap);
+               va_end(ap);
+       }
 }
 
 void
 TIFFErrorExt(thandle_t fd, const char* module, const char* fmt, ...)
 {
        va_list ap;
-       va_start(ap, fmt);
-       if (_TIFFerrorHandler)
+       if (_TIFFerrorHandler) {
+               va_start(ap, fmt);
                (*_TIFFerrorHandler)(module, fmt, ap);
-       if (_TIFFerrorHandlerExt)
+               va_end(ap);
+       }
+       if (_TIFFerrorHandlerExt) {
+               va_start(ap, fmt);
                (*_TIFFerrorHandlerExt)(fd, module, fmt, ap);
-       va_end(ap);
+               va_end(ap);
+       }
 }
 
 /*
index 8a0ec28..2047bc6 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: tif_fax3.c,v 1.80 2017-04-27 19:50:01 erouault Exp $ */
+/* $Id: tif_fax3.c,v 1.81 2017-06-18 10:31:50 erouault Exp $ */
 
 /*
  * Copyright (c) 1990-1997 Sam Leffler
@@ -25,7 +25,6 @@
  */
 
 #include <precomp.h>
-
 #ifdef CCITT_SUPPORT
 /*
  * TIFF Library.
@@ -1044,7 +1043,11 @@ Fax3Encode2DRow(TIFF* tif, unsigned char* bp, unsigned char* rp, uint32 bits)
        for (;;) {
                b2 = finddiff2(rp, b1, bits, PIXEL(rp,b1));
                if (b2 >= a1) {
-                       int32 d = b1 - a1;
+                       /* Naive computation triggers -fsanitize=undefined,unsigned-integer-overflow */
+                       /* although it is correct unless the difference between both is < 31 bit */
+                       /* int32 d = b1 - a1; */
+                       int32 d = (b1 >= a1 && b1 - a1 <= 3U) ? (int32)(b1 - a1):
+                                 (b1 < a1 && a1 - b1 <= 3U) ? -(int32)(a1 - b1) : 0x7FFFFFFF;
                        if (!(-3 <= d && d <= 3)) {     /* horizontal mode */
                                a2 = finddiff2(bp, a1, bits, PIXEL(bp,a1));
                                putcode(tif, &horizcode);
index 2319f8d..d0f4af4 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: tif_getimage.c,v 1.106 2017-05-20 11:29:02 erouault Exp $ */
+/* $Id: tif_getimage.c,v 1.114 2017-11-17 20:21:00 erouault Exp $ */
 
 /*
  * Copyright (c) 1991-1997 Sam Leffler
@@ -29,7 +29,6 @@
  *
  * Read and return a packed RGBA image.
  */
-
 #include <precomp.h>
 //#include <stdio.h>
 
@@ -139,7 +138,7 @@ TIFFRGBAImageOK(TIFF* tif, char emsg[1024])
                        /*
                         * TODO: if at all meaningful and useful, make more complete
                         * support check here, or better still, refactor to let supporting
-                        * code decide whether there is support and what meaningfull
+                        * code decide whether there is support and what meaningful
                         * error to return
                         */
                        break;
@@ -417,7 +416,7 @@ TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stop, char emsg[1024])
                        /*
                         * TODO: if at all meaningful and useful, make more complete
                         * support check here, or better still, refactor to let supporting
-                        * code decide whether there is support and what meaningfull
+                        * code decide whether there is support and what meaningful
                         * error to return
                         */
                        break;
@@ -627,7 +626,7 @@ gtTileContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
     uint32 col, row, y, rowstoread;
     tmsize_t pos;
     uint32 tw, th;
-    unsigned char* buf;
+    unsigned char* buf = NULL;
     int32 fromskew, toskew;
     uint32 nrow;
     int ret = 1, flip;
@@ -635,13 +634,14 @@ gtTileContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
     int32 this_toskew, leftmost_toskew;
     int32 leftmost_fromskew;
     uint32 leftmost_tw;
+    tmsize_t bufsize;
 
-    buf = (unsigned char*) _TIFFmalloc(TIFFTileSize(tif));
-    if (buf == 0) {
-               TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", "No space for tile buffer");
-               return (0);
+    bufsize = TIFFTileSize(tif);
+    if (bufsize == 0) {
+        TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", "No space for tile buffer");
+        return (0);
     }
-    _TIFFmemset(buf, 0, TIFFTileSize(tif));
+
     TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
     TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
 
@@ -661,7 +661,7 @@ gtTileContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
     leftmost_fromskew = img->col_offset % tw;
     leftmost_tw = tw - leftmost_fromskew;
     leftmost_toskew = toskew + leftmost_fromskew;
-    for (row = 0; row < h; row += nrow)
+    for (row = 0; ret != 0 && row < h; row += nrow)
     {
         rowstoread = th - (row + img->row_offset) % th;
        nrow = (row + rowstoread > h ? h - row : rowstoread);
@@ -672,8 +672,9 @@ gtTileContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
        col = img->col_offset;
        while (tocol < w)
         {
-           if (TIFFReadTile(tif, buf, col,  
-                            row+img->row_offset, 0, 0)==(tmsize_t)(-1) && img->stoponerr)
+           if (_TIFFReadTileAndAllocBuffer(tif, (void**) &buf, bufsize, col,
+                            row+img->row_offset, 0, 0)==(tmsize_t)(-1) &&
+                (buf == NULL || img->stoponerr))
             {
                 ret = 0;
                 break;
@@ -738,11 +739,11 @@ gtTileSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
        uint32 col, row, y, rowstoread;
        tmsize_t pos;
        uint32 tw, th;
-       unsigned char* buf;
-       unsigned char* p0;
-       unsigned char* p1;
-       unsigned char* p2;
-       unsigned char* pa;
+       unsigned char* buf = NULL;
+       unsigned char* p0 = NULL;
+       unsigned char* p1 = NULL;
+       unsigned char* p2 = NULL;
+       unsigned char* pa = NULL;
        tmsize_t tilesize;
        tmsize_t bufsize;
        int32 fromskew, toskew;
@@ -761,16 +762,7 @@ gtTileSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
                TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Integer overflow in %s", "gtTileSeparate");
                return (0);
        }
-       buf = (unsigned char*) _TIFFmalloc(bufsize);
-       if (buf == 0) {
-               TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", "No space for tile buffer");
-               return (0);
-       }
-       _TIFFmemset(buf, 0, bufsize);
-       p0 = buf;
-       p1 = p0 + tilesize;
-       p2 = p1 + tilesize;
-       pa = (alpha?(p2+tilesize):NULL);
+
        TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
        TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
 
@@ -790,7 +782,6 @@ gtTileSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
           case PHOTOMETRIC_MINISBLACK:
           case PHOTOMETRIC_PALETTE:
             colorchannels = 1;
-            p2 = p1 = p0;
             break;
 
           default:
@@ -804,7 +795,7 @@ gtTileSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
        leftmost_fromskew = img->col_offset % tw;
        leftmost_tw = tw - leftmost_fromskew;
        leftmost_toskew = toskew + leftmost_fromskew;
-       for (row = 0; row < h; row += nrow)
+       for (row = 0; ret != 0 && row < h; row += nrow)
        {
                rowstoread = th - (row + img->row_offset) % th;
                nrow = (row + rowstoread > h ? h - row : rowstoread);
@@ -815,7 +806,30 @@ gtTileSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
                col = img->col_offset;
                while (tocol < w)
                {
-                       if (TIFFReadTile(tif, p0, col,  
+                        if( buf == NULL )
+                        {
+                            if (_TIFFReadTileAndAllocBuffer(
+                                    tif, (void**) &buf, bufsize, col,
+                                    row+img->row_offset,0,0)==(tmsize_t)(-1)
+                                && (buf == NULL || img->stoponerr))
+                            {
+                                    ret = 0;
+                                    break;
+                            }
+                            p0 = buf;
+                            if( colorchannels == 1 )
+                            {
+                                p2 = p1 = p0;
+                                pa = (alpha?(p0+3*tilesize):NULL);
+                            }
+                            else
+                            {
+                                p1 = p0 + tilesize;
+                                p2 = p1 + tilesize;
+                                pa = (alpha?(p2+tilesize):NULL);
+                            }
+                        }
+                       else if (TIFFReadTile(tif, p0, col,  
                            row+img->row_offset,0,0)==(tmsize_t)(-1) && img->stoponerr)
                        {
                                ret = 0;
@@ -906,26 +920,22 @@ gtStripContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
        tileContigRoutine put = img->put.contig;
        uint32 row, y, nrow, nrowsub, rowstoread;
        tmsize_t pos;
-       unsigned char* buf;
+       unsigned char* buf = NULL;
        uint32 rowsperstrip;
        uint16 subsamplinghor,subsamplingver;
        uint32 imagewidth = img->width;
        tmsize_t scanline;
        int32 fromskew, toskew;
        int ret = 1, flip;
+        tmsize_t maxstripsize;
 
        TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING, &subsamplinghor, &subsamplingver);
        if( subsamplingver == 0 ) {
                TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Invalid vertical YCbCr subsampling");
                return (0);
        }
-
-       buf = (unsigned char*) _TIFFmalloc(TIFFStripSize(tif));
-       if (buf == 0) {
-               TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for strip buffer");
-               return (0);
-       }
-       _TIFFmemset(buf, 0, TIFFStripSize(tif));
+       
+       maxstripsize = TIFFStripSize(tif);
 
        flip = setorientation(img);
        if (flip & FLIP_VERTICALLY) {
@@ -947,11 +957,12 @@ gtStripContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
                nrowsub = nrow;
                if ((nrowsub%subsamplingver)!=0)
                        nrowsub+=subsamplingver-nrowsub%subsamplingver;
-               if (TIFFReadEncodedStrip(tif,
+               if (_TIFFReadEncodedStripAndAllocBuffer(tif,
                    TIFFComputeStrip(tif,row+img->row_offset, 0),
-                   buf,
+                   (void**)(&buf),
+                    maxstripsize,
                    ((row + img->row_offset)%rowsperstrip + nrowsub) * scanline)==(tmsize_t)(-1)
-                   && img->stoponerr)
+                   && (buf == NULL || img->stoponerr))
                {
                        ret = 0;
                        break;
@@ -995,8 +1006,8 @@ gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
 {
        TIFF* tif = img->tif;
        tileSeparateRoutine put = img->put.separate;
-       unsigned char *buf;
-       unsigned char *p0, *p1, *p2, *pa;
+       unsigned char *buf = NULL;
+       unsigned char *p0 = NULL, *p1 = NULL, *p2 = NULL, *pa = NULL;
        uint32 row, y, nrow, rowstoread;
        tmsize_t pos;
        tmsize_t scanline;
@@ -1015,15 +1026,6 @@ gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
                TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Integer overflow in %s", "gtStripSeparate");
                return (0);
        }
-       p0 = buf = (unsigned char *)_TIFFmalloc(bufsize);
-       if (buf == 0) {
-               TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for tile buffer");
-               return (0);
-       }
-       _TIFFmemset(buf, 0, bufsize);
-       p1 = p0 + stripsize;
-       p2 = p1 + stripsize;
-       pa = (alpha?(p2+stripsize):NULL);
 
        flip = setorientation(img);
        if (flip & FLIP_VERTICALLY) {
@@ -1041,7 +1043,6 @@ gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
           case PHOTOMETRIC_MINISBLACK:
           case PHOTOMETRIC_PALETTE:
             colorchannels = 1;
-            p2 = p1 = p0;
             break;
 
           default:
@@ -1057,7 +1058,31 @@ gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
                rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip;
                nrow = (row + rowstoread > h ? h - row : rowstoread);
                offset_row = row + img->row_offset;
-               if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 0),
+                if( buf == NULL )
+                {
+                    if (_TIFFReadEncodedStripAndAllocBuffer(
+                            tif, TIFFComputeStrip(tif, offset_row, 0),
+                            (void**) &buf, bufsize,
+                            ((row + img->row_offset)%rowsperstrip + nrow) * scanline)==(tmsize_t)(-1)
+                        && (buf == NULL || img->stoponerr))
+                    {
+                            ret = 0;
+                            break;
+                    }
+                    p0 = buf;
+                    if( colorchannels == 1 )
+                    {
+                        p2 = p1 = p0;
+                        pa = (alpha?(p0+3*stripsize):NULL);
+                    }
+                    else
+                    {
+                        p1 = p0 + stripsize;
+                        p2 = p1 + stripsize;
+                        pa = (alpha?(p2+stripsize):NULL);
+                    }
+                }
+               else if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 0),
                    p0, ((row + img->row_offset)%rowsperstrip + nrow) * scanline)==(tmsize_t)(-1)
                    && img->stoponerr)
                {
@@ -1213,8 +1238,8 @@ DECLAREContigPutFunc(put8bitcmaptile)
     int samplesperpixel = img->samplesperpixel;
 
     (void) y;
-    while (h-- > 0) {
-       for (x = w; x-- > 0;)
+    for( ; h > 0; --h) {
+       for (x = w; x > 0; --x)
         {
            *cp++ = PALmap[*pp][0];
             pp += samplesperpixel;
@@ -1233,7 +1258,7 @@ DECLAREContigPutFunc(put4bitcmaptile)
 
     (void) x; (void) y;
     fromskew /= 2;
-    while (h-- > 0) {
+    for( ; h > 0; --h) {
        uint32* bw;
        UNROLL2(w, bw = PALmap[*pp++], *cp++ = *bw++);
        cp += toskew;
@@ -1250,7 +1275,7 @@ DECLAREContigPutFunc(put2bitcmaptile)
 
     (void) x; (void) y;
     fromskew /= 4;
-    while (h-- > 0) {
+    for( ; h > 0; --h) {
        uint32* bw;
        UNROLL4(w, bw = PALmap[*pp++], *cp++ = *bw++);
        cp += toskew;
@@ -1267,7 +1292,7 @@ DECLAREContigPutFunc(put1bitcmaptile)
 
     (void) x; (void) y;
     fromskew /= 8;
-    while (h-- > 0) {
+    for( ; h > 0; --h) {
        uint32* bw;
        UNROLL8(w, bw = PALmap[*pp++], *cp++ = *bw++);
        cp += toskew;
@@ -1284,8 +1309,8 @@ DECLAREContigPutFunc(putgreytile)
     uint32** BWmap = img->BWmap;
 
     (void) y;
-    while (h-- > 0) {
-       for (x = w; x-- > 0;)
+    for( ; h > 0; --h) {
+       for (x = w; x > 0; --x)
         {
            *cp++ = BWmap[*pp][0];
             pp += samplesperpixel;
@@ -1304,8 +1329,8 @@ DECLAREContigPutFunc(putagreytile)
     uint32** BWmap = img->BWmap;
 
     (void) y;
-    while (h-- > 0) {
-       for (x = w; x-- > 0;)
+    for( ; h > 0; --h) {
+       for (x = w; x > 0; --x)
         {
             *cp++ = BWmap[*pp][0] & ((uint32)*(pp+1) << 24 | ~A1);
             pp += samplesperpixel;
@@ -1324,10 +1349,10 @@ DECLAREContigPutFunc(put16bitbwtile)
     uint32** BWmap = img->BWmap;
 
     (void) y;
-    while (h-- > 0) {
+    for( ; h > 0; --h) {
         uint16 *wp = (uint16 *) pp;
 
-       for (x = w; x-- > 0;)
+       for (x = w; x > 0; --x)
         {
             /* use high order byte of 16bit value */
 
@@ -1349,7 +1374,7 @@ DECLAREContigPutFunc(put1bitbwtile)
 
     (void) x; (void) y;
     fromskew /= 8;
-    while (h-- > 0) {
+    for( ; h > 0; --h) {
        uint32* bw;
        UNROLL8(w, bw = BWmap[*pp++], *cp++ = *bw++);
        cp += toskew;
@@ -1366,7 +1391,7 @@ DECLAREContigPutFunc(put2bitbwtile)
 
     (void) x; (void) y;
     fromskew /= 4;
-    while (h-- > 0) {
+    for( ; h > 0; --h) {
        uint32* bw;
        UNROLL4(w, bw = BWmap[*pp++], *cp++ = *bw++);
        cp += toskew;
@@ -1383,7 +1408,7 @@ DECLAREContigPutFunc(put4bitbwtile)
 
     (void) x; (void) y;
     fromskew /= 2;
-    while (h-- > 0) {
+    for( ; h > 0; --h) {
        uint32* bw;
        UNROLL2(w, bw = BWmap[*pp++], *cp++ = *bw++);
        cp += toskew;
@@ -1400,7 +1425,7 @@ DECLAREContigPutFunc(putRGBcontig8bittile)
 
     (void) x; (void) y;
     fromskew *= samplesperpixel;
-    while (h-- > 0) {
+    for( ; h > 0; --h) {
        UNROLL8(w, NOP,
            *cp++ = PACK(pp[0], pp[1], pp[2]);
            pp += samplesperpixel);
@@ -1419,7 +1444,7 @@ DECLAREContigPutFunc(putRGBAAcontig8bittile)
 
     (void) x; (void) y;
     fromskew *= samplesperpixel;
-    while (h-- > 0) {
+    for( ; h > 0; --h) {
        UNROLL8(w, NOP,
            *cp++ = PACK4(pp[0], pp[1], pp[2], pp[3]);
            pp += samplesperpixel);
@@ -1437,10 +1462,10 @@ DECLAREContigPutFunc(putRGBUAcontig8bittile)
        int samplesperpixel = img->samplesperpixel;
        (void) y;
        fromskew *= samplesperpixel;
-       while (h-- > 0) {
+       for( ; h > 0; --h) {
                uint32 r, g, b, a;
                uint8* m;
-               for (x = w; x-- > 0;) {
+               for (x = w; x > 0; --x) {
                        a = pp[3];
                        m = img->UaToAa+((size_t) a<<8);
                        r = m[pp[0]];
@@ -1463,8 +1488,8 @@ DECLAREContigPutFunc(putRGBcontig16bittile)
        uint16 *wp = (uint16 *)pp;
        (void) y;
        fromskew *= samplesperpixel;
-       while (h-- > 0) {
-               for (x = w; x-- > 0;) {
+       for( ; h > 0; --h) {
+               for (x = w; x > 0; --x) {
                        *cp++ = PACK(img->Bitdepth16To8[wp[0]],
                            img->Bitdepth16To8[wp[1]],
                            img->Bitdepth16To8[wp[2]]);
@@ -1485,8 +1510,8 @@ DECLAREContigPutFunc(putRGBAAcontig16bittile)
        uint16 *wp = (uint16 *)pp;
        (void) y;
        fromskew *= samplesperpixel;
-       while (h-- > 0) {
-               for (x = w; x-- > 0;) {
+       for( ; h > 0; --h) {
+               for (x = w; x > 0; --x) {
                        *cp++ = PACK4(img->Bitdepth16To8[wp[0]],
                            img->Bitdepth16To8[wp[1]],
                            img->Bitdepth16To8[wp[2]],
@@ -1508,10 +1533,10 @@ DECLAREContigPutFunc(putRGBUAcontig16bittile)
        uint16 *wp = (uint16 *)pp;
        (void) y;
        fromskew *= samplesperpixel;
-       while (h-- > 0) {
+       for( ; h > 0; --h) {
                uint32 r,g,b,a;
                uint8* m;
-               for (x = w; x-- > 0;) {
+               for (x = w; x > 0; --x) {
                        a = img->Bitdepth16To8[wp[3]];
                        m = img->UaToAa+((size_t) a<<8);
                        r = m[img->Bitdepth16To8[wp[0]]];
@@ -1537,7 +1562,7 @@ DECLAREContigPutFunc(putRGBcontig8bitCMYKtile)
 
     (void) x; (void) y;
     fromskew *= samplesperpixel;
-    while (h-- > 0) {
+    for( ; h > 0; --h) {
        UNROLL8(w, NOP,
            k = 255 - pp[3];
            r = (k*(255-pp[0]))/255;
@@ -1563,8 +1588,8 @@ DECLAREContigPutFunc(putRGBcontig8bitCMYKMaptile)
 
     (void) y;
     fromskew *= samplesperpixel;
-    while (h-- > 0) {
-       for (x = w; x-- > 0;) {
+    for( ; h > 0; --h) {
+       for (x = w; x > 0; --x) {
            k = 255 - pp[3];
            r = (k*(255-pp[0]))/255;
            g = (k*(255-pp[1]))/255;
@@ -1593,7 +1618,7 @@ static void name(\
 DECLARESepPutFunc(putRGBseparate8bittile)
 {
     (void) img; (void) x; (void) y; (void) a;
-    while (h-- > 0) {
+    for( ; h > 0; --h) {
        UNROLL8(w, NOP, *cp++ = PACK(*r++, *g++, *b++));
        SKEW(r, g, b, fromskew);
        cp += toskew;
@@ -1606,7 +1631,7 @@ DECLARESepPutFunc(putRGBseparate8bittile)
 DECLARESepPutFunc(putRGBAAseparate8bittile)
 {
        (void) img; (void) x; (void) y; 
-       while (h-- > 0) {
+       for( ; h > 0; --h) {
                UNROLL8(w, NOP, *cp++ = PACK4(*r++, *g++, *b++, *a++));
                SKEW4(r, g, b, a, fromskew);
                cp += toskew;
@@ -1619,9 +1644,9 @@ DECLARESepPutFunc(putRGBAAseparate8bittile)
 DECLARESepPutFunc(putCMYKseparate8bittile)
 {
        (void) img; (void) y;
-       while (h-- > 0) {
+       for( ; h > 0; --h) {
                uint32 rv, gv, bv, kv;
-               for (x = w; x-- > 0;) {
+               for (x = w; x > 0; --x) {
                        kv = 255 - *a++;
                        rv = (kv*(255-*r++))/255;
                        gv = (kv*(255-*g++))/255;
@@ -1639,10 +1664,10 @@ DECLARESepPutFunc(putCMYKseparate8bittile)
 DECLARESepPutFunc(putRGBUAseparate8bittile)
 {
        (void) img; (void) y;
-       while (h-- > 0) {
+       for( ; h > 0; --h) {
                uint32 rv, gv, bv, av;
                uint8* m;
-               for (x = w; x-- > 0;) {
+               for (x = w; x > 0; --x) {
                        av = *a++;
                        m = img->UaToAa+((size_t) av<<8);
                        rv = m[*r++];
@@ -1664,7 +1689,7 @@ DECLARESepPutFunc(putRGBseparate16bittile)
        uint16 *wg = (uint16*) g;
        uint16 *wb = (uint16*) b;
        (void) img; (void) y; (void) a;
-       while (h-- > 0) {
+       for( ; h > 0; --h) {
                for (x = 0; x < w; x++)
                        *cp++ = PACK(img->Bitdepth16To8[*wr++],
                            img->Bitdepth16To8[*wg++],
@@ -1684,7 +1709,7 @@ DECLARESepPutFunc(putRGBAAseparate16bittile)
        uint16 *wb = (uint16*) b;
        uint16 *wa = (uint16*) a;
        (void) img; (void) y;
-       while (h-- > 0) {
+       for( ; h > 0; --h) {
                for (x = 0; x < w; x++)
                        *cp++ = PACK4(img->Bitdepth16To8[*wr++],
                            img->Bitdepth16To8[*wg++],
@@ -1705,10 +1730,10 @@ DECLARESepPutFunc(putRGBUAseparate16bittile)
        uint16 *wb = (uint16*) b;
        uint16 *wa = (uint16*) a;
        (void) img; (void) y;
-       while (h-- > 0) {
+       for( ; h > 0; --h) {
                uint32 r2,g2,b2,a2;
                uint8* m;
-               for (x = w; x-- > 0;) {
+               for (x = w; x > 0; --x) {
                        a2 = img->Bitdepth16To8[*wa++];
                        m = img->UaToAa+((size_t) a2<<8);
                        r2 = m[img->Bitdepth16To8[*wr++]];
@@ -1730,8 +1755,8 @@ DECLAREContigPutFunc(putcontig8bitCIELab)
        uint32 r, g, b;
        (void) y;
        fromskew *= 3;
-       while (h-- > 0) {
-               for (x = w; x-- > 0;) {
+       for( ; h > 0; --h) {
+               for (x = w; x > 0; --x) {
                        TIFFCIELabToXYZ(img->cielab,
                                        (unsigned char)pp[0],
                                        (signed char)pp[1],
@@ -1844,7 +1869,7 @@ DECLAREContigPutFunc(putcontig8bitYCbCr44tile)
 
     (void) y;
     /* adjust fromskew */
-    fromskew = (fromskew * 18) / 4;
+    fromskew = (fromskew / 4) * (4*2+2);
     if ((h & 3) == 0 && (w & 3) == 0) {                                        
         for (; h >= 4; h -= 4) {
             x = w>>2;
@@ -1947,7 +1972,7 @@ DECLAREContigPutFunc(putcontig8bitYCbCr42tile)
     int32 incr = 2*toskew+w;
 
     (void) y;
-    fromskew = (fromskew * 10) / 4;
+    fromskew = (fromskew / 4) * (4*2+2);
     if ((w & 3) == 0 && (h & 1) == 0) {
         for (; h >= 2; h -= 2) {
             x = w>>2;
@@ -2025,7 +2050,7 @@ DECLAREContigPutFunc(putcontig8bitYCbCr42tile)
 DECLAREContigPutFunc(putcontig8bitYCbCr41tile)
 {
     (void) y;
-    /* XXX adjust fromskew */
+    fromskew = (fromskew / 4) * (4*1+2);
     do {
        x = w>>2;
        while(x>0) {
@@ -2072,7 +2097,7 @@ DECLAREContigPutFunc(putcontig8bitYCbCr22tile)
        uint32* cp2;
        int32 incr = 2*toskew+w;
        (void) y;
-       fromskew = (fromskew / 2) * 6;
+       fromskew = (fromskew / 2) * (2*2+2);
        cp2 = cp+w+toskew;
        while (h>=2) {
                x = w;
@@ -2128,7 +2153,7 @@ DECLAREContigPutFunc(putcontig8bitYCbCr22tile)
 DECLAREContigPutFunc(putcontig8bitYCbCr21tile)
 {
        (void) y;
-       fromskew = (fromskew * 4) / 2;
+       fromskew = (fromskew / 2) * (2*1+2);
        do {
                x = w>>1;
                while(x>0) {
@@ -2167,7 +2192,7 @@ DECLAREContigPutFunc(putcontig8bitYCbCr12tile)
        uint32* cp2;
        int32 incr = 2*toskew+w;
        (void) y;
-       fromskew = (fromskew / 2) * 4;
+       fromskew = (fromskew / 1) * (1 * 2 + 2);
        cp2 = cp+w+toskew;
        while (h>=2) {
                x = w;
@@ -2203,7 +2228,7 @@ DECLAREContigPutFunc(putcontig8bitYCbCr12tile)
 DECLAREContigPutFunc(putcontig8bitYCbCr11tile)
 {
        (void) y;
-       fromskew *= 3;
+       fromskew = (fromskew / 1) * (1 * 1 + 2);
        do {
                x = w; /* was x = w>>1; patched 2000/09/25 warmerda@home.com */
                do {
@@ -2227,7 +2252,7 @@ DECLARESepPutFunc(putseparate8bitYCbCr11tile)
        (void) y;
        (void) a;
        /* TODO: naming of input vars is still off, change obfuscating declaration inside define, or resolve obfuscation */
-       while (h-- > 0) {
+       for( ; h > 0; --h) {
                x = w;
                do {
                        uint32 dr, dg, db;
@@ -2242,7 +2267,7 @@ DECLARESepPutFunc(putseparate8bitYCbCr11tile)
 
 static int isInRefBlackWhiteRange(float f)
 {
-    return f >= (float)(-0x7FFFFFFF + 128) && f <= (float)0x7FFFFFFF;
+    return f > (float)(-0x7FFFFFFF + 128) && f < (float)0x7FFFFFFF;
 }
 
 static int
@@ -2307,6 +2332,13 @@ initCIELabConversion(TIFFRGBAImage* img)
        float   *whitePoint;
        float   refWhite[3];
 
+       TIFFGetFieldDefaulted(img->tif, TIFFTAG_WHITEPOINT, &whitePoint);
+       if (whitePoint[1] == 0.0f ) {
+               TIFFErrorExt(img->tif->tif_clientdata, module,
+                   "Invalid value for WhitePoint tag.");
+               return NULL;
+        }
+
        if (!img->cielab) {
                img->cielab = (TIFFCIELabToRGB *)
                        _TIFFmalloc(sizeof(TIFFCIELabToRGB));
@@ -2317,7 +2349,6 @@ initCIELabConversion(TIFFRGBAImage* img)
                }
        }
 
-       TIFFGetFieldDefaulted(img->tif, TIFFTAG_WHITEPOINT, &whitePoint);
        refWhite[1] = 100.0F;
        refWhite[0] = whitePoint[0] / whitePoint[1] * refWhite[1];
        refWhite[2] = (1.0F - whitePoint[0] - whitePoint[1])
index 7e21441..707fa9c 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: tif_jbig.c,v 1.15 2010-03-10 18:56:48 bfriesen Exp $ */
+/* $Id: tif_jbig.c,v 1.16 2017-06-26 15:20:00 erouault Exp $ */
 
 /*
  * Copyright (c) 1988-1997 Sam Leffler
@@ -94,6 +94,7 @@ static int JBIGDecode(TIFF* tif, uint8* buffer, tmsize_t size, uint16 s)
                             jbg_strerror(decodeStatus)
 #endif
                             );
+               jbg_dec_free(&decoder);
                return 0;
        }
 
index bed9ddd..9d4f3dd 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: tif_jpeg.c,v 1.127 2017-01-31 13:02:27 erouault Exp $ */
+/* $Id: tif_jpeg.c,v 1.134 2017-10-17 19:04:47 erouault Exp $ */
 
 /*
  * Copyright (c) 1994-1997 Sam Leffler
@@ -48,6 +48,7 @@
 int TIFFFillStrip(TIFF* tif, uint32 strip);
 int TIFFFillTile(TIFF* tif, uint32 tile);
 int TIFFReInitJPEG_12( TIFF *tif, int scheme, int is_encode );
+int TIFFJPEGIsFullStripRequired_12(TIFF* tif);
 
 /* We undefine FAR to avoid conflict with JPEG definition */
 
@@ -146,6 +147,8 @@ typedef struct {
 
        jpeg_error_mgr  err;            /* libjpeg error manager */
        JMP_BUF         exit_jmpbuf;    /* for catching libjpeg failures */
+       
+       struct jpeg_progress_mgr progress;
        /*
         * The following two members could be a union, but
         * they're small enough that it's not worth the effort.
@@ -176,6 +179,7 @@ typedef struct {
        int             jpegtablesmode; /* What to put in JPEGTables */
 
         int             ycbcrsampling_fetched;
+        int             max_allowed_scan_number;
 } JPEGState;
 
 #define        JState(tif)     ((JPEGState*)(tif)->tif_data)
@@ -236,6 +240,33 @@ TIFFjpeg_output_message(j_common_ptr cinfo)
        TIFFWarningExt(((JPEGState *) cinfo)->tif->tif_clientdata, "JPEGLib", "%s", buffer);
 }
 
+/* Avoid the risk of denial-of-service on crafted JPEGs with an insane */
+/* number of scans. */
+/* See http://www.libjpeg-turbo.org/pmwiki/uploads/About/TwoIssueswiththeJPEGStandard.pdf */
+static void
+TIFFjpeg_progress_monitor(j_common_ptr cinfo)
+{
+    JPEGState *sp = (JPEGState *) cinfo;       /* NB: cinfo assumed first */
+    if (cinfo->is_decompressor)
+    {
+        const int scan_no =
+            ((j_decompress_ptr)cinfo)->input_scan_number;
+        if (scan_no >= sp->max_allowed_scan_number)
+        {
+            TIFFErrorExt(((JPEGState *) cinfo)->tif->tif_clientdata, 
+                     "TIFFjpeg_progress_monitor",
+                     "Scan number %d exceeds maximum scans (%d). This limit "
+                     "can be raised through the LIBTIFF_JPEG_MAX_ALLOWED_SCAN_NUMBER "
+                     "environment variable.",
+                     scan_no, sp->max_allowed_scan_number);
+
+            jpeg_abort(cinfo);                 /* clean up libjpeg state */
+            LONGJMP(sp->exit_jmpbuf, 1);               /* return to libtiff caller */
+        }
+    }
+}
+
+
 /*
  * Interface routines.  This layer of routines exists
  * primarily to limit side-effects from using setjmp.
@@ -337,9 +368,24 @@ TIFFjpeg_read_header(JPEGState* sp, boolean require_image)
        return CALLJPEG(sp, -1, jpeg_read_header(&sp->cinfo.d, require_image));
 }
 
+static int
+TIFFjpeg_has_multiple_scans(JPEGState* sp)
+{
+       return CALLJPEG(sp, 0, jpeg_has_multiple_scans(&sp->cinfo.d));
+}
+
 static int
 TIFFjpeg_start_decompress(JPEGState* sp)
 {
+        const char* sz_max_allowed_scan_number;
+        /* progress monitor */
+        sp->cinfo.d.progress = &sp->progress;
+        sp->progress.progress_monitor = TIFFjpeg_progress_monitor;
+        sp->max_allowed_scan_number = 100;
+        sz_max_allowed_scan_number = getenv("LIBTIFF_JPEG_MAX_ALLOWED_SCAN_NUMBER");
+        if( sz_max_allowed_scan_number )
+            sp->max_allowed_scan_number = atoi(sz_max_allowed_scan_number);
+
        return CALLVJPEG(sp, jpeg_start_decompress(&sp->cinfo.d));
 }
 
@@ -590,9 +636,8 @@ std_term_source(j_decompress_ptr cinfo)
 }
 
 static void
-TIFFjpeg_data_src(JPEGState* sp, TIFF* tif)
+TIFFjpeg_data_src(JPEGState* sp)
 {
-       (void) tif;
        sp->cinfo.d.src = &sp->src;
        sp->src.init_source = std_init_source;
        sp->src.fill_input_buffer = std_fill_input_buffer;
@@ -618,9 +663,9 @@ tables_init_source(j_decompress_ptr cinfo)
 }
 
 static void
-TIFFjpeg_tables_src(JPEGState* sp, TIFF* tif)
+TIFFjpeg_tables_src(JPEGState* sp)
 {
-       TIFFjpeg_data_src(sp, tif);
+       TIFFjpeg_data_src(sp);
        sp->src.init_source = tables_init_source;
 }
 
@@ -977,7 +1022,7 @@ JPEGSetupDecode(TIFF* tif)
 
        /* Read JPEGTables if it is present */
        if (TIFFFieldSet(tif,FIELD_JPEGTABLES)) {
-               TIFFjpeg_tables_src(sp, tif);
+               TIFFjpeg_tables_src(sp);
                if(TIFFjpeg_read_header(sp,FALSE) != JPEG_HEADER_TABLES_ONLY) {
                        TIFFErrorExt(tif->tif_clientdata, "JPEGSetupDecode", "Bogus JPEGTables field");
                        return (0);
@@ -999,11 +1044,47 @@ JPEGSetupDecode(TIFF* tif)
        }
 
        /* Set up for reading normal data */
-       TIFFjpeg_data_src(sp, tif);
+       TIFFjpeg_data_src(sp);
        tif->tif_postdecode = _TIFFNoPostDecode; /* override byte swapping */
        return (1);
 }
 
+/* Returns 1 if the full strip should be read, even when doing scanline per */
+/* scanline decoding. This happens when the JPEG stream uses multiple scans. */
+/* Currently only called in CHUNKY_STRIP_READ_SUPPORT mode through */
+/* scanline interface. */
+/* Only reads tif->tif_dir.td_bitspersample, tif->tif_rawdata and */
+/* tif->tif_rawcc members. */
+/* Can be called independently of the usual setup/predecode/decode states */
+int TIFFJPEGIsFullStripRequired(TIFF* tif)
+{
+    int ret;
+    JPEGState state;
+
+#if defined(JPEG_DUAL_MODE_8_12) && !defined(TIFFJPEGIsFullStripRequired)
+    if( tif->tif_dir.td_bitspersample == 12 )
+        return TIFFJPEGIsFullStripRequired_12( tif );
+#endif
+
+    memset(&state, 0, sizeof(JPEGState));
+    state.tif = tif;
+
+    TIFFjpeg_create_decompress(&state);
+
+    TIFFjpeg_data_src(&state);
+
+    if (TIFFjpeg_read_header(&state, TRUE) != JPEG_HEADER_OK)
+    {
+        TIFFjpeg_destroy(&state);
+        return (0);
+    }
+    ret = TIFFjpeg_has_multiple_scans(&state);
+
+    TIFFjpeg_destroy(&state);
+
+    return ret;
+}
+
 /*
  * Set up for decoding a strip or tile.
  */
@@ -1044,13 +1125,13 @@ JPEGPreDecode(TIFF* tif, uint16 s)
        /*
         * Check image parameters and set decompression parameters.
         */
-       segment_width = td->td_imagewidth;
-       segment_height = td->td_imagelength - tif->tif_row;
        if (isTiled(tif)) {
                 segment_width = td->td_tilewidth;
                 segment_height = td->td_tilelength;
                sp->bytesperline = TIFFTileRowSize(tif);
        } else {
+               segment_width = td->td_imagewidth;
+               segment_height = td->td_imagelength - tif->tif_row;
                if (segment_height > td->td_rowsperstrip)
                        segment_height = td->td_rowsperstrip;
                sp->bytesperline = TIFFScanlineSize(tif);
@@ -1071,9 +1152,23 @@ JPEGPreDecode(TIFF* tif, uint16 s)
                               segment_width, segment_height,
                               sp->cinfo.d.image_width,
                               sp->cinfo.d.image_height);
-       } 
-       if (sp->cinfo.d.image_width > segment_width ||
-           sp->cinfo.d.image_height > segment_height) {
+       }
+       if( sp->cinfo.d.image_width == segment_width &&
+           sp->cinfo.d.image_height > segment_height &&
+           tif->tif_row + segment_height == td->td_imagelength &&
+           !isTiled(tif) ) {
+               /* Some files have a last strip, that should be truncated, */
+               /* but their JPEG codestream has still the maximum strip */
+               /* height. Warn about this as this is non compliant, but */
+               /* we can safely recover from that. */
+               TIFFWarningExt(tif->tif_clientdata, module,
+                            "JPEG strip size exceeds expected dimensions,"
+                            " expected %dx%d, got %dx%d",
+                            segment_width, segment_height,
+                            sp->cinfo.d.image_width, sp->cinfo.d.image_height);
+       }
+       else if (sp->cinfo.d.image_width > segment_width ||
+                sp->cinfo.d.image_height > segment_height) {
                /*
                 * This case could be dangerous, if the strip or tile size has
                 * been reported as less than the amount of data jpeg will
@@ -1106,6 +1201,47 @@ JPEGPreDecode(TIFF* tif, uint16 s)
                return (0);
        }
 #endif
+
+        /* In some cases, libjpeg needs to allocate a lot of memory */
+        /* http://www.libjpeg-turbo.org/pmwiki/uploads/About/TwoIssueswiththeJPEGStandard.pdf */
+        if( TIFFjpeg_has_multiple_scans(sp) )
+        {
+            /* In this case libjpeg will need to allocate memory or backing */
+            /* store for all coefficients */
+            /* See call to jinit_d_coef_controller() from master_selection() */
+            /* in libjpeg */
+            toff_t nRequiredMemory = (toff_t)sp->cinfo.d.image_width *
+                                     sp->cinfo.d.image_height *
+                                     sp->cinfo.d.num_components *
+                                     ((td->td_bitspersample+7)/8);
+            /* BLOCK_SMOOTHING_SUPPORTED is generally defined, so we need */
+            /* to replicate the logic of jinit_d_coef_controller() */
+            if( sp->cinfo.d.progressive_mode )
+                nRequiredMemory *= 3;
+
+#ifndef TIFF_LIBJPEG_LARGEST_MEM_ALLOC
+#define TIFF_LIBJPEG_LARGEST_MEM_ALLOC (100 * 1024 * 1024)
+#endif
+
+            if( nRequiredMemory > TIFF_LIBJPEG_LARGEST_MEM_ALLOC &&
+                getenv("LIBTIFF_ALLOW_LARGE_LIBJPEG_MEM_ALLOC") == NULL )
+            {
+                    TIFFErrorExt(tif->tif_clientdata, module,
+                        "Reading this strip would require libjpeg to allocate "
+                        "at least %u bytes. "
+                        "This is disabled since above the %u threshold. "
+                        "You may override this restriction by defining the "
+                        "LIBTIFF_ALLOW_LARGE_LIBJPEG_MEM_ALLOC environment variable, "
+                        "or recompile libtiff by defining the "
+                        "TIFF_LIBJPEG_LARGEST_MEM_ALLOC macro to a value greater "
+                        "than %u",
+                        (unsigned)nRequiredMemory,
+                        (unsigned)TIFF_LIBJPEG_LARGEST_MEM_ALLOC,
+                        (unsigned)TIFF_LIBJPEG_LARGEST_MEM_ALLOC);
+                    return (0);
+            }
+        }
+
        if (td->td_planarconfig == PLANARCONFIG_CONTIG) {
                /* Component 0 should have expected sampling factors */
                if (sp->cinfo.d.comp_info[0].h_samp_factor != sp->h_sampling ||
@@ -1367,10 +1503,18 @@ JPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
 {
        JPEGState *sp = JState(tif);
        tmsize_t nrows;
+        TIFFDirectory *td = &tif->tif_dir;
        (void) s;
 
+        nrows = sp->cinfo.d.image_height;
+        /* For last strip, limit number of rows to its truncated height */
+        /* even if the codestream height is larger (which is not compliant, */
+        /* but that we tolerate) */
+        if( (uint32)nrows > td->td_imagelength - tif->tif_row && !isTiled(tif) )
+            nrows = td->td_imagelength - tif->tif_row;
+
        /* data is expected to be read in multiples of a scanline */
-       if ( (nrows = sp->cinfo.d.image_height) != 0 ) {
+       if ( nrows != 0 ) {
 
                /* Cb,Cr both have sampling factors 1, so this is correct */
                JDIMENSION clumps_per_line = sp->cinfo.d.comp_info[1].downsampled_width;            
@@ -2311,12 +2455,22 @@ static int JPEGInitializeLibJPEG( TIFF * tif, int decompress )
 #ifndef TIFF_JPEG_MAX_MEMORY_TO_USE
 #define TIFF_JPEG_MAX_MEMORY_TO_USE (10 * 1024 * 1024)
 #endif
-        /* Increase the max memory usable. This helps when creating files */
-        /* with "big" tile, without using libjpeg temporary files. */
-        /* For example a 512x512 tile with 3 bands */
-        /* requires 1.5 MB which is above libjpeg 1MB default */
-        if( sp->cinfo.c.mem->max_memory_to_use < TIFF_JPEG_MAX_MEMORY_TO_USE )
-            sp->cinfo.c.mem->max_memory_to_use = TIFF_JPEG_MAX_MEMORY_TO_USE;
+        /* libjpeg turbo 1.5.2 honours max_memory_to_use, but has no backing */
+        /* store implementation, so better not set max_memory_to_use ourselves. */
+        /* See https://github.com/libjpeg-turbo/libjpeg-turbo/issues/162 */
+        if( sp->cinfo.c.mem->max_memory_to_use > 0 )
+        {
+            /* This is to address bug related in ticket GDAL #1795. */
+            if (getenv("JPEGMEM") == NULL)
+            {
+                /* Increase the max memory usable. This helps when creating files */
+                /* with "big" tile, without using libjpeg temporary files. */
+                /* For example a 512x512 tile with 3 bands */
+                /* requires 1.5 MB which is above libjpeg 1MB default */
+                if( sp->cinfo.c.mem->max_memory_to_use < TIFF_JPEG_MAX_MEMORY_TO_USE )
+                    sp->cinfo.c.mem->max_memory_to_use = TIFF_JPEG_MAX_MEMORY_TO_USE;
+            }
+        }
     }
 
     sp->cinfo_initialized = TRUE;
index afb5acd..39bee5b 100644 (file)
@@ -4,6 +4,7 @@
 #if defined(JPEG_DUAL_MODE_8_12)
 
 #  define TIFFInitJPEG TIFFInitJPEG_12
+#  define TIFFJPEGIsFullStripRequired TIFFJPEGIsFullStripRequired_12
 
 int
 TIFFInitJPEG_12(TIFF* tif, int scheme);
index 7c78e2a..e6be21e 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: tif_luv.c,v 1.47 2017-05-14 10:17:27 erouault Exp $ */
+/* $Id: tif_luv.c,v 1.49 2017-07-24 12:47:30 erouault Exp $ */
 
 /*
  * Copyright (c) 1997 Greg Ward Larson
@@ -25,7 +25,6 @@
  */
 
 #include <precomp.h>
-
 #ifdef LOGLUV_SUPPORT
 
 /*
@@ -1315,7 +1314,7 @@ LogL16InitState(TIFF* tif)
        }
         if( isTiled(tif) )
             sp->tbuflen = multiply_ms(td->td_tilewidth, td->td_tilelength);
-        else if( td->td_rowsperstrip != (uint32)-1 )
+        else if( td->td_rowsperstrip < td->td_imagelength )
             sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_rowsperstrip);
         else
             sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_imagelength);
@@ -1417,8 +1416,10 @@ LogLuvInitState(TIFF* tif)
        }
         if( isTiled(tif) )
             sp->tbuflen = multiply_ms(td->td_tilewidth, td->td_tilelength);
-        else
+        else if( td->td_rowsperstrip < td->td_imagelength )
             sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_rowsperstrip);
+        else
+            sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_imagelength);
        if (multiply_ms(sp->tbuflen, sizeof (uint32)) == 0 ||
            (sp->tbuf = (uint8*) _TIFFmalloc(sp->tbuflen * sizeof (uint32))) == NULL) {
                TIFFErrorExt(tif->tif_clientdata, module, "No space for SGILog translation buffer");
index 212b38d..c6ab1be 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: tif_lzw.c,v 1.55 2017-05-17 09:38:58 erouault Exp $ */
+/* $Id: tif_lzw.c,v 1.57 2017-07-11 10:54:29 erouault Exp $ */
 
 /*
  * Copyright (c) 1988-1997 Sam Leffler
@@ -25,7 +25,6 @@
  */
 
 #include <precomp.h>
-
 #ifdef LZW_SUPPORT
 /*
  * TIFF Library.  
@@ -276,7 +275,8 @@ LZWPreDecode(TIFF* tif, uint16 s)
        /*
         * Check for old bit-reversed codes.
         */
-       if (tif->tif_rawdata[0] == 0 && (tif->tif_rawdata[1] & 0x1)) {
+       if (tif->tif_rawcc >= 2 &&
+           tif->tif_rawdata[0] == 0 && (tif->tif_rawdata[1] & 0x1)) {
 #ifdef LZW_COMPAT
                if (!sp->dec_decode) {
                        TIFFWarningExt(tif->tif_clientdata, module,
@@ -656,6 +656,9 @@ LZWDecodeCompat(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s)
        }
 
        bp = (unsigned char *)tif->tif_rawcp;
+#ifdef LZW_CHECKEOS
+       sp->dec_bitsleft = (((uint64)tif->tif_rawcc) << 3);
+#endif
        nbits = sp->lzw_nbits;
        nextdata = sp->lzw_nextdata;
        nextbits = sp->lzw_nextbits;
@@ -765,6 +768,7 @@ LZWDecodeCompat(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s)
                }
        }
 
+       tif->tif_rawcc -= (tmsize_t)( (uint8*) bp - tif->tif_rawcp );
        tif->tif_rawcp = (uint8*) bp;
        sp->lzw_nbits = (unsigned short)nbits;
        sp->lzw_nextdata = nextdata;
index b0756d0..53bdd4d 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: tif_pixarlog.c,v 1.53 2017-05-17 09:53:06 erouault Exp $ */
+/* $Id: tif_pixarlog.c,v 1.54 2017-07-10 10:40:28 erouault Exp $ */
 
 /*
  * Copyright (c) 1996-1997 Sam Leffler
@@ -25,7 +25,6 @@
  */
 
 #include <precomp.h>
-
 #ifdef PIXARLOG_SUPPORT
 
 /*
@@ -674,6 +673,7 @@ PixarLogSetupDecode(TIFF* tif)
        TIFFDirectory *td = &tif->tif_dir;
        PixarLogState* sp = DecoderState(tif);
        tmsize_t tbuf_size;
+        uint32 strip_height;
 
        assert(sp != NULL);
 
@@ -683,6 +683,10 @@ PixarLogSetupDecode(TIFF* tif)
        if( (sp->state & PLSTATE_INIT) != 0 )
                return 1;
 
+        strip_height = td->td_rowsperstrip;
+        if( strip_height > td->td_imagelength )
+            strip_height = td->td_imagelength;
+
        /* Make sure no byte swapping happens on the data
         * after decompression. */
        tif->tif_postdecode = _TIFFNoPostDecode;  
@@ -692,7 +696,7 @@ PixarLogSetupDecode(TIFF* tif)
        sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ?
            td->td_samplesperpixel : 1);
        tbuf_size = multiply_ms(multiply_ms(multiply_ms(sp->stride, td->td_imagewidth),
-                                     td->td_rowsperstrip), sizeof(uint16));
+                                     strip_height), sizeof(uint16));
        /* add one more stride in case input ends mid-stride */
        tbuf_size = add_ms(tbuf_size, sizeof(uint16) * sp->stride);
        if (tbuf_size == 0)
index 331ad89..f83b19f 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: tif_predict.c,v 1.43 2017-05-10 15:21:16 erouault Exp $ */
+/* $Id: tif_predict.c,v 1.44 2017-06-18 10:31:50 erouault Exp $ */
 
 /*
  * Copyright (c) 1988-1997 Sam Leffler
@@ -29,7 +29,6 @@
  *
  * Predictor Tag Support (used by multiple codecs).
  */
-
 #include <precomp.h>
 #include "tif_predict.h"
 
@@ -278,6 +277,7 @@ PredictorSetupEncode(TIFF* tif)
 /* - when storing into the byte stream, we explicitly mask with 0xff so */
 /*   as to make icc -check=conversions happy (not necessary by the standard) */
 
+TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
 static int
 horAcc8(TIFF* tif, uint8* cp0, tmsize_t cc)
 {
@@ -345,6 +345,7 @@ swabHorAcc16(TIFF* tif, uint8* cp0, tmsize_t cc)
         return horAcc16(tif, cp0, cc);
 }
 
+TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
 static int
 horAcc16(TIFF* tif, uint8* cp0, tmsize_t cc)
 {
@@ -379,6 +380,7 @@ swabHorAcc32(TIFF* tif, uint8* cp0, tmsize_t cc)
        return horAcc32(tif, cp0, cc);
 }
 
+TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
 static int
 horAcc32(TIFF* tif, uint8* cp0, tmsize_t cc)
 {
@@ -504,6 +506,7 @@ PredictorDecodeTile(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s)
                return 0;
 }
 
+TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
 static int
 horDiff8(TIFF* tif, uint8* cp0, tmsize_t cc)
 {
@@ -557,6 +560,7 @@ horDiff8(TIFF* tif, uint8* cp0, tmsize_t cc)
        return 1;
 }
 
+TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
 static int
 horDiff16(TIFF* tif, uint8* cp0, tmsize_t cc)
 {
@@ -596,6 +600,7 @@ swabHorDiff16(TIFF* tif, uint8* cp0, tmsize_t cc)
     return 1;
 }
 
+TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
 static int
 horDiff32(TIFF* tif, uint8* cp0, tmsize_t cc)
 {
@@ -638,6 +643,7 @@ swabHorDiff32(TIFF* tif, uint8* cp0, tmsize_t cc)
 /*
  * Floating point predictor differencing routine.
  */
+TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
 static int
 fpDiff(TIFF* tif, uint8* cp0, tmsize_t cc)
 {
index fa24aa8..2d0e0f7 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: tif_read.c,v 1.59 2017-05-13 15:34:06 erouault Exp $ */
+/* $Id: tif_read.c,v 1.66 2017-11-17 20:21:00 erouault Exp $ */
 
 /*
  * Copyright (c) 1988-1997 Sam Leffler
@@ -28,7 +28,6 @@
  * TIFF Library.
  * Scanline-oriented Read Support
  */
-
 #include <precomp.h>
 //#include <stdio.h>
 
@@ -263,6 +262,7 @@ TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart )
         tif->tif_rawdataoff = tif->tif_rawdataoff + tif->tif_rawdataloaded - unused_data ;
         tif->tif_rawdataloaded = unused_data + to_read;
 
+        tif->tif_rawcc = tif->tif_rawdataloaded;
         tif->tif_rawcp = tif->tif_rawdata;
                         
         if (!isFillOrder(tif, td->td_fillorder) &&
@@ -276,10 +276,28 @@ TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart )
         ** restart the decoder.
         */
         if( restart )
-                return TIFFStartStrip(tif, strip);
+        {
+
+#ifdef JPEG_SUPPORT
+            /* A bit messy since breaks the codec abstraction. Ultimately */
+            /* there should be a function pointer for that, but it seems */
+            /* only JPEG is affected. */
+            /* For JPEG, if there are multiple scans (can generally be known */
+            /* with the  read_ahead used), we need to read the whole strip */
+            if( tif->tif_dir.td_compression==COMPRESSION_JPEG &&
+                (uint64)tif->tif_rawcc < td->td_stripbytecount[strip] )
+            {
+                if( TIFFJPEGIsFullStripRequired(tif) )
+                {
+                    return TIFFFillStrip(tif, strip);
+                }
+            }
+#endif
+
+            return TIFFStartStrip(tif, strip);
+        }
         else
         {
-                tif->tif_rawcc = tif->tif_rawdataloaded;
                 return 1;
         }
 }
@@ -443,18 +461,17 @@ TIFFReadScanline(TIFF* tif, void* buf, uint32 row, uint16 sample)
 }
 
 /*
- * Read a strip of data and decompress the specified
- * amount into the user-supplied buffer.
+ * Calculate the strip size according to the number of
+ * rows in the strip (check for truncated last strip on any
+ * of the separations).
  */
-tmsize_t
-TIFFReadEncodedStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size)
+static tmsize_t TIFFReadEncodedStripGetStripSize(TIFF* tif, uint32 strip, uint16* pplane)
 {
        static const char module[] = "TIFFReadEncodedStrip";
        TIFFDirectory *td = &tif->tif_dir;
        uint32 rowsperstrip;
        uint32 stripsperplane;
        uint32 stripinplane;
-       uint16 plane;
        uint32 rows;
        tmsize_t stripsize;
        if (!TIFFCheckRead(tif,0))
@@ -466,23 +483,37 @@ TIFFReadEncodedStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size)
                    (unsigned long)td->td_nstrips);
                return((tmsize_t)(-1));
        }
-       /*
-        * Calculate the strip size according to the number of
-        * rows in the strip (check for truncated last strip on any
-        * of the separations).
-        */
+
        rowsperstrip=td->td_rowsperstrip;
        if (rowsperstrip>td->td_imagelength)
                rowsperstrip=td->td_imagelength;
        stripsperplane= TIFFhowmany_32_maxuint_compat(td->td_imagelength, rowsperstrip);
        stripinplane=(strip%stripsperplane);
-       plane=(uint16)(strip/stripsperplane);
+       if( pplane ) *pplane=(uint16)(strip/stripsperplane);
        rows=td->td_imagelength-stripinplane*rowsperstrip;
        if (rows>rowsperstrip)
                rows=rowsperstrip;
        stripsize=TIFFVStripSize(tif,rows);
        if (stripsize==0)
                return((tmsize_t)(-1));
+       return stripsize;
+}
+
+/*
+ * Read a strip of data and decompress the specified
+ * amount into the user-supplied buffer.
+ */
+tmsize_t
+TIFFReadEncodedStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size)
+{
+       static const char module[] = "TIFFReadEncodedStrip";
+       TIFFDirectory *td = &tif->tif_dir;
+       tmsize_t stripsize;
+       uint16 plane;
+
+       stripsize=TIFFReadEncodedStripGetStripSize(tif, strip, &plane);
+       if (stripsize==((tmsize_t)(-1)))
+               return((tmsize_t)(-1));
 
     /* shortcut to avoid an extra memcpy() */
     if( td->td_compression == COMPRESSION_NONE &&
@@ -511,6 +542,49 @@ TIFFReadEncodedStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size)
        return(stripsize);
 }
 
+/* Variant of TIFFReadEncodedStrip() that does 
+ * * if *buf == NULL, *buf = _TIFFmalloc(bufsizetoalloc) only after TIFFFillStrip() has
+ *   succeeded. This avoid excessive memory allocation in case of truncated
+ *   file.
+ * * calls regular TIFFReadEncodedStrip() if *buf != NULL
+ */
+tmsize_t
+_TIFFReadEncodedStripAndAllocBuffer(TIFF* tif, uint32 strip,
+                                    void **buf, tmsize_t bufsizetoalloc,
+                                    tmsize_t size_to_read)
+{
+    tmsize_t this_stripsize;
+    uint16 plane;
+
+    if( *buf != NULL )
+    {
+        return TIFFReadEncodedStrip(tif, strip, *buf, size_to_read);
+    }
+
+    this_stripsize=TIFFReadEncodedStripGetStripSize(tif, strip, &plane);
+    if (this_stripsize==((tmsize_t)(-1)))
+            return((tmsize_t)(-1));
+
+    if ((size_to_read!=(tmsize_t)(-1))&&(size_to_read<this_stripsize))
+            this_stripsize=size_to_read;
+    if (!TIFFFillStrip(tif,strip))
+            return((tmsize_t)(-1));
+
+    *buf = _TIFFmalloc(bufsizetoalloc);
+    if (*buf == NULL) {
+            TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for strip buffer");
+            return((tmsize_t)(-1));
+    }
+    _TIFFmemset(*buf, 0, bufsizetoalloc);
+
+    if ((*tif->tif_decodestrip)(tif,*buf,this_stripsize,plane)<=0)
+            return((tmsize_t)(-1));
+    (*tif->tif_postdecode)(tif,*buf,this_stripsize);
+    return(this_stripsize);
+
+
+}
+
 static tmsize_t
 TIFFReadRawStrip1(TIFF* tif, uint32 strip, void* buf, tmsize_t size,
     const char* module)
@@ -742,26 +816,7 @@ TIFFFillStrip(TIFF* tif, uint32 strip)
                        }
                }
 
-               if (isMapped(tif) &&
-                   (isFillOrder(tif, td->td_fillorder)
-                   || (tif->tif_flags & TIFF_NOBITREV))) {
-                       /*
-                        * The image is mapped into memory and we either don't
-                        * need to flip bits or the compression routine is
-                        * going to handle this operation itself.  In this
-                        * case, avoid copying the raw data and instead just
-                        * reference the data from the memory mapped file
-                        * image.  This assumes that the decompression
-                        * routines do not modify the contents of the raw data
-                        * buffer (if they try to, the application will get a
-                        * fault since the file is mapped read-only).
-                        */
-                       if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) {
-                               _TIFFfree(tif->tif_rawdata);
-                               tif->tif_rawdata = NULL;
-                               tif->tif_rawdatasize = 0;
-                       }
-                       tif->tif_flags &= ~TIFF_MYBUFFER;
+               if (isMapped(tif)) {
                        /*
                         * We must check for overflow, potentially causing
                         * an OOB read. Instead of simple
@@ -798,6 +853,28 @@ TIFFFillStrip(TIFF* tif, uint32 strip)
                                tif->tif_curstrip = NOSTRIP;
                                return (0);
                        }
+               }
+
+               if (isMapped(tif) &&
+                   (isFillOrder(tif, td->td_fillorder)
+                   || (tif->tif_flags & TIFF_NOBITREV))) {
+                       /*
+                        * The image is mapped into memory and we either don't
+                        * need to flip bits or the compression routine is
+                        * going to handle this operation itself.  In this
+                        * case, avoid copying the raw data and instead just
+                        * reference the data from the memory mapped file
+                        * image.  This assumes that the decompression
+                        * routines do not modify the contents of the raw data
+                        * buffer (if they try to, the application will get a
+                        * fault since the file is mapped read-only).
+                        */
+                       if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) {
+                               _TIFFfree(tif->tif_rawdata);
+                               tif->tif_rawdata = NULL;
+                               tif->tif_rawdatasize = 0;
+                       }
+                       tif->tif_flags &= ~TIFF_MYBUFFER;
                        tif->tif_rawdatasize = (tmsize_t)bytecount;
                        tif->tif_rawdata = tif->tif_base + (tmsize_t)td->td_stripoffset[strip];
                         tif->tif_rawdataoff = 0;
@@ -940,6 +1017,77 @@ TIFFReadEncodedTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size)
                return ((tmsize_t)(-1));
 }
 
+/* Variant of TIFFReadTile() that does 
+ * * if *buf == NULL, *buf = _TIFFmalloc(bufsizetoalloc) only after TIFFFillTile() has
+ *   succeeded. This avoid excessive memory allocation in case of truncated
+ *   file.
+ * * calls regular TIFFReadEncodedTile() if *buf != NULL
+ */
+tmsize_t
+_TIFFReadTileAndAllocBuffer(TIFF* tif,
+                            void **buf, tmsize_t bufsizetoalloc,
+                            uint32 x, uint32 y, uint32 z, uint16 s)
+{
+    if (!TIFFCheckRead(tif, 1) || !TIFFCheckTile(tif, x, y, z, s))
+            return ((tmsize_t)(-1));
+    return (_TIFFReadEncodedTileAndAllocBuffer(tif,
+                                               TIFFComputeTile(tif, x, y, z, s),
+                                               buf, bufsizetoalloc,
+                                               (tmsize_t)(-1)));
+}
+
+/* Variant of TIFFReadEncodedTile() that does 
+ * * if *buf == NULL, *buf = _TIFFmalloc(bufsizetoalloc) only after TIFFFillTile() has
+ *   succeeded. This avoid excessive memory allocation in case of truncated
+ *   file.
+ * * calls regular TIFFReadEncodedTile() if *buf != NULL
+ */
+tmsize_t
+_TIFFReadEncodedTileAndAllocBuffer(TIFF* tif, uint32 tile,
+                                    void **buf, tmsize_t bufsizetoalloc,
+                                    tmsize_t size_to_read)
+{
+    static const char module[] = "_TIFFReadEncodedTileAndAllocBuffer";
+    TIFFDirectory *td = &tif->tif_dir;
+    tmsize_t tilesize = tif->tif_tilesize;
+
+    if( *buf != NULL )
+    {
+        return TIFFReadEncodedTile(tif, tile, *buf, size_to_read);
+    }
+
+    if (!TIFFCheckRead(tif, 1))
+            return ((tmsize_t)(-1));
+    if (tile >= td->td_nstrips) {
+            TIFFErrorExt(tif->tif_clientdata, module,
+                "%lu: Tile out of range, max %lu",
+                (unsigned long) tile, (unsigned long) td->td_nstrips);
+            return ((tmsize_t)(-1));
+    }
+
+    if (!TIFFFillTile(tif,tile))
+            return((tmsize_t)(-1));
+
+    *buf = _TIFFmalloc(bufsizetoalloc);
+    if (*buf == NULL) {
+            TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif),
+                         "No space for tile buffer");
+            return((tmsize_t)(-1));
+    }
+    _TIFFmemset(*buf, 0, bufsizetoalloc);
+
+    if (size_to_read == (tmsize_t)(-1))
+        size_to_read = tilesize;
+    else if (size_to_read > tilesize)
+        size_to_read = tilesize;
+    if( (*tif->tif_decodetile)(tif,
+        (uint8*) *buf, size_to_read, (uint16)(tile/td->td_stripsperimage))) {
+        (*tif->tif_postdecode)(tif, (uint8*) *buf, size_to_read);
+        return (size_to_read);
+    } else
+        return ((tmsize_t)(-1));
+}
+
 static tmsize_t
 TIFFReadRawTile1(TIFF* tif, uint32 tile, void* buf, tmsize_t size, const char* module)
 {
@@ -1082,6 +1230,56 @@ TIFFFillTile(TIFF* tif, uint32 tile)
 #endif
                        return (0);
                }
+
+               /* To avoid excessive memory allocations: */
+               /* Byte count should normally not be larger than a number of */
+               /* times the uncompressed size plus some margin */
+                if( bytecount > 1024 * 1024 )
+                {
+                       /* 10 and 4096 are just values that could be adjusted. */
+                       /* Hopefully they are safe enough for all codecs */
+                       tmsize_t stripsize = TIFFTileSize(tif);
+                       if( stripsize != 0 &&
+                           (bytecount - 4096) / 10 > (uint64)stripsize  )
+                       {
+                               uint64 newbytecount = (uint64)stripsize * 10 + 4096;
+                               if( (int64)newbytecount >= 0 )
+                               {
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+                                       TIFFWarningExt(tif->tif_clientdata, module,
+                                         "Too large tile byte count %I64u, tile %lu. Limiting to %I64u",
+                                            (unsigned __int64) bytecount,
+                                            (unsigned long) tile,
+                                            (unsigned __int64) newbytecount);
+#else
+                                       TIFFErrorExt(tif->tif_clientdata, module,
+                                         "Too large tile byte count %llu, tile %lu. Limiting to %llu",
+                                            (unsigned long long) bytecount,
+                                            (unsigned long) tile,
+                                            (unsigned long long) newbytecount);
+#endif
+                                       bytecount = newbytecount;
+                               }
+                       }
+               }
+
+               if (isMapped(tif)) {
+                       /*
+                        * We must check for overflow, potentially causing
+                        * an OOB read. Instead of simple
+                        *
+                        *  td->td_stripoffset[tile]+bytecount > tif->tif_size
+                        *
+                        * comparison (which can overflow) we do the following
+                        * two comparisons:
+                        */
+                       if (bytecount > (uint64)tif->tif_size ||
+                           td->td_stripoffset[tile] > (uint64)tif->tif_size - bytecount) {
+                               tif->tif_curtile = NOTILE;
+                               return (0);
+                       }
+               }
+
                if (isMapped(tif) &&
                    (isFillOrder(tif, td->td_fillorder)
                     || (tif->tif_flags & TIFF_NOBITREV))) {
@@ -1102,20 +1300,7 @@ TIFFFillTile(TIFF* tif, uint32 tile)
                                tif->tif_rawdatasize = 0;
                        }
                        tif->tif_flags &= ~TIFF_MYBUFFER;
-                       /*
-                        * We must check for overflow, potentially causing
-                        * an OOB read. Instead of simple
-                        *
-                        *  td->td_stripoffset[tile]+bytecount > tif->tif_size
-                        *
-                        * comparison (which can overflow) we do the following
-                        * two comparisons:
-                        */
-                       if (bytecount > (uint64)tif->tif_size ||
-                           td->td_stripoffset[tile] > (uint64)tif->tif_size - bytecount) {
-                               tif->tif_curtile = NOTILE;
-                               return (0);
-                       }
+
                        tif->tif_rawdatasize = (tmsize_t)bytecount;
                        tif->tif_rawdata =
                                tif->tif_base + (tmsize_t)td->td_stripoffset[tile];
@@ -1314,7 +1499,10 @@ TIFFStartTile(TIFF* tif, uint32 tile)
        else
        {
                tif->tif_rawcp = tif->tif_rawdata;
-               tif->tif_rawcc = (tmsize_t)td->td_stripbytecount[tile];
+               if( tif->tif_rawdataloaded > 0 )
+                       tif->tif_rawcc = tif->tif_rawdataloaded;
+               else
+                       tif->tif_rawcc = (tmsize_t)td->td_stripbytecount[tile];
        }
        return ((*tif->tif_predecode)(tif,
                        (uint16)(tile/td->td_stripsperimage)));
index c3e8fdd..c16c6fa 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: tif_swab.c,v 1.14 2016-09-04 21:32:56 erouault Exp $ */
+/* $Id: tif_swab.c,v 1.15 2017-06-08 16:39:50 erouault Exp $ */
 
 /*
  * Copyright (c) 1988-1997 Sam Leffler
  *
  * XXX We assume short = 16-bits and long = 32-bits XXX
  */
-
 #include <precomp.h>
 
-#ifndef TIFFSwabShort
+#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabShort)
 void
 TIFFSwabShort(uint16* wp)
 {
@@ -43,7 +42,7 @@ TIFFSwabShort(uint16* wp)
 }
 #endif
 
-#ifndef TIFFSwabLong
+#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabLong)
 void
 TIFFSwabLong(uint32* lp)
 {
@@ -55,7 +54,7 @@ TIFFSwabLong(uint32* lp)
 }
 #endif
 
-#ifndef TIFFSwabLong8
+#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabLong8)
 void
 TIFFSwabLong8(uint64* lp)
 {
@@ -69,7 +68,7 @@ TIFFSwabLong8(uint64* lp)
 }
 #endif
 
-#ifndef TIFFSwabArrayOfShort
+#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfShort)
 void
 TIFFSwabArrayOfShort(register uint16* wp, tmsize_t n)
 {
@@ -85,7 +84,7 @@ TIFFSwabArrayOfShort(register uint16* wp, tmsize_t n)
 }
 #endif
 
-#ifndef TIFFSwabArrayOfTriples
+#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfTriples)
 void
 TIFFSwabArrayOfTriples(register uint8* tp, tmsize_t n)
 {
@@ -101,7 +100,7 @@ TIFFSwabArrayOfTriples(register uint8* tp, tmsize_t n)
 }
 #endif
 
-#ifndef TIFFSwabArrayOfLong
+#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfLong)
 void
 TIFFSwabArrayOfLong(register uint32* lp, tmsize_t n)
 {
@@ -118,7 +117,7 @@ TIFFSwabArrayOfLong(register uint32* lp, tmsize_t n)
 }
 #endif
 
-#ifndef TIFFSwabArrayOfLong8
+#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfLong8)
 void
 TIFFSwabArrayOfLong8(register uint64* lp, tmsize_t n)
 {
@@ -137,7 +136,7 @@ TIFFSwabArrayOfLong8(register uint64* lp, tmsize_t n)
 }
 #endif
 
-#ifndef TIFFSwabFloat
+#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabFloat)
 void
 TIFFSwabFloat(float* fp)
 {
@@ -149,7 +148,7 @@ TIFFSwabFloat(float* fp)
 }
 #endif
 
-#ifndef TIFFSwabArrayOfFloat
+#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfFloat)
 void
 TIFFSwabArrayOfFloat(register float* fp, tmsize_t n)
 {
@@ -166,7 +165,7 @@ TIFFSwabArrayOfFloat(register float* fp, tmsize_t n)
 }
 #endif
 
-#ifndef TIFFSwabDouble
+#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabDouble)
 void
 TIFFSwabDouble(double *dp)
 {
@@ -180,7 +179,7 @@ TIFFSwabDouble(double *dp)
 }
 #endif
 
-#ifndef TIFFSwabArrayOfDouble
+#if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfDouble)
 void
 TIFFSwabArrayOfDouble(double* dp, tmsize_t n)
 {
index c9e152b..51ce200 100644 (file)
@@ -1,4 +1,4 @@
-/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_warning.c,v 1.3 2010-03-10 18:56:49 bfriesen Exp $ */
+/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_warning.c,v 1.4 2017-07-04 12:54:42 erouault Exp $ */
 
 /*
  * Copyright (c) 1988-1997 Sam Leffler
@@ -27,7 +27,6 @@
 /*
  * TIFF Library.
  */
-
 #include <precomp.h>
 
 TIFFErrorHandlerExt _TIFFwarningHandlerExt = NULL;
@@ -52,24 +51,32 @@ void
 TIFFWarning(const char* module, const char* fmt, ...)
 {
        va_list ap;
-       va_start(ap, fmt);
-       if (_TIFFwarningHandler)
+       if (_TIFFwarningHandler) {
+               va_start(ap, fmt);
                (*_TIFFwarningHandler)(module, fmt, ap);
-       if (_TIFFwarningHandlerExt)
+               va_end(ap);
+       }
+       if (_TIFFwarningHandlerExt) {
+               va_start(ap, fmt);
                (*_TIFFwarningHandlerExt)(0, module, fmt, ap);
-       va_end(ap);
+               va_end(ap);
+       }
 }
 
 void
 TIFFWarningExt(thandle_t fd, const char* module, const char* fmt, ...)
 {
        va_list ap;
-       va_start(ap, fmt);
-       if (_TIFFwarningHandler)
+       if (_TIFFwarningHandler) {
+               va_start(ap, fmt);      
                (*_TIFFwarningHandler)(module, fmt, ap);
-       if (_TIFFwarningHandlerExt)
+               va_end(ap);
+       }
+       if (_TIFFwarningHandlerExt) {
+               va_start(ap, fmt);
                (*_TIFFwarningHandlerExt)(fd, module, fmt, ap);
-       va_end(ap);
+               va_end(ap);
+       }
 }
 
 
index 0621c7a..449d5a7 100644 (file)
 #define TIFF_INT64_FORMAT "%I64d"
 
 /* Signed 64-bit type */
-#ifdef __GNUC__
-#define TIFF_INT64_T signed long long
-#else
 #define TIFF_INT64_T signed __int64
-#endif
 
 /* Unsigned 64-bit type formatter */
 #define TIFF_UINT64_FORMAT "%I64u"
 
 /* Unsigned 64-bit type */
-#ifdef __GNUC__
-#define TIFF_UINT64_T unsigned long long
-#else
 #define TIFF_UINT64_T unsigned __int64
-#endif
 
 #if _WIN64
 /*
index 6af5f3d..5a38076 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: tif_dir.h,v 1.54 2011-02-18 20:53:05 fwarmerdam Exp $ */
+/* $Id: tif_dir.h,v 1.55 2017-06-01 12:44:04 erouault Exp $ */
 
 /*
  * Copyright (c) 1988-1997 Sam Leffler
@@ -291,6 +291,7 @@ struct _TIFFField {
 extern int _TIFFMergeFields(TIFF*, const TIFFField[], uint32);
 extern const TIFFField* _TIFFFindOrRegisterField(TIFF *, uint32, TIFFDataType);
 extern  TIFFField* _TIFFCreateAnonField(TIFF *, uint32, TIFFDataType);
+extern int _TIFFCheckFieldIsValidForCodec(TIFF *tif, ttag_t tag);
 
 #if defined(__cplusplus)
 }
index 799a47a..c5d566f 100644 (file)
 #define TIFF_INT64_FORMAT "%I64d"
 
 /* Signed 64-bit type */
-#ifdef __GNUC__
-#define TIFF_INT64_T signed long long
-#else
 #define TIFF_INT64_T signed __int64
-#endif
 
 /* Unsigned 64-bit type formatter */
 #define TIFF_UINT64_FORMAT "%I64u"
 
 /* Unsigned 64-bit type */
-#ifdef __GNUC__
-#define TIFF_UINT64_T unsigned long long
-#else
 #define TIFF_UINT64_T unsigned __int64
-#endif
 
 #if _WIN64
 /*
index 4978235..c7eff6d 100644 (file)
@@ -96,9 +96,12 @@ typedef void* tdata_t;          /* image data ref */
 
 #if defined(USE_WIN32_FILEIO)
 # define VC_EXTRALEAN
-//# include <windows.h>
+#ifdef __REACTOS__
 # define WIN32_NO_STATUS
 # include <windef.h>
+#else /* __REACTOS__ */
+# include <windows.h>
+#endif /* __REACTOS__ */
 # ifdef __WIN32__
 DECLARE_HANDLE(thandle_t);     /* Win32 file handle */
 # else
index 5294ee7..daa291c 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: tiffiop.h,v 1.90 2016-12-02 21:56:56 erouault Exp $ */
+/* $Id: tiffiop.h,v 1.95 2017-09-07 14:02:52 erouault Exp $ */
 
 /*
  * Copyright (c) 1988-1997 Sam Leffler
@@ -238,8 +238,7 @@ struct tiff {
        (TIFFReadFile((tif),(buf),(size))==(size))
 #endif
 #ifndef SeekOK
-#define SeekOK(tif, off) \
-       (TIFFSeekFile((tif),(off),SEEK_SET)==(off))
+#define SeekOK(tif, off) _TIFFSeekOK(tif, off)
 #endif
 #ifndef WriteOK
 #define WriteOK(tif, buf, size) \
@@ -315,6 +314,13 @@ typedef size_t TIFFIOSize_t;
 #define _TIFF_off_t off_t
 #endif
 
+#if __clang_major__ >= 4 || (__clang_major__ == 3 && __clang_minor__ >= 8)
+#define TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW __attribute__((no_sanitize("unsigned-integer-overflow")))
+#else
+#define TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
+#endif
+
+
 #if defined(__cplusplus)
 extern "C" {
 #endif
@@ -365,6 +371,20 @@ extern void* _TIFFCheckRealloc(TIFF*, void*, tmsize_t, tmsize_t, const char*);
 extern double _TIFFUInt64ToDouble(uint64);
 extern float _TIFFUInt64ToFloat(uint64);
 
+extern tmsize_t
+_TIFFReadEncodedStripAndAllocBuffer(TIFF* tif, uint32 strip,
+                                    void **buf, tmsize_t bufsizetoalloc,
+                                    tmsize_t size_to_read);
+extern tmsize_t
+_TIFFReadEncodedTileAndAllocBuffer(TIFF* tif, uint32 tile,
+                                    void **buf, tmsize_t bufsizetoalloc,
+                                    tmsize_t size_to_read);
+extern tmsize_t
+_TIFFReadTileAndAllocBuffer(TIFF* tif,
+                            void **buf, tmsize_t bufsizetoalloc,
+                            uint32 x, uint32 y, uint32 z, uint16 s);
+extern int _TIFFSeekOK(TIFF* tif, toff_t off);
+
 extern int TIFFInitDumpMode(TIFF*, int);
 #ifdef PACKBITS_SUPPORT
 extern int TIFFInitPackBits(TIFF*, int);
@@ -387,6 +407,7 @@ extern int TIFFInitOJPEG(TIFF*, int);
 #endif
 #ifdef JPEG_SUPPORT
 extern int TIFFInitJPEG(TIFF*, int);
+extern int TIFFJPEGIsFullStripRequired(TIFF*);
 #endif
 #ifdef JBIG_SUPPORT
 extern int TIFFInitJBIG(TIFF*, int);
index 890e433..7c41574 100644 (file)
@@ -1,4 +1,4 @@
-#define TIFFLIB_VERSION_STR "LIBTIFF, Version 4.0.8\nCopyright (c) 1988-1996 Sam Leffler\nCopyright (c) 1991-1996 Silicon Graphics, Inc."
+#define TIFFLIB_VERSION_STR "LIBTIFF, Version 4.0.9\nCopyright (c) 1988-1996 Sam Leffler\nCopyright (c) 1991-1996 Silicon Graphics, Inc."
 /*
  * This define can be used in code that requires
  * compilation-related definitions specific to a
@@ -6,4 +6,4 @@
  * version checking should be done based on the
  * string returned by TIFFGetVersion.
  */
-#define TIFFLIB_VERSION 20170521
+#define TIFFLIB_VERSION 20171118