2016-11-20  Juan Manuel Guerrero  <juan.guerrero@gmx.de>

	* contrib/iptcutil/iptcutil.c [_O_BINARY]:  Define _O_BINARY as O_BINARY,
	_fileno as _fileno and _setmode as setmode.
	[__DJGPP__]:  Include <sys/exceptn.h> for __djgpp_set_ctrl_c declaration
	and <unistd.h> for isatty declaration.
	Define SET_BINARY macro.  For POSIX like OS this is a no-op.  For Win32
	it calls setmode.
	(main):  For DJGPP, call SET_BINARY to reenable SIGINT and SIGQUIT
	signals if stdin and/or stdout is connected to console and has been
	switched to binary mode.

	* libtiff/tiffiop.h [HAVE_SEARCH_H]:  New guard HAVE_LFIND added.
	Do not assume that <search.h> provides lfind().

	* libtiff/tif_jpeg.c (JPEGCleanup, JPEGPrintDir):  Assertion did not
	hold true, resulting in the client application calling abort().

	* tools/fax2ps.c [_O_BINARY]:  Define _O_BINARY as O_BINARY, _fileno as
	_fileno and _setmode as setmode.
	[__DJGPP__]:  Define SET_BINARY to have interruptible terminal reads
	and writes; include <unistd.h> for isatty declaration and
	<sys/exceptn.h> for __djgpp_set_ctrl_c declaration.  For POSIX like OS
	this is a no-op.  For Win32 it calls setmode.
	(main):  Use SET_BINARY instead of setmode() to reenable SIGINT and
	SIGQUIT if stdin and/or stdout is connected to console and has been
	switched to binary mode.

	* tools/ppm2tiff.c [_O_BINARY]:  Define _O_BINARY as O_BINARY, _fileno as
	_fileno and _setmode as setmode.
	[__DJGPP__]: Define SET_BINARY to have interruptible terminale reads
	and writes; include <unistd.h> for isatty declaration and
	<sys/exceptn.h> for __djgpp_set_ctrl_c declaration.  For POSIX like OS
	this is a no-op.  For Win32 it calls setmode.
	(main):  Use SET_BINARY instead of setmode() to reenable SIGINT and
	SIGQUIT if stdin and/or stdout is connected to console and has been
	switched to binary mode.






diff -aprNU5 tiff-4.0.7.orig/contrib/iptcutil/iptcutil.c tiff-4.0.7/contrib/iptcutil/iptcutil.c
--- tiff-4.0.7.orig/contrib/iptcutil/iptcutil.c	2015-06-21 03:09:08 +0200
+++ tiff-4.0.7/contrib/iptcutil/iptcutil.c	2016-11-20 23:26:08 +0100
@@ -11,10 +11,50 @@
 # include <strings.h>
 #endif
 
 #ifdef HAVE_IO_H
 # include <io.h>
+# ifdef _O_BINARY
+#  define _O_BINARY       O_BINARY
+#  define _fileno(f)      fileno(f)
+#  define _setmode(f, m)  setmode(f, m)
+# endif /* __O_BINARY */
+
+# ifdef __DJGPP__
+#  if defined (__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8))
+#    define __gnuc_extension__  __extension__
+#  else
+#    define __gnuc_extension__
+#  endif
+
+#  include <unistd.h>       /* to declare isatty() */
+#  include <sys/exceptn.h>  /* to declare __djgpp_set_ctrl_c() */
+   /* This is DJGPP-specific.  By default, switching console
+      to binary mode disables SIGINT and SIGQUIT.  But it
+      is preferable to have terminal reads and writes to
+      be interruptible.  */
+#  define SET_BINARY(f)                                          \
+   (__gnuc_extension__                                           \
+     ({                                                          \
+        int file_descriptor = fileno(f);                         \
+        int previous_mode = setmode(file_descriptor, O_BINARY);  \
+        if (isatty(file_descriptor))                             \
+          __djgpp_set_ctrl_c(1);                                 \
+        previous_mode;                                           \
+     })                                                          \
+   )
+# endif /* __DJGPP__ */
+# ifdef WIN32
+#  define SET_BINARY(f)   (setmode(fileno(f), O_BINARY))
+# endif
+# ifdef __CYGWIN__
+#  define SET_BINARY(f)   /* */
+# endif
+#endif
+
+#ifndef SET_BINARY
+# define SET_BINARY(f)   /* */
 #endif
 
 #ifdef HAVE_FCNTL_H
 # include <fcntl.h>
 #endif
@@ -414,21 +454,17 @@ int main(int argc, char *argv[])
           c = argv[i][1];
           switch( c )
             {
             case 't':
               mode = 1;
-#ifdef WIN32
               /* Set "stdout" to binary mode: */
-              _setmode( _fileno( ofile ), _O_BINARY );
-#endif
+              SET_BINARY(ofile);
               break;
             case 'b':
               mode = 0;
-#ifdef WIN32
               /* Set "stdin" to binary mode: */
-              _setmode( _fileno( ifile ), _O_BINARY );
-#endif
+              SET_BINARY(ifile);
               break;
             case 'i':
               if (mode == 0)
                 ifile = fopen(argv[++i], "rb");
               else
diff -aprNU5 tiff-4.0.7.orig/libtiff/tiffiop.h tiff-4.0.7/libtiff/tiffiop.h
--- tiff-4.0.7.orig/libtiff/tiffiop.h	2016-01-24 16:39:50 +0100
+++ tiff-4.0.7/libtiff/tiffiop.h	2016-11-20 23:26:08 +0100
@@ -48,11 +48,11 @@
 # include <assert.h>
 #else
 # define assert(x) 
 #endif
 
-#ifdef HAVE_SEARCH_H
+#if defined HAVE_SEARCH_H && defined HAVE_LFIND
 # include <search.h>
 #else
 extern void *lfind(const void *, const void *, size_t *, size_t,
 		   int (*)(const void *, const void *));
 #endif
diff -aprNU5 tiff-4.0.7.orig/libtiff/tif_jpeg.c tiff-4.0.7/libtiff/tif_jpeg.c
--- tiff-4.0.7.orig/libtiff/tif_jpeg.c	2016-01-24 16:39:50 +0100
+++ tiff-4.0.7/libtiff/tif_jpeg.c	2016-11-20 23:26:08 +0100
@@ -2070,11 +2070,11 @@ JPEGPostEncode(TIFF* tif)
 static void
 JPEGCleanup(TIFF* tif)
 {
 	JPEGState *sp = JState(tif);
 	
-	assert(sp != 0);
+	/* assert(sp != 0); */
 
 	tif->tif_tagmethods.vgetfield = sp->vgetparent;
 	tif->tif_tagmethods.vsetfield = sp->vsetparent;
 	tif->tif_tagmethods.printdir = sp->printdir;
         if( sp->cinfo_initialized )
@@ -2207,11 +2207,15 @@ JPEGVGetField(TIFF* tif, uint32 tag, va_
 static void
 JPEGPrintDir(TIFF* tif, FILE* fd, long flags)
 {
 	JPEGState* sp = JState(tif);
 
-	assert(sp != NULL);
+	/* assert(sp != NULL); */
+	if (sp == NULL) {
+		TIFFWarningExt(tif->tif_clientdata, "JPEGPrintDir", "Unknown JPEGState");
+		return;
+	}
 	(void) flags;
 
         if( sp != NULL ) {
 		if (TIFFFieldSet(tif,FIELD_JPEGTABLES))
 			fprintf(fd, "  JPEG Tables: (%lu bytes)\n",
diff -aprNU5 tiff-4.0.7.orig/tools/fax2ps.c tiff-4.0.7/tools/fax2ps.c
--- tiff-4.0.7.orig/tools/fax2ps.c	2015-09-06 20:24:26 +0200
+++ tiff-4.0.7/tools/fax2ps.c	2016-11-20 23:26:10 +0100
@@ -39,10 +39,50 @@
 # include <fcntl.h>
 #endif
 
 #ifdef HAVE_IO_H
 # include <io.h>
+# ifdef _O_BINARY
+#  define _O_BINARY       O_BINARY
+#  define _fileno(f)      fileno(f)
+#  define _setmode(f, m)  setmode(f, m)
+# endif /* __O_BINARY */
+
+# ifdef __DJGPP__
+#  if defined (__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8))
+#    define __gnuc_extension__  __extension__
+#  else
+#    define __gnuc_extension__
+#  endif
+
+#  include <unistd.h>       /* to declare isatty() */
+#  include <sys/exceptn.h>  /* to declare __djgpp_set_ctrl_c() */
+   /* This is DJGPP-specific.  By default, switching console
+      to binary mode disables SIGINT and SIGQUIT.  But it
+      is preferable to have terminal reads and writes to
+      be interruptible.  */
+#  define SET_BINARY(f)                                          \
+   (__gnuc_extension__                                           \
+     ({                                                          \
+        int file_descriptor = fileno(f);                         \
+        int previous_mode = setmode(file_descriptor, O_BINARY);  \
+        if (isatty(file_descriptor))                             \
+          __djgpp_set_ctrl_c(1);                                 \
+        previous_mode;                                           \
+     })                                                          \
+   )
+# endif /* __DJGPP__ */
+# ifdef WIN32
+#  define SET_BINARY(f)   (setmode(fileno(f), O_BINARY))
+# endif
+# ifdef __CYGWIN__
+#  define SET_BINARY(f)   /* */
+# endif
+#endif
+
+#ifndef SET_BINARY
+# define SET_BINARY(f)   /* */
 #endif
 
 #ifdef NEED_LIBPORT
 # include "libport.h"
 #endif
@@ -393,13 +433,11 @@ main(int argc, char** argv)
 	fd = tmpfile();
 	if (fd == NULL) {
 	    fprintf(stderr, "Could not obtain temporary file.\n");
 	    exit(-2);
 	}
-#if defined(HAVE_SETMODE) && defined(O_BINARY)
-	setmode(fileno(stdin), O_BINARY);
-#endif
+	SET_BINARY(stdin);
 	while ((n = read(fileno(stdin), buf, sizeof (buf))) > 0) {
                 if (write(fileno(fd), buf, n) != n) {
                         fclose(fd);
                         fprintf(stderr,
                                 "Could not copy stdin to temporary file.\n");
diff -aprNU5 tiff-4.0.7.orig/tools/ppm2tiff.c tiff-4.0.7/tools/ppm2tiff.c
--- tiff-4.0.7.orig/tools/ppm2tiff.c	2015-08-29 00:17:08 +0200
+++ tiff-4.0.7/tools/ppm2tiff.c	2016-11-20 23:26:10 +0100
@@ -39,10 +39,50 @@
 # include <fcntl.h>
 #endif
 
 #ifdef HAVE_IO_H
 # include <io.h>
+# ifdef _O_BINARY
+#  define _O_BINARY       O_BINARY
+#  define _fileno(f)      fileno(f)
+#  define _setmode(f, m)  setmode(f, m)
+# endif /* __O_BINARY */
+
+# ifdef __DJGPP__
+#  if defined (__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8))
+#    define __gnuc_extension__  __extension__
+#  else
+#    define __gnuc_extension__
+#  endif
+
+#  include <unistd.h>       /* to declare isatty() */
+#  include <sys/exceptn.h>  /* to declare __djgpp_set_ctrl_c() */
+   /* This is DJGPP-specific.  By default, switching console
+      to binary mode disables SIGINT and SIGQUIT.  But it
+      is preferable to have terminal reads and writes to
+      be interruptible.  */
+#  define SET_BINARY(f)                                          \
+   (__gnuc_extension__                                           \
+     ({                                                          \
+        int file_descriptor = fileno(f);                         \
+        int previous_mode = setmode(file_descriptor, O_BINARY);  \
+        if (isatty(file_descriptor))                             \
+          __djgpp_set_ctrl_c(1);                                 \
+        previous_mode;                                           \
+     })                                                          \
+   )
+# endif /* __DJGPP__ */
+# ifdef WIN32
+#  define SET_BINARY(f)   (setmode(fileno(f), O_BINARY))
+# endif
+# ifdef __CYGWIN__
+#  define SET_BINARY(f)   /* */
+# endif
+#endif
+
+#ifndef SET_BINARY
+# define SET_BINARY(f)   /* */
 #endif
 
 #ifdef NEED_LIBPORT
 # include "libport.h"
 #endif
@@ -142,13 +182,11 @@ main(int argc, char* argv[])
 			return (-1);
 		}
 	} else {
 		infile = "<stdin>";
 		in = stdin;
-#if defined(HAVE_SETMODE) && defined(O_BINARY)
-		setmode(fileno(stdin), O_BINARY);
-#endif
+		SET_BINARY(stdin);
 	}
 
 	if (fgetc(in) != 'P')
 		BadPPM(infile);
 	switch (fgetc(in)) {



2016-12-19  Juan Manuel Guerrero  <juan.guerrero@gmx.de>

	Applied all patches taken from tiff_4.0.7-3.debian.tar.xz available at
	http://ftp.de.debian.org/debian/pool/main/t/tiff/.
	See the ChangeLog file for changes.






diff -aprNU5 tiff-4.0.7.orig/ChangeLog tiff-4.0.7/ChangeLog
--- tiff-4.0.7.orig/ChangeLog	2016-11-19 17:39:46 -47721848
+++ tiff-4.0.7/ChangeLog	2016-12-19 11:59:30 -47721848
@@ -1,5 +1,123 @@
+2016-12-13 Even Rouault <even.rouault at spatialys.com>
+
+	* libtiff/tif_fax3.h: revert change done on 2016-01-09 that made
+	Param member of TIFFFaxTabEnt structure a uint16 to reduce size of
+	the binary. It happens that the Hylafax software uses the tables that
+	follow this typedef (TIFFFaxMainTable, TIFFFaxWhiteTable,
+	TIFFFaxBlackTable), also they are not in a public libtiff header.
+	Raised by Lee Howard.
+	Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2636
+
+2016-12-03 Even Rouault <even.rouault at spatialys.com>
+
+	* tools/tiffcp.c: replace assert( (bps % 8) == 0 ) by a non assert check.
+	Reported by Agostino Sarubbo.
+	Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2605
+
+2016-12-03 Even Rouault <even.rouault at spatialys.com>
+
+	* tools/tiffcp.c: fix uint32 underflow/overflow that can cause heap-based
+	buffer overflow.
+	Reported by Agostino Sarubbo.
+	Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2610
+
+2016-12-03 Even Rouault <even.rouault at spatialys.com>
+
+	* tools/tiffcp.c: avoid potential division by zero if BitsPerSamples tag is
+	missing.
+	Reported by Agostino Sarubbo.
+	Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2607
+
+2016-12-03 Even Rouault <even.rouault at spatialys.com>
+
+	* tools/tif_dir.c: when TIFFGetField(, TIFFTAG_NUMBEROFINKS, ) is called,
+	limit the return number of inks to SamplesPerPixel, so that code that parses
+	ink names doesn't go past the end of the buffer.
+	Reported by Agostino Sarubbo.
+	Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2599
+
+2016-12-03 Even Rouault <even.rouault at spatialys.com>
+
+	* tools/tiffcp.c: avoid potential division by zero if BitsPerSamples tag is
+	missing.
+	Reported by Agostino Sarubbo.
+	Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2597
+
+2016-12-03 Even Rouault <even.rouault at spatialys.com>
+
+	* tools/tiffinfo.c: fix null pointer dereference in -r mode when the image has
+	no StripByteCount tag.
+	Reported by Agostino Sarubbo.
+	Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2594
+
+2016-12-03 Even Rouault <even.rouault at spatialys.com>
+
+	* tools/tiffcrop.c: fix integer division by zero when BitsPerSample is missing.
+	Reported by Agostino Sarubbo.
+	Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2619
+
+2016-12-03 Even Rouault <even.rouault at spatialys.com>
+
+	* tools/tiffcrop.c: add 3 extra bytes at end of strip buffer in
+	readSeparateStripsIntoBuffer() to avoid read outside of heap allocated buffer.
+	Reported by Agostino Sarubbo.
+	Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2621
+
+2016-12-03 Even Rouault <even.rouault at spatialys.com>
+
+	* tools/tiffcrop.c: fix readContigStripsIntoBuffer() in -i (ignore) mode so
+	that the output buffer is correctly incremented to avoid write outside bounds.
+	Reported by Agostino Sarubbo.
+	Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2620
+
+2016-12-03 Even Rouault <even.rouault at spatialys.com>
+
+	* libtiff/tif_ojpeg.c: make OJPEGDecode() early exit in case of failure in
+	OJPEGPreDecode(). This will avoid a divide by zero, and potential other issues.
+	Reported by Agostino Sarubbo.
+	Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2611
+
+2016-12-03 Even Rouault <even.rouault at spatialys.com>
+
+	* libtiff/tif_dirread.c: modify ChopUpSingleUncompressedStrip() to
+	instanciate compute ntrips as TIFFhowmany_32(td->td_imagelength, rowsperstrip),
+	instead of a logic based on the total size of data. Which is faulty is
+	the total size of data is not sufficient to fill the whole image, and thus
+	results in reading outside of the StripByCounts/StripOffsets arrays when
+	using TIFFReadScanline().
+	Reported by Agostino Sarubbo.
+	Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2608.
+
+	* libtiff/tif_strip.c: revert the change in TIFFNumberOfStrips() done
+	for http://bugzilla.maptools.org/show_bug.cgi?id=2587 / CVE-2016-9273 since
+	the above change is a better fix that makes it unnecessary.
+
+2016-12-03 Even Rouault <even.rouault at spatialys.com>
+
+	* libtiff/tif_pixarlog.c, libtiff/tif_luv.c: fix heap-based buffer
+	overflow on generation of PixarLog / LUV compressed files, with
+	ColorMap, TransferFunction attached and nasty plays with bitspersample.
+	The fix for LUV has not been tested, but suffers from the same kind
+	of issue of PixarLog.
+	Reported by Agostino Sarubbo.
+	Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2604
+
+2016-12-02 Even Rouault <even.rouault at spatialys.com>
+
+	* tools/tiffcp.c: avoid uint32 underflow in cpDecodedStrips that 
+	can cause various issues, such as buffer overflows in the library.
+	Reported by Agostino Sarubbo.
+	Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2598
+
+2016-12-02 Even Rouault <even.rouault at spatialys.com>
+
+	* libtiff/tif_read.c, libtiff/tiffiop.h: fix uint32 overflow in
+	TIFFReadEncodedStrip() that caused an integer division by zero.
+	Reported by Agostino Sarubbo.
+	Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2596
+
 2016-11-19  Bob Friesenhahn  <bfriesen@simple.dallas.tx.us>
 
 	* libtiff 4.0.7 released.
 
 	* configure.ac: Update for 4.0.7 release.
diff -aprNU5 tiff-4.0.7.orig/libtiff/tiffiop.h tiff-4.0.7/libtiff/tiffiop.h
--- tiff-4.0.7.orig/libtiff/tiffiop.h	2016-12-17 21:14:44 -47721848
+++ tiff-4.0.7/libtiff/tiffiop.h	2016-12-19 11:43:20 -47721848
@@ -248,10 +248,14 @@ struct tiff {
 
 /* NB: the uint32 casts are to silence certain ANSI-C compilers */
 #define TIFFhowmany_32(x, y) (((uint32)x < (0xffffffff - (uint32)(y-1))) ? \
 			   ((((uint32)(x))+(((uint32)(y))-1))/((uint32)(y))) : \
 			   0U)
+/* Variant of TIFFhowmany_32() that doesn't return 0 if x close to MAXUINT. */
+/* Caution: TIFFhowmany_32_maxuint_compat(x,y)*y might overflow */
+#define TIFFhowmany_32_maxuint_compat(x, y) \
+			   (((uint32)(x) / (uint32)(y)) + ((((uint32)(x) % (uint32)(y)) != 0) ? 1 : 0))
 #define TIFFhowmany8_32(x) (((x)&0x07)?((uint32)(x)>>3)+1:(uint32)(x)>>3)
 #define TIFFroundup_32(x, y) (TIFFhowmany_32(x,y)*(y))
 #define TIFFhowmany_64(x, y) ((((uint64)(x))+(((uint64)(y))-1))/((uint64)(y)))
 #define TIFFhowmany8_64(x) (((x)&0x07)?((uint64)(x)>>3)+1:(uint64)(x)>>3)
 #define TIFFroundup_64(x, y) (TIFFhowmany_64(x,y)*(y))
diff -aprNU5 tiff-4.0.7.orig/libtiff/tif_dir.c tiff-4.0.7/libtiff/tif_dir.c
--- tiff-4.0.7.orig/libtiff/tif_dir.c	2016-10-29 23:03:14 -47721848
+++ tiff-4.0.7/libtiff/tif_dir.c	2016-12-19 11:56:08 -47721848
@@ -852,10 +852,36 @@ _TIFFVGetField(TIFF* tif, uint32 tag, va
 	uint32 standard_tag = tag;
 	const TIFFField* fip = TIFFFindField(tif, tag, TIFF_ANY);
 	if( fip == NULL ) /* cannot happen since TIFFGetField() already checks it */
 	    return 0;
 	
+        if( tag == TIFFTAG_NUMBEROFINKS )
+        {
+            int i;
+            for (i = 0; i < td->td_customValueCount; i++) {
+                uint16 val;
+                TIFFTagValue *tv = td->td_customValues + i;
+                if (tv->info->field_tag != tag)
+                    continue;
+                val = *(uint16 *)tv->value;
+                /* Truncate to SamplesPerPixel, since the */
+                /* setting code for INKNAMES assume that there are SamplesPerPixel */
+                /* inknames. */
+                /* Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2599 */
+                if( val > td->td_samplesperpixel )
+                {
+                    TIFFWarningExt(tif->tif_clientdata,"_TIFFVGetField",
+                                   "Truncating NumberOfInks from %u to %u",
+                                   val, td->td_samplesperpixel);
+                    val = td->td_samplesperpixel;
+                }
+                *va_arg(ap, uint16*) = val;
+                return 1;
+            }
+            return 0;
+        }
+
 	/*
 	 * We want to force the custom code to be used for custom
 	 * fields even if the tag happens to match a well known 
 	 * one - important for reinterpreted handling of standard
 	 * tag values in custom directories (i.e. EXIF) 
diff -aprNU5 tiff-4.0.7.orig/libtiff/tif_dirread.c tiff-4.0.7/libtiff/tif_dirread.c
--- tiff-4.0.7.orig/libtiff/tif_dirread.c	2016-11-18 02:42:42 -47721848
+++ tiff-4.0.7/libtiff/tif_dirread.c	2016-12-19 11:47:18 -47721848
@@ -5500,12 +5500,11 @@ ChopUpSingleUncompressedStrip(TIFF* tif)
 	uint64 offset;
 	uint32 rowblock;
 	uint64 rowblockbytes;
 	uint64 stripbytes;
 	uint32 strip;
-	uint64 nstrips64;
-	uint32 nstrips32;
+	uint32 nstrips;
 	uint32 rowsperstrip;
 	uint64* newcounts;
 	uint64* newoffsets;
 
 	bytecount = td->td_stripbytecount[0];
@@ -5532,22 +5531,21 @@ ChopUpSingleUncompressedStrip(TIFF* tif)
 	}
 	else
 	    return;
 
 	/*
-	 * never increase the number of strips in an image
+	 * never increase the number of rows per strip
 	 */
 	if (rowsperstrip >= td->td_rowsperstrip)
 		return;
-	nstrips64 = TIFFhowmany_64(bytecount, stripbytes);
-	if ((nstrips64==0)||(nstrips64>0xFFFFFFFF)) /* something is wonky, do nothing. */
-	    return;
-	nstrips32 = (uint32)nstrips64;
+        nstrips = TIFFhowmany_32(td->td_imagelength, rowsperstrip);
+        if( nstrips == 0 )
+            return;
 
-	newcounts = (uint64*) _TIFFCheckMalloc(tif, nstrips32, sizeof (uint64),
+	newcounts = (uint64*) _TIFFCheckMalloc(tif, nstrips, sizeof (uint64),
 				"for chopped \"StripByteCounts\" array");
-	newoffsets = (uint64*) _TIFFCheckMalloc(tif, nstrips32, sizeof (uint64),
+	newoffsets = (uint64*) _TIFFCheckMalloc(tif, nstrips, sizeof (uint64),
 				"for chopped \"StripOffsets\" array");
 	if (newcounts == NULL || newoffsets == NULL) {
 		/*
 		 * Unable to allocate new strip information, give up and use
 		 * the original one strip information.
@@ -5560,22 +5558,22 @@ ChopUpSingleUncompressedStrip(TIFF* tif)
 	}
 	/*
 	 * Fill the strip information arrays with new bytecounts and offsets
 	 * that reflect the broken-up format.
 	 */
-	for (strip = 0; strip < nstrips32; strip++) {
+	for (strip = 0; strip < nstrips; strip++) {
 		if (stripbytes > bytecount)
 			stripbytes = bytecount;
 		newcounts[strip] = stripbytes;
-		newoffsets[strip] = offset;
+		newoffsets[strip] = stripbytes ? offset : 0;
 		offset += stripbytes;
 		bytecount -= stripbytes;
 	}
 	/*
 	 * Replace old single strip info with multi-strip info.
 	 */
-	td->td_stripsperimage = td->td_nstrips = nstrips32;
+	td->td_stripsperimage = td->td_nstrips = nstrips;
 	TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
 
 	_TIFFfree(td->td_stripbytecount);
 	_TIFFfree(td->td_stripoffset);
 	td->td_stripbytecount = newcounts;
diff -aprNU5 tiff-4.0.7.orig/libtiff/tif_fax3.h tiff-4.0.7/libtiff/tif_fax3.h
--- tiff-4.0.7.orig/libtiff/tif_fax3.h	2016-01-24 15:39:46 -47721848
+++ tiff-4.0.7/libtiff/tif_fax3.h	2016-12-19 11:59:32 -47721848
@@ -79,14 +79,16 @@ extern void _TIFFFax3fillruns(unsigned c
 #define S_MakeUpW  9
 #define S_MakeUpB  10
 #define S_MakeUp   11
 #define S_EOL      12
 
+/* WARNING: do not change the layout of this structure as the Halyfax software */
+/* really depends on it. See http://bugzilla.maptools.org/show_bug.cgi?id=2636 */
 typedef struct {                /* state table entry */
 	unsigned char State;    /* see above */
 	unsigned char Width;    /* width of code in bits */
-	uint16 Param;           /* unsigned 16-bit run length in bits */
+	uint32 Param;           /* unsigned 32-bit run length in bits (holds on 16 bit actually, but cannot be changed. See above warning) */
 } TIFFFaxTabEnt;
 
 extern const TIFFFaxTabEnt TIFFFaxMainTable[];
 extern const TIFFFaxTabEnt TIFFFaxWhiteTable[];
 extern const TIFFFaxTabEnt TIFFFaxBlackTable[];
diff -aprNU5 tiff-4.0.7.orig/libtiff/tif_luv.c tiff-4.0.7/libtiff/tif_luv.c
--- tiff-4.0.7.orig/libtiff/tif_luv.c	2016-09-08 13:23:52 -47721848
+++ tiff-4.0.7/libtiff/tif_luv.c	2016-12-19 11:45:12 -47721848
@@ -156,10 +156,11 @@
  * file using LogLuv compression/decompression.
  */
 typedef struct logLuvState LogLuvState;
 
 struct logLuvState {
+        int                     encoder_state;  /* 1 if encoder correctly initialized */
 	int                     user_datafmt;   /* user data format */
 	int                     encode_meth;    /* encoding method */
 	int                     pixel_size;     /* bytes per pixel */
 
 	uint8*                  tbuf;           /* translation buffer */
@@ -1550,10 +1551,11 @@ LogLuvSetupEncode(TIFF* tif)
 		TIFFErrorExt(tif->tif_clientdata, module,
 		    "Inappropriate photometric interpretation %d for SGILog compression; %s",
 		    td->td_photometric, "must be either LogLUV or LogL");
 		break;
 	}
+	sp->encoder_state = 1;
 	return (1);
 notsupported:
 	TIFFErrorExt(tif->tif_clientdata, module,
 	    "SGILog compression supported only for %s, or raw data",
 	    td->td_photometric == PHOTOMETRIC_LOGL ? "Y, L" : "XYZ, Luv");
@@ -1561,23 +1563,31 @@ notsupported:
 }
 
 static void
 LogLuvClose(TIFF* tif)
 {
+        LogLuvState* sp = (LogLuvState*) tif->tif_data;
 	TIFFDirectory *td = &tif->tif_dir;
 
+	assert(sp != 0);
 	/*
 	 * For consistency, we always want to write out the same
 	 * bitspersample and sampleformat for our TIFF file,
 	 * regardless of the data format being used by the application.
 	 * Since this routine is called after tags have been set but
 	 * before they have been recorded in the file, we reset them here.
+         * Note: this is really a nasty approach. See PixarLogClose
 	 */
-	td->td_samplesperpixel =
-	    (td->td_photometric == PHOTOMETRIC_LOGL) ? 1 : 3;
-	td->td_bitspersample = 16;
-	td->td_sampleformat = SAMPLEFORMAT_INT;
+        if( sp->encoder_state )
+        {
+            /* See PixarLogClose. Might avoid issues with tags whose size depends
+             * on those below, but not completely sure this is enough. */
+            td->td_samplesperpixel =
+                (td->td_photometric == PHOTOMETRIC_LOGL) ? 1 : 3;
+            td->td_bitspersample = 16;
+            td->td_sampleformat = SAMPLEFORMAT_INT;
+        }
 }
 
 static void
 LogLuvCleanup(TIFF* tif)
 {
diff -aprNU5 tiff-4.0.7.orig/libtiff/tif_ojpeg.c tiff-4.0.7/libtiff/tif_ojpeg.c
--- tiff-4.0.7.orig/libtiff/tif_ojpeg.c	2016-09-08 13:23:52 -47721848
+++ tiff-4.0.7/libtiff/tif_ojpeg.c	2016-12-19 11:47:26 -47721848
@@ -242,10 +242,11 @@ typedef enum {
 	ososEoi
 } OJPEGStateOutState;
 
 typedef struct {
 	TIFF* tif;
+        int decoder_ok;
 	#ifndef LIBJPEG_ENCAP_EXTERNAL
 	JMP_BUF exit_jmpbuf;
 	#endif
 	TIFFVGetMethod vgetparent;
 	TIFFVSetMethod vsetparent;
@@ -720,10 +721,11 @@ OJPEGPreDecode(TIFF* tif, uint16 s)
 			if (OJPEGPreDecodeSkipScanlines(tif)==0)
 				return(0);
 		}
 		sp->write_curstrile++;
 	}
+	sp->decoder_ok = 1;
 	return(1);
 }
 
 static int
 OJPEGPreDecodeSkipRaw(TIFF* tif)
@@ -782,12 +784,18 @@ OJPEGPreDecodeSkipScanlines(TIFF* tif)
 }
 
 static int
 OJPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
 {
+        static const char module[]="OJPEGDecode";
 	OJPEGState* sp=(OJPEGState*)tif->tif_data;
 	(void)s;
+        if( !sp->decoder_ok )
+        {
+            TIFFErrorExt(tif->tif_clientdata,module,"Cannot decode: decoder not correctly initialized");
+            return 0;
+        }
 	if (sp->libjpeg_jpeg_query_style==0)
 	{
 		if (OJPEGDecodeRaw(tif,buf,cc)==0)
 			return(0);
 	}
diff -aprNU5 tiff-4.0.7.orig/libtiff/tif_pixarlog.c tiff-4.0.7/libtiff/tif_pixarlog.c
--- tiff-4.0.7.orig/libtiff/tif_pixarlog.c	2016-09-23 22:56:02 -47721848
+++ tiff-4.0.7/libtiff/tif_pixarlog.c	2016-12-19 11:45:12 -47721848
@@ -1231,22 +1231,35 @@ PixarLogPostEncode(TIFF* tif)
 }
 
 static void
 PixarLogClose(TIFF* tif)
 {
+        PixarLogState* sp = (PixarLogState*) tif->tif_data;
 	TIFFDirectory *td = &tif->tif_dir;
 
+	assert(sp != 0);
 	/* In a really sneaky (and really incorrect, and untruthful, and
 	 * troublesome, and error-prone) maneuver that completely goes against
 	 * the spirit of TIFF, and breaks TIFF, on close, we covertly
 	 * modify both bitspersample and sampleformat in the directory to
 	 * indicate 8-bit linear.  This way, the decode "just works" even for
 	 * readers that don't know about PixarLog, or how to set
 	 * the PIXARLOGDATFMT pseudo-tag.
 	 */
-	td->td_bitspersample = 8;
-	td->td_sampleformat = SAMPLEFORMAT_UINT;
+
+        if (sp->state&PLSTATE_INIT) {
+            /* We test the state to avoid an issue such as in
+             * http://bugzilla.maptools.org/show_bug.cgi?id=2604
+             * What appends in that case is that the bitspersample is 1 and
+             * a TransferFunction is set. The size of the TransferFunction
+             * depends on 1<<bitspersample. So if we increase it, an access
+             * out of the buffer will happen at directory flushing.
+             * Another option would be to clear those targs. 
+             */
+            td->td_bitspersample = 8;
+            td->td_sampleformat = SAMPLEFORMAT_UINT;
+        }
 }
 
 static void
 PixarLogCleanup(TIFF* tif)
 {
diff -aprNU5 tiff-4.0.7.orig/libtiff/tif_read.c tiff-4.0.7/libtiff/tif_read.c
--- tiff-4.0.7.orig/libtiff/tif_read.c	2016-07-13 13:28:12 -47721848
+++ tiff-4.0.7/libtiff/tif_read.c	2016-12-19 11:43:20 -47721848
@@ -344,11 +344,11 @@ TIFFReadEncodedStrip(TIFF* tif, uint32 s
 	 * of the separations).
 	 */
 	rowsperstrip=td->td_rowsperstrip;
 	if (rowsperstrip>td->td_imagelength)
 		rowsperstrip=td->td_imagelength;
-	stripsperplane=((td->td_imagelength+rowsperstrip-1)/rowsperstrip);
+	stripsperplane= TIFFhowmany_32_maxuint_compat(td->td_imagelength, rowsperstrip);
 	stripinplane=(strip%stripsperplane);
 	plane=(uint16)(strip/stripsperplane);
 	rows=td->td_imagelength-stripinplane*rowsperstrip;
 	if (rows>rowsperstrip)
 		rows=rowsperstrip;
diff -aprNU5 tiff-4.0.7.orig/libtiff/tif_strip.c tiff-4.0.7/libtiff/tif_strip.c
--- tiff-4.0.7.orig/libtiff/tif_strip.c	2016-11-10 02:12:32 -47721848
+++ tiff-4.0.7/libtiff/tif_strip.c	2016-12-19 11:47:18 -47721848
@@ -61,19 +61,10 @@ uint32
 TIFFNumberOfStrips(TIFF* tif)
 {
 	TIFFDirectory *td = &tif->tif_dir;
 	uint32 nstrips;
 
-    /* If the value was already computed and store in td_nstrips, then return it,
-       since ChopUpSingleUncompressedStrip might have altered and resized the
-       since the td_stripbytecount and td_stripoffset arrays to the new value
-       after the initial affectation of td_nstrips = TIFFNumberOfStrips() in
-       tif_dirread.c ~line 3612.
-       See http://bugzilla.maptools.org/show_bug.cgi?id=2587 */
-    if( td->td_nstrips )
-        return td->td_nstrips;
-
 	nstrips = (td->td_rowsperstrip == (uint32) -1 ? 1 :
 	     TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip));
 	if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
 		nstrips = _TIFFMultiply32(tif, nstrips, (uint32)td->td_samplesperpixel,
 		    "TIFFNumberOfStrips");
diff -aprNU5 tiff-4.0.7.orig/tools/tiffcp.c tiff-4.0.7/tools/tiffcp.c
--- tiff-4.0.7.orig/tools/tiffcp.c	2016-10-12 01:45:12 -47721848
+++ tiff-4.0.7/tools/tiffcp.c	2016-12-19 11:58:28 -47721848
@@ -43,11 +43,10 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
 #include <ctype.h>
-#include <assert.h>
 
 #ifdef HAVE_UNISTD_H
 # include <unistd.h>
 #endif
 
@@ -983,11 +982,11 @@ DECLAREcpFunc(cpDecodedStrips)
 	(void) imagewidth; (void) spp;
 	if (buf) {
 		tstrip_t s, ns = TIFFNumberOfStrips(in);
 		uint32 row = 0;
 		_TIFFmemset(buf, 0, stripsize);
-		for (s = 0; s < ns; s++) {
+		for (s = 0; s < ns && row < imagelength; s++) {
 			tsize_t cc = (row + rowsperstrip > imagelength) ?
 			    TIFFVStripSize(in, imagelength - row) : stripsize;
 			if (TIFFReadEncodedStrip(in, s, buf, cc) < 0
 			    && !ignore) {
 				TIFFError(TIFFFileName(in),
@@ -1161,11 +1160,11 @@ bad:
 	return 0;
 }
 
 static void
 cpStripToTile(uint8* out, uint8* in,
-    uint32 rows, uint32 cols, int outskew, int inskew)
+    uint32 rows, uint32 cols, int outskew, int64 inskew)
 {
 	while (rows-- > 0) {
 		uint32 j = cols;
 		while (j-- > 0)
 			*out++ = *in++;
@@ -1318,11 +1317,11 @@ DECLAREreadFunc(readContigTilesIntoBuffe
 	int status = 1;
 	tsize_t tilesize = TIFFTileSize(in);
 	tdata_t tilebuf;
 	uint32 imagew = TIFFScanlineSize(in);
 	uint32 tilew  = TIFFTileRowSize(in);
-	int iskew = imagew - tilew;
+	int64 iskew = (int64)imagew - (int64)tilew;
 	uint8* bufp = (uint8*) buf;
 	uint32 tw, tl;
 	uint32 row;
 
 	(void) spp;
@@ -1346,11 +1345,11 @@ DECLAREreadFunc(readContigTilesIntoBuffe
 				    (unsigned long) col,
 				    (unsigned long) row);
 				status = 0;
 				goto done;
 			}
-			if (colb + tilew > imagew) {
+			if (colb > iskew) {
 				uint32 width = imagew - colb;
 				uint32 oskew = tilew - width;
 				cpStripToTile(bufp + colb,
 				    tilebuf, nrow, width,
 				    oskew + iskew, oskew );
@@ -1376,20 +1375,31 @@ DECLAREreadFunc(readSeparateTilesIntoBuf
 	tsize_t tilesize = TIFFTileSize(in);
 	tdata_t tilebuf;
 	uint8* bufp = (uint8*) buf;
 	uint32 tw, tl;
 	uint32 row;
-	uint16 bps, bytes_per_sample;
+	uint16 bps = 0, bytes_per_sample;
 
 	tilebuf = _TIFFmalloc(tilesize);
 	if (tilebuf == 0)
 		return 0;
 	_TIFFmemset(tilebuf, 0, tilesize);
 	(void) TIFFGetField(in, TIFFTAG_TILEWIDTH, &tw);
 	(void) TIFFGetField(in, TIFFTAG_TILELENGTH, &tl);
 	(void) TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &bps);
-	assert( bps % 8 == 0 );
+        if( bps == 0 )
+        {
+            TIFFError(TIFFFileName(in), "Error, cannot read BitsPerSample");
+            status = 0;
+            goto done;
+        }
+        if( (bps % 8) != 0 )
+        {
+            TIFFError(TIFFFileName(in), "Error, cannot handle BitsPerSample that is not a multiple of 8");
+            status = 0;
+            goto done;
+        }
 	bytes_per_sample = bps/8;
 
 	for (row = 0; row < imagelength; row += tl) {
 		uint32 nrow = (row+tl > imagelength) ? imagelength-row : tl;
 		uint32 colb = 0;
@@ -1561,20 +1571,31 @@ DECLAREwriteFunc(writeBufferToSeparateTi
 	tsize_t tilesize = TIFFTileSize(out);
 	tdata_t obuf;
 	uint8* bufp = (uint8*) buf;
 	uint32 tl, tw;
 	uint32 row;
-	uint16 bps, bytes_per_sample;
+	uint16 bps = 0, bytes_per_sample;
 
 	obuf = _TIFFmalloc(TIFFTileSize(out));
 	if (obuf == NULL)
 		return 0;
 	_TIFFmemset(obuf, 0, tilesize);
 	(void) TIFFGetField(out, TIFFTAG_TILELENGTH, &tl);
 	(void) TIFFGetField(out, TIFFTAG_TILEWIDTH, &tw);
 	(void) TIFFGetField(out, TIFFTAG_BITSPERSAMPLE, &bps);
-	assert( bps % 8 == 0 );
+        if( bps == 0 )
+        {
+            TIFFError(TIFFFileName(out), "Error, cannot read BitsPerSample");
+            _TIFFfree(obuf);
+            return 0;
+        }
+        if( (bps % 8) != 0 )
+        {
+            TIFFError(TIFFFileName(out), "Error, cannot handle BitsPerSample that is not a multiple of 8");
+            _TIFFfree(obuf);
+            return 0;
+        }
 	bytes_per_sample = bps/8;
 
 	for (row = 0; row < imagelength; row += tl) {
 		uint32 nrow = (row+tl > imagelength) ? imagelength-row : tl;
 		uint32 colb = 0;
diff -aprNU5 tiff-4.0.7.orig/tools/tiffcrop.c tiff-4.0.7/tools/tiffcrop.c
--- tiff-4.0.7.orig/tools/tiffcrop.c	2016-11-19 01:45:26 -47721848
+++ tiff-4.0.7/tools/tiffcrop.c	2016-12-19 11:55:54 -47721848
@@ -1162,11 +1162,11 @@ writeBufferToSeparateStrips (TIFF* out,
   tsize_t  rowstripsize,  scanlinesize = TIFFScanlineSize(out);
   tsize_t  total_bytes = 0;
   tdata_t  obuf;
 
   (void) TIFFGetFieldDefaulted(out, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
-  (void) TIFFGetField(out, TIFFTAG_BITSPERSAMPLE, &bps);
+  (void) TIFFGetFieldDefaulted(out, TIFFTAG_BITSPERSAMPLE, &bps);
   bytes_per_sample = (bps + 7) / 8;
   if( width == 0 ||
       (uint32)bps * (uint32)spp > TIFF_UINT32_MAX / width ||
       bps * spp * width > TIFF_UINT32_MAX - 7U )
   {
@@ -3696,11 +3696,11 @@ static int readContigStripsIntoBuffer (T
                 if (bytes_read < 0 && !ignore) {
                         TIFFError("", "Error reading strip %lu after %lu rows",
                                   (unsigned long) strip, (unsigned long)rows);
                         return 0;
                 }
-                bufp += bytes_read;
+                bufp += stripsize;
         }
 
         return 1;
 } /* end readContigStripsIntoBuffer */
 
@@ -4758,11 +4758,11 @@ static int readSeparateStripsIntoBuffer
                                          struct dump_opts *dump)
   {
   int i, bytes_per_sample, bytes_per_pixel, shift_width, result = 1;
   uint32 j;
   int32  bytes_read = 0;
-  uint16 bps, planar;
+  uint16 bps = 0, planar;
   uint32 nstrips;
   uint32 strips_per_sample;
   uint32 src_rowsize, dst_rowsize, rows_processed, rps;
   uint32 rows_this_strip = 0;
   tsample_t s;
@@ -4778,11 +4778,11 @@ static int readSeparateStripsIntoBuffer
     TIFFError("readSeparateStripsIntoBuffer","Invalid buffer argument");
     return (0);
     }
 
   memset (srcbuffs, '\0', sizeof(srcbuffs));
-  TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &bps);
+  TIFFGetFieldDefaulted(in, TIFFTAG_BITSPERSAMPLE, &bps);
   TIFFGetFieldDefaulted(in, TIFFTAG_PLANARCONFIG, &planar);
   TIFFGetFieldDefaulted(in, TIFFTAG_ROWSPERSTRIP, &rps);
   if (rps > length)
     rps = length;
 
@@ -4813,22 +4813,32 @@ static int readSeparateStripsIntoBuffer
    * written before data for any other plane.
    */
   nstrips = TIFFNumberOfStrips(in);
   strips_per_sample = nstrips /spp;
 
+  /* Add 3 padding bytes for combineSeparateSamples32bits */
+  if( (size_t) stripsize > 0xFFFFFFFFU - 3U )
+  {
+      TIFFError("readSeparateStripsIntoBuffer", "Integer overflow when calculating buffer size.");
+      exit(-1);
+  }
+
   for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
     {
     srcbuffs[s] = NULL;
-    buff = _TIFFmalloc(stripsize);
+    buff = _TIFFmalloc(stripsize + 3);
     if (!buff)
       {
       TIFFError ("readSeparateStripsIntoBuffer", 
                  "Unable to allocate strip read buffer for sample %d", s);
       for (i = 0; i < s; i++)
         _TIFFfree (srcbuffs[i]);
       return 0;
       }
+    buff[stripsize] = 0;
+    buff[stripsize+1] = 0;
+    buff[stripsize+2] = 0;
     srcbuffs[s] = buff;
     }
 
   rows_processed = 0;
   for (j = 0; (j < strips_per_sample) && (result == 1); j++)
diff -aprNU5 tiff-4.0.7.orig/tools/tiffinfo.c tiff-4.0.7/tools/tiffinfo.c
--- tiff-4.0.7.orig/tools/tiffinfo.c	2016-11-12 20:06:00 -47721848
+++ tiff-4.0.7/tools/tiffinfo.c	2016-12-19 11:56:00 -47721848
@@ -415,11 +415,11 @@ TIFFReadRawData(TIFF* tif, int bitrev)
 	tstrip_t nstrips = TIFFNumberOfStrips(tif);
 	const char* what = TIFFIsTiled(tif) ? "Tile" : "Strip";
 	uint64* stripbc=NULL;
 
 	TIFFGetField(tif, TIFFTAG_STRIPBYTECOUNTS, &stripbc);
-	if (nstrips > 0) {
+	if (stripbc != NULL && nstrips > 0) {
 		uint32 bufsize = (uint32) stripbc[0];
 		tdata_t buf = _TIFFmalloc(bufsize);
 		tstrip_t s;
 
 		for (s = 0; s < nstrips; s++) {
