|
|
e89a5c |
From 3cb85548e07580e4d787ab7122900ae6946c8d26 Mon Sep 17 00:00:00 2001
|
|
|
e89a5c |
From: =?UTF-8?q?Nikola=20Forr=C3=B3?= <nforro@redhat.com>
|
|
|
e89a5c |
Date: Thu, 20 Feb 2020 13:08:37 +0100
|
|
|
e89a5c |
Subject: [PATCH 1/2] Fix CVE-2019-14973
|
|
|
e89a5c |
|
|
|
e89a5c |
---
|
|
|
e89a5c |
libtiff/tif_aux.c | 49 +++++-
|
|
|
e89a5c |
libtiff/tif_getimage.c | 6 +-
|
|
|
e89a5c |
libtiff/tif_luv.c | 7 +-
|
|
|
e89a5c |
libtiff/tif_pixarlog.c | 18 +-
|
|
|
e89a5c |
libtiff/tif_read.c | 375 ++++++++++++++++++++++++++++++++++-------
|
|
|
e89a5c |
libtiff/tif_strip.c | 27 +--
|
|
|
e89a5c |
libtiff/tif_tile.c | 27 +--
|
|
|
e89a5c |
libtiff/tiffiop.h | 7 +-
|
|
|
e89a5c |
8 files changed, 377 insertions(+), 139 deletions(-)
|
|
|
e89a5c |
|
|
|
e89a5c |
diff --git a/libtiff/tif_aux.c b/libtiff/tif_aux.c
|
|
|
e89a5c |
index 927150a..f686a79 100644
|
|
|
e89a5c |
--- a/libtiff/tif_aux.c
|
|
|
e89a5c |
+++ b/libtiff/tif_aux.c
|
|
|
e89a5c |
@@ -59,18 +59,57 @@ _TIFFMultiply64(TIFF* tif, uint64 first, uint64 second, const char* where)
|
|
|
e89a5c |
return bytes;
|
|
|
e89a5c |
}
|
|
|
e89a5c |
|
|
|
e89a5c |
+tmsize_t
|
|
|
e89a5c |
+_TIFFMultiplySSize(TIFF* tif, tmsize_t first, tmsize_t second, const char* where)
|
|
|
e89a5c |
+{
|
|
|
e89a5c |
+ if( first <= 0 || second <= 0 )
|
|
|
e89a5c |
+ {
|
|
|
e89a5c |
+ if( tif != NULL && where != NULL )
|
|
|
e89a5c |
+ {
|
|
|
e89a5c |
+ TIFFErrorExt(tif->tif_clientdata, where,
|
|
|
e89a5c |
+ "Invalid argument to _TIFFMultiplySSize() in %s", where);
|
|
|
e89a5c |
+ }
|
|
|
e89a5c |
+ return 0;
|
|
|
e89a5c |
+ }
|
|
|
e89a5c |
+
|
|
|
e89a5c |
+ if( first > TIFF_TMSIZE_T_MAX / second )
|
|
|
e89a5c |
+ {
|
|
|
e89a5c |
+ if( tif != NULL && where != NULL )
|
|
|
e89a5c |
+ {
|
|
|
e89a5c |
+ TIFFErrorExt(tif->tif_clientdata, where,
|
|
|
e89a5c |
+ "Integer overflow in %s", where);
|
|
|
e89a5c |
+ }
|
|
|
e89a5c |
+ return 0;
|
|
|
e89a5c |
+ }
|
|
|
e89a5c |
+ return first * second;
|
|
|
e89a5c |
+}
|
|
|
e89a5c |
+
|
|
|
e89a5c |
+tmsize_t _TIFFCastUInt64ToSSize(TIFF* tif, uint64 val, const char* module)
|
|
|
e89a5c |
+{
|
|
|
e89a5c |
+ if( val > (uint64)TIFF_TMSIZE_T_MAX )
|
|
|
e89a5c |
+ {
|
|
|
e89a5c |
+ if( tif != NULL && module != NULL )
|
|
|
e89a5c |
+ {
|
|
|
e89a5c |
+ TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
|
|
|
e89a5c |
+ }
|
|
|
e89a5c |
+ return 0;
|
|
|
e89a5c |
+ }
|
|
|
e89a5c |
+ return (tmsize_t)val;
|
|
|
e89a5c |
+}
|
|
|
e89a5c |
+
|
|
|
e89a5c |
void*
|
|
|
e89a5c |
_TIFFCheckRealloc(TIFF* tif, void* buffer,
|
|
|
e89a5c |
tmsize_t nmemb, tmsize_t elem_size, const char* what)
|
|
|
e89a5c |
{
|
|
|
e89a5c |
void* cp = NULL;
|
|
|
e89a5c |
- tmsize_t bytes = nmemb * elem_size;
|
|
|
e89a5c |
-
|
|
|
e89a5c |
+ tmsize_t count = _TIFFMultiplySSize(tif, nmemb, elem_size, NULL);
|
|
|
e89a5c |
/*
|
|
|
e89a5c |
- * XXX: Check for integer overflow.
|
|
|
e89a5c |
+ * Check for integer overflow.
|
|
|
e89a5c |
*/
|
|
|
e89a5c |
- if (nmemb && elem_size && bytes / elem_size == nmemb)
|
|
|
e89a5c |
- cp = _TIFFrealloc(buffer, bytes);
|
|
|
e89a5c |
+ if (count != 0)
|
|
|
e89a5c |
+ {
|
|
|
e89a5c |
+ cp = _TIFFrealloc(buffer, count);
|
|
|
e89a5c |
+ }
|
|
|
e89a5c |
|
|
|
e89a5c |
if (cp == NULL) {
|
|
|
e89a5c |
TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
|
|
|
e89a5c |
diff --git a/libtiff/tif_getimage.c b/libtiff/tif_getimage.c
|
|
|
e89a5c |
index 503237d..c664cc0 100644
|
|
|
e89a5c |
--- a/libtiff/tif_getimage.c
|
|
|
e89a5c |
+++ b/libtiff/tif_getimage.c
|
|
|
e89a5c |
@@ -720,9 +720,8 @@ gtTileSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
|
|
|
e89a5c |
int colorchannels;
|
|
|
e89a5c |
|
|
|
e89a5c |
tilesize = TIFFTileSize(tif);
|
|
|
e89a5c |
- bufsize = TIFFSafeMultiply(tmsize_t,alpha?4:3,tilesize);
|
|
|
e89a5c |
+ bufsize = _TIFFMultiplySSize(tif, alpha?4:3,tilesize, "gtTileSeparate");
|
|
|
e89a5c |
if (bufsize == 0) {
|
|
|
e89a5c |
- TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Integer overflow in %s", "gtTileSeparate");
|
|
|
e89a5c |
return (0);
|
|
|
e89a5c |
}
|
|
|
e89a5c |
buf = (unsigned char*) _TIFFmalloc(bufsize);
|
|
|
e89a5c |
@@ -955,9 +954,8 @@ gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
|
|
|
e89a5c |
int ret = 1, flip, colorchannels;
|
|
|
e89a5c |
|
|
|
e89a5c |
stripsize = TIFFStripSize(tif);
|
|
|
e89a5c |
- bufsize = TIFFSafeMultiply(tmsize_t,alpha?4:3,stripsize);
|
|
|
e89a5c |
+ bufsize = _TIFFMultiplySSize(tif,alpha?4:3,stripsize, "gtStripSeparate");
|
|
|
e89a5c |
if (bufsize == 0) {
|
|
|
e89a5c |
- TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Integer overflow in %s", "gtStripSeparate");
|
|
|
e89a5c |
return (0);
|
|
|
e89a5c |
}
|
|
|
e89a5c |
p0 = buf = (unsigned char *)_TIFFmalloc(bufsize);
|
|
|
e89a5c |
diff --git a/libtiff/tif_luv.c b/libtiff/tif_luv.c
|
|
|
e89a5c |
index ebbd692..0607c41 100644
|
|
|
e89a5c |
--- a/libtiff/tif_luv.c
|
|
|
e89a5c |
+++ b/libtiff/tif_luv.c
|
|
|
e89a5c |
@@ -1244,12 +1244,7 @@ LogL16GuessDataFmt(TIFFDirectory *td)
|
|
|
e89a5c |
static tmsize_t
|
|
|
e89a5c |
multiply_ms(tmsize_t m1, tmsize_t m2)
|
|
|
e89a5c |
{
|
|
|
e89a5c |
- tmsize_t bytes = m1 * m2;
|
|
|
e89a5c |
-
|
|
|
e89a5c |
- if (m1 && bytes / m1 != m2)
|
|
|
e89a5c |
- bytes = 0;
|
|
|
e89a5c |
-
|
|
|
e89a5c |
- return bytes;
|
|
|
e89a5c |
+ return _TIFFMultiplySSize(NULL, m1, m2, NULL);
|
|
|
e89a5c |
}
|
|
|
e89a5c |
|
|
|
e89a5c |
static int
|
|
|
e89a5c |
diff --git a/libtiff/tif_pixarlog.c b/libtiff/tif_pixarlog.c
|
|
|
e89a5c |
index 6128f2f..558325d 100644
|
|
|
e89a5c |
--- a/libtiff/tif_pixarlog.c
|
|
|
e89a5c |
+++ b/libtiff/tif_pixarlog.c
|
|
|
e89a5c |
@@ -637,26 +637,20 @@ PixarLogGuessDataFmt(TIFFDirectory *td)
|
|
|
e89a5c |
static tmsize_t
|
|
|
e89a5c |
multiply_ms(tmsize_t m1, tmsize_t m2)
|
|
|
e89a5c |
{
|
|
|
e89a5c |
- tmsize_t bytes = m1 * m2;
|
|
|
e89a5c |
-
|
|
|
e89a5c |
- if (m1 && bytes / m1 != m2)
|
|
|
e89a5c |
- bytes = 0;
|
|
|
e89a5c |
-
|
|
|
e89a5c |
- return bytes;
|
|
|
e89a5c |
+ return _TIFFMultiplySSize(NULL, m1, m2, NULL);
|
|
|
e89a5c |
}
|
|
|
e89a5c |
|
|
|
e89a5c |
static tmsize_t
|
|
|
e89a5c |
add_ms(tmsize_t m1, tmsize_t m2)
|
|
|
e89a5c |
{
|
|
|
e89a5c |
- tmsize_t bytes = m1 + m2;
|
|
|
e89a5c |
-
|
|
|
e89a5c |
+ assert(m1 >= 0 && m2 >= 0);
|
|
|
e89a5c |
/* if either input is zero, assume overflow already occurred */
|
|
|
e89a5c |
if (m1 == 0 || m2 == 0)
|
|
|
e89a5c |
- bytes = 0;
|
|
|
e89a5c |
- else if (bytes <= m1 || bytes <= m2)
|
|
|
e89a5c |
- bytes = 0;
|
|
|
e89a5c |
+ return 0;
|
|
|
e89a5c |
+ else if (m1 > TIFF_TMSIZE_T_MAX - m2)
|
|
|
e89a5c |
+ return 0;
|
|
|
e89a5c |
|
|
|
e89a5c |
- return bytes;
|
|
|
e89a5c |
+ return m1 + m2;
|
|
|
e89a5c |
}
|
|
|
e89a5c |
|
|
|
e89a5c |
static int
|
|
|
e89a5c |
diff --git a/libtiff/tif_read.c b/libtiff/tif_read.c
|
|
|
e89a5c |
index ff5a548..2198b17 100644
|
|
|
e89a5c |
--- a/libtiff/tif_read.c
|
|
|
e89a5c |
+++ b/libtiff/tif_read.c
|
|
|
e89a5c |
@@ -1,4 +1,4 @@
|
|
|
e89a5c |
-/* $Id: tif_read.c,v 1.41 2012-07-06 19:22:58 bfriesen Exp $ */
|
|
|
e89a5c |
+/* $Id: tif_read.c,v 1.42 2013-01-18 21:37:13 fwarmerdam Exp $ */
|
|
|
e89a5c |
|
|
|
e89a5c |
/*
|
|
|
e89a5c |
* Copyright (c) 1988-1997 Sam Leffler
|
|
|
e89a5c |
@@ -42,14 +42,132 @@ TIFFReadRawStrip1(TIFF* tif, uint32 strip, void* buf, tmsize_t size,const char*
|
|
|
e89a5c |
#define NOSTRIP ((uint32)(-1)) /* undefined state */
|
|
|
e89a5c |
#define NOTILE ((uint32)(-1)) /* undefined state */
|
|
|
e89a5c |
|
|
|
e89a5c |
+#define INITIAL_THRESHOLD (1024 * 1024)
|
|
|
e89a5c |
+#define THRESHOLD_MULTIPLIER 10
|
|
|
e89a5c |
+#define MAX_THRESHOLD (THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * INITIAL_THRESHOLD)
|
|
|
e89a5c |
+
|
|
|
e89a5c |
+#define TIFF_INT64_MAX ((((int64)0x7FFFFFFF) << 32) | 0xFFFFFFFF)
|
|
|
e89a5c |
+
|
|
|
e89a5c |
+/* Read 'size' bytes in tif_rawdata buffer starting at offset 'rawdata_offset'
|
|
|
e89a5c |
+ * Returns 1 in case of success, 0 otherwise. */
|
|
|
e89a5c |
+static int TIFFReadAndRealloc( TIFF* tif, tmsize_t size,
|
|
|
e89a5c |
+ tmsize_t rawdata_offset,
|
|
|
e89a5c |
+ int is_strip, uint32 strip_or_tile,
|
|
|
e89a5c |
+ const char* module )
|
|
|
e89a5c |
+{
|
|
|
e89a5c |
+#if SIZEOF_VOIDP == 8 || SIZEOF_SIZE_T == 8
|
|
|
e89a5c |
+ tmsize_t threshold = INITIAL_THRESHOLD;
|
|
|
e89a5c |
+#endif
|
|
|
e89a5c |
+ tmsize_t already_read = 0;
|
|
|
e89a5c |
+
|
|
|
e89a5c |
+ /* On 64 bit processes, read first a maximum of 1 MB, then 10 MB, etc */
|
|
|
e89a5c |
+ /* so as to avoid allocating too much memory in case the file is too */
|
|
|
e89a5c |
+ /* short. We could ask for the file size, but this might be */
|
|
|
e89a5c |
+ /* expensive with some I/O layers (think of reading a gzipped file) */
|
|
|
e89a5c |
+ /* Restrict to 64 bit processes, so as to avoid reallocs() */
|
|
|
e89a5c |
+ /* on 32 bit processes where virtual memory is scarce. */
|
|
|
e89a5c |
+ while( already_read < size )
|
|
|
e89a5c |
+ {
|
|
|
e89a5c |
+ tmsize_t bytes_read;
|
|
|
e89a5c |
+ tmsize_t to_read = size - already_read;
|
|
|
e89a5c |
+#if SIZEOF_VOIDP == 8 || SIZEOF_SIZE_T == 8
|
|
|
e89a5c |
+ if( to_read >= threshold && threshold < MAX_THRESHOLD &&
|
|
|
e89a5c |
+ already_read + to_read + rawdata_offset > tif->tif_rawdatasize )
|
|
|
e89a5c |
+ {
|
|
|
e89a5c |
+ to_read = threshold;
|
|
|
e89a5c |
+ threshold *= THRESHOLD_MULTIPLIER;
|
|
|
e89a5c |
+ }
|
|
|
e89a5c |
+#endif
|
|
|
e89a5c |
+ if (already_read + to_read + rawdata_offset > tif->tif_rawdatasize) {
|
|
|
e89a5c |
+ uint8* new_rawdata;
|
|
|
e89a5c |
+ assert((tif->tif_flags & TIFF_MYBUFFER) != 0);
|
|
|
e89a5c |
+ tif->tif_rawdatasize = (tmsize_t)TIFFroundup_64(
|
|
|
e89a5c |
+ (uint64)already_read + to_read + rawdata_offset, 1024);
|
|
|
e89a5c |
+ if (tif->tif_rawdatasize==0) {
|
|
|
e89a5c |
+ TIFFErrorExt(tif->tif_clientdata, module,
|
|
|
e89a5c |
+ "Invalid buffer size");
|
|
|
e89a5c |
+ return 0;
|
|
|
e89a5c |
+ }
|
|
|
e89a5c |
+ new_rawdata = (uint8*) _TIFFrealloc(
|
|
|
e89a5c |
+ tif->tif_rawdata, tif->tif_rawdatasize);
|
|
|
e89a5c |
+ if( new_rawdata == 0 )
|
|
|
e89a5c |
+ {
|
|
|
e89a5c |
+ TIFFErrorExt(tif->tif_clientdata, module,
|
|
|
e89a5c |
+ "No space for data buffer at scanline %lu",
|
|
|
e89a5c |
+ (unsigned long) tif->tif_row);
|
|
|
e89a5c |
+ _TIFFfree(tif->tif_rawdata);
|
|
|
e89a5c |
+ tif->tif_rawdata = 0;
|
|
|
e89a5c |
+ tif->tif_rawdatasize = 0;
|
|
|
e89a5c |
+ return 0;
|
|
|
e89a5c |
+ }
|
|
|
e89a5c |
+ tif->tif_rawdata = new_rawdata;
|
|
|
e89a5c |
+ }
|
|
|
e89a5c |
+
|
|
|
e89a5c |
+ bytes_read = TIFFReadFile(tif,
|
|
|
e89a5c |
+ tif->tif_rawdata + rawdata_offset + already_read, to_read);
|
|
|
e89a5c |
+ already_read += bytes_read;
|
|
|
e89a5c |
+ if (bytes_read != to_read) {
|
|
|
e89a5c |
+ memset( tif->tif_rawdata + rawdata_offset + already_read, 0,
|
|
|
e89a5c |
+ tif->tif_rawdatasize - rawdata_offset - already_read );
|
|
|
e89a5c |
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
|
|
|
e89a5c |
+ if( is_strip )
|
|
|
e89a5c |
+ {
|
|
|
e89a5c |
+ TIFFErrorExt(tif->tif_clientdata, module,
|
|
|
e89a5c |
+ "Read error at scanline %lu; got %I64u bytes, "
|
|
|
e89a5c |
+ "expected %I64u",
|
|
|
e89a5c |
+ (unsigned long) tif->tif_row,
|
|
|
e89a5c |
+ (unsigned __int64) already_read,
|
|
|
e89a5c |
+ (unsigned __int64) size);
|
|
|
e89a5c |
+ }
|
|
|
e89a5c |
+ else
|
|
|
e89a5c |
+ {
|
|
|
e89a5c |
+ TIFFErrorExt(tif->tif_clientdata, module,
|
|
|
e89a5c |
+ "Read error at row %lu, col %lu, tile %lu; "
|
|
|
e89a5c |
+ "got %I64u bytes, expected %I64u",
|
|
|
e89a5c |
+ (unsigned long) tif->tif_row,
|
|
|
e89a5c |
+ (unsigned long) tif->tif_col,
|
|
|
e89a5c |
+ (unsigned long) strip_or_tile,
|
|
|
e89a5c |
+ (unsigned __int64) already_read,
|
|
|
e89a5c |
+ (unsigned __int64) size);
|
|
|
e89a5c |
+ }
|
|
|
e89a5c |
+#else
|
|
|
e89a5c |
+ if( is_strip )
|
|
|
e89a5c |
+ {
|
|
|
e89a5c |
+ TIFFErrorExt(tif->tif_clientdata, module,
|
|
|
e89a5c |
+ "Read error at scanline %lu; got %llu bytes, "
|
|
|
e89a5c |
+ "expected %llu",
|
|
|
e89a5c |
+ (unsigned long) tif->tif_row,
|
|
|
e89a5c |
+ (unsigned long long) already_read,
|
|
|
e89a5c |
+ (unsigned long long) size);
|
|
|
e89a5c |
+ }
|
|
|
e89a5c |
+ else
|
|
|
e89a5c |
+ {
|
|
|
e89a5c |
+ TIFFErrorExt(tif->tif_clientdata, module,
|
|
|
e89a5c |
+ "Read error at row %lu, col %lu, tile %lu; "
|
|
|
e89a5c |
+ "got %llu bytes, expected %llu",
|
|
|
e89a5c |
+ (unsigned long) tif->tif_row,
|
|
|
e89a5c |
+ (unsigned long) tif->tif_col,
|
|
|
e89a5c |
+ (unsigned long) strip_or_tile,
|
|
|
e89a5c |
+ (unsigned long long) already_read,
|
|
|
e89a5c |
+ (unsigned long long) size);
|
|
|
e89a5c |
+ }
|
|
|
e89a5c |
+#endif
|
|
|
e89a5c |
+ return 0;
|
|
|
e89a5c |
+ }
|
|
|
e89a5c |
+ }
|
|
|
e89a5c |
+ return 1;
|
|
|
e89a5c |
+}
|
|
|
e89a5c |
+
|
|
|
e89a5c |
+
|
|
|
e89a5c |
static int
|
|
|
e89a5c |
TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart )
|
|
|
e89a5c |
{
|
|
|
e89a5c |
static const char module[] = "TIFFFillStripPartial";
|
|
|
e89a5c |
register TIFFDirectory *td = &tif->tif_dir;
|
|
|
e89a5c |
- uint64 unused_data;
|
|
|
e89a5c |
+ tmsize_t unused_data;
|
|
|
e89a5c |
uint64 read_offset;
|
|
|
e89a5c |
- tmsize_t cc, to_read;
|
|
|
e89a5c |
+ tmsize_t to_read;
|
|
|
e89a5c |
+ tmsize_t read_ahead_mod;
|
|
|
e89a5c |
/* tmsize_t bytecountm; */
|
|
|
e89a5c |
|
|
|
e89a5c |
if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
|
|
|
e89a5c |
@@ -62,7 +180,14 @@ TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart )
|
|
|
e89a5c |
*/
|
|
|
e89a5c |
|
|
|
e89a5c |
/* bytecountm=(tmsize_t) td->td_stripbytecount[strip]; */
|
|
|
e89a5c |
- if (read_ahead*2 > tif->tif_rawdatasize) {
|
|
|
e89a5c |
+
|
|
|
e89a5c |
+ /* Not completely sure where the * 2 comes from, but probably for */
|
|
|
e89a5c |
+ /* an exponentional growth strategy of tif_rawdatasize */
|
|
|
e89a5c |
+ if( read_ahead < TIFF_TMSIZE_T_MAX / 2 )
|
|
|
e89a5c |
+ read_ahead_mod = read_ahead * 2;
|
|
|
e89a5c |
+ else
|
|
|
e89a5c |
+ read_ahead_mod = read_ahead;
|
|
|
e89a5c |
+ if (read_ahead_mod > tif->tif_rawdatasize) {
|
|
|
e89a5c |
assert( restart );
|
|
|
e89a5c |
|
|
|
e89a5c |
tif->tif_curstrip = NOSTRIP;
|
|
|
e89a5c |
@@ -72,8 +197,6 @@ TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart )
|
|
|
e89a5c |
(unsigned long) strip);
|
|
|
e89a5c |
return (0);
|
|
|
e89a5c |
}
|
|
|
e89a5c |
- if (!TIFFReadBufferSetup(tif, 0, read_ahead*2))
|
|
|
e89a5c |
- return (0);
|
|
|
e89a5c |
}
|
|
|
e89a5c |
|
|
|
e89a5c |
if( restart )
|
|
|
e89a5c |
@@ -113,34 +236,26 @@ TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart )
|
|
|
e89a5c |
/*
|
|
|
e89a5c |
** How much do we want to read?
|
|
|
e89a5c |
*/
|
|
|
e89a5c |
- to_read = tif->tif_rawdatasize - unused_data;
|
|
|
e89a5c |
+ if( read_ahead_mod > tif->tif_rawdatasize )
|
|
|
e89a5c |
+ to_read = read_ahead_mod - unused_data;
|
|
|
e89a5c |
+ else
|
|
|
e89a5c |
+ to_read = tif->tif_rawdatasize - unused_data;
|
|
|
e89a5c |
if( (uint64) to_read > td->td_stripbytecount[strip]
|
|
|
e89a5c |
- tif->tif_rawdataoff - tif->tif_rawdataloaded )
|
|
|
e89a5c |
{
|
|
|
e89a5c |
- to_read = td->td_stripbytecount[strip]
|
|
|
e89a5c |
+ to_read = (tmsize_t) td->td_stripbytecount[strip]
|
|
|
e89a5c |
- tif->tif_rawdataoff - tif->tif_rawdataloaded;
|
|
|
e89a5c |
}
|
|
|
e89a5c |
|
|
|
e89a5c |
assert((tif->tif_flags&TIFF_BUFFERMMAP)==0);
|
|
|
e89a5c |
- cc = TIFFReadFile(tif, tif->tif_rawdata + unused_data, to_read);
|
|
|
e89a5c |
-
|
|
|
e89a5c |
- if (cc != to_read) {
|
|
|
e89a5c |
-#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
|
|
|
e89a5c |
- TIFFErrorExt(tif->tif_clientdata, module,
|
|
|
e89a5c |
- "Read error at scanline %lu; got %I64u bytes, expected %I64u",
|
|
|
e89a5c |
- (unsigned long) tif->tif_row,
|
|
|
e89a5c |
- (unsigned __int64) cc,
|
|
|
e89a5c |
- (unsigned __int64) to_read);
|
|
|
e89a5c |
-#else
|
|
|
e89a5c |
- TIFFErrorExt(tif->tif_clientdata, module,
|
|
|
e89a5c |
- "Read error at scanline %lu; got %llu bytes, expected %llu",
|
|
|
e89a5c |
- (unsigned long) tif->tif_row,
|
|
|
e89a5c |
- (unsigned long long) cc,
|
|
|
e89a5c |
- (unsigned long long) to_read);
|
|
|
e89a5c |
-#endif
|
|
|
e89a5c |
+ if( !TIFFReadAndRealloc( tif, to_read, unused_data,
|
|
|
e89a5c |
+ 1, /* is_strip */
|
|
|
e89a5c |
+ 0, /* strip_or_tile */
|
|
|
e89a5c |
+ module) )
|
|
|
e89a5c |
+ {
|
|
|
e89a5c |
return 0;
|
|
|
e89a5c |
}
|
|
|
e89a5c |
-
|
|
|
e89a5c |
+
|
|
|
e89a5c |
tif->tif_rawdataoff = tif->tif_rawdataoff + tif->tif_rawdataloaded - unused_data ;
|
|
|
e89a5c |
tif->tif_rawdataloaded = unused_data + to_read;
|
|
|
e89a5c |
|
|
|
e89a5c |
@@ -214,7 +329,18 @@ TIFFSeek(TIFF* tif, uint32 row, uint16 sample )
|
|
|
e89a5c |
|
|
|
e89a5c |
if( !whole_strip )
|
|
|
e89a5c |
{
|
|
|
e89a5c |
- read_ahead = tif->tif_scanlinesize * 16 + 5000;
|
|
|
e89a5c |
+ /* 16 is for YCbCr mode where we may need to read 16 */
|
|
|
e89a5c |
+ /* lines at a time to get a decompressed line, and 5000 */
|
|
|
e89a5c |
+ /* is some constant value, for example for JPEG tables */
|
|
|
e89a5c |
+ if( tif->tif_scanlinesize < TIFF_TMSIZE_T_MAX / 16 &&
|
|
|
e89a5c |
+ tif->tif_scanlinesize * 16 < TIFF_TMSIZE_T_MAX - 5000 )
|
|
|
e89a5c |
+ {
|
|
|
e89a5c |
+ read_ahead = tif->tif_scanlinesize * 16 + 5000;
|
|
|
e89a5c |
+ }
|
|
|
e89a5c |
+ else
|
|
|
e89a5c |
+ {
|
|
|
e89a5c |
+ read_ahead = tif->tif_scanlinesize;
|
|
|
e89a5c |
+ }
|
|
|
e89a5c |
}
|
|
|
e89a5c |
|
|
|
e89a5c |
/*
|
|
|
e89a5c |
@@ -401,7 +527,7 @@ TIFFReadRawStrip1(TIFF* tif, uint32 strip, void* buf, tmsize_t size,
|
|
|
e89a5c |
tmsize_t n;
|
|
|
e89a5c |
ma=(tmsize_t)td->td_stripoffset[strip];
|
|
|
e89a5c |
mb=ma+size;
|
|
|
e89a5c |
- if (((uint64)ma!=td->td_stripoffset[strip])||(ma>tif->tif_size))
|
|
|
e89a5c |
+ if ((td->td_stripoffset[strip] > (uint64)TIFF_TMSIZE_T_MAX)||(ma>tif->tif_size))
|
|
|
e89a5c |
n=0;
|
|
|
e89a5c |
else if ((mb<ma)||(mb<size)||(mb>tif->tif_size))
|
|
|
e89a5c |
n=tif->tif_size-ma;
|
|
|
e89a5c |
@@ -431,6 +557,43 @@ TIFFReadRawStrip1(TIFF* tif, uint32 strip, void* buf, tmsize_t size,
|
|
|
e89a5c |
return (size);
|
|
|
e89a5c |
}
|
|
|
e89a5c |
|
|
|
e89a5c |
+static tmsize_t
|
|
|
e89a5c |
+TIFFReadRawStripOrTile2(TIFF* tif, uint32 strip_or_tile, int is_strip,
|
|
|
e89a5c |
+ tmsize_t size, const char* module)
|
|
|
e89a5c |
+{
|
|
|
e89a5c |
+ TIFFDirectory *td = &tif->tif_dir;
|
|
|
e89a5c |
+
|
|
|
e89a5c |
+ assert( !isMapped(tif) );
|
|
|
e89a5c |
+ assert((tif->tif_flags&TIFF_NOREADRAW)==0);
|
|
|
e89a5c |
+
|
|
|
e89a5c |
+ if (!SeekOK(tif, td->td_stripoffset[strip_or_tile])) {
|
|
|
e89a5c |
+ if( is_strip )
|
|
|
e89a5c |
+ {
|
|
|
e89a5c |
+ TIFFErrorExt(tif->tif_clientdata, module,
|
|
|
e89a5c |
+ "Seek error at scanline %lu, strip %lu",
|
|
|
e89a5c |
+ (unsigned long) tif->tif_row,
|
|
|
e89a5c |
+ (unsigned long) strip_or_tile);
|
|
|
e89a5c |
+ }
|
|
|
e89a5c |
+ else
|
|
|
e89a5c |
+ {
|
|
|
e89a5c |
+ TIFFErrorExt(tif->tif_clientdata, module,
|
|
|
e89a5c |
+ "Seek error at row %lu, col %lu, tile %lu",
|
|
|
e89a5c |
+ (unsigned long) tif->tif_row,
|
|
|
e89a5c |
+ (unsigned long) tif->tif_col,
|
|
|
e89a5c |
+ (unsigned long) strip_or_tile);
|
|
|
e89a5c |
+ }
|
|
|
e89a5c |
+ return ((tmsize_t)(-1));
|
|
|
e89a5c |
+ }
|
|
|
e89a5c |
+
|
|
|
e89a5c |
+ if( !TIFFReadAndRealloc( tif, size, 0, is_strip,
|
|
|
e89a5c |
+ strip_or_tile, module ) )
|
|
|
e89a5c |
+ {
|
|
|
e89a5c |
+ return ((tmsize_t)(-1));
|
|
|
e89a5c |
+ }
|
|
|
e89a5c |
+
|
|
|
e89a5c |
+ return (size);
|
|
|
e89a5c |
+}
|
|
|
e89a5c |
+
|
|
|
e89a5c |
/*
|
|
|
e89a5c |
* Read a strip of data from the file.
|
|
|
e89a5c |
*/
|
|
|
e89a5c |
@@ -458,23 +621,8 @@ TIFFReadRawStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size)
|
|
|
e89a5c |
return ((tmsize_t)(-1));
|
|
|
e89a5c |
}
|
|
|
e89a5c |
bytecount = td->td_stripbytecount[strip];
|
|
|
e89a5c |
- if ((int64)bytecount <= 0) {
|
|
|
e89a5c |
-#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
|
|
|
e89a5c |
- TIFFErrorExt(tif->tif_clientdata, module,
|
|
|
e89a5c |
- "%I64u: Invalid strip byte count, strip %lu",
|
|
|
e89a5c |
- (unsigned __int64) bytecount,
|
|
|
e89a5c |
- (unsigned long) strip);
|
|
|
e89a5c |
-#else
|
|
|
e89a5c |
- TIFFErrorExt(tif->tif_clientdata, module,
|
|
|
e89a5c |
- "%llu: Invalid strip byte count, strip %lu",
|
|
|
e89a5c |
- (unsigned long long) bytecount,
|
|
|
e89a5c |
- (unsigned long) strip);
|
|
|
e89a5c |
-#endif
|
|
|
e89a5c |
- return ((tmsize_t)(-1));
|
|
|
e89a5c |
- }
|
|
|
e89a5c |
- bytecountm = (tmsize_t)bytecount;
|
|
|
e89a5c |
- if ((uint64)bytecountm!=bytecount) {
|
|
|
e89a5c |
- TIFFErrorExt(tif->tif_clientdata, module, "Integer overflow");
|
|
|
e89a5c |
+ bytecountm = _TIFFCastUInt64ToSSize(tif, bytecount, module);
|
|
|
e89a5c |
+ if (bytecountm == 0) {
|
|
|
e89a5c |
return ((tmsize_t)(-1));
|
|
|
e89a5c |
}
|
|
|
e89a5c |
if (size != (tmsize_t)(-1) && size < bytecountm)
|
|
|
e89a5c |
@@ -498,7 +646,7 @@ TIFFFillStrip(TIFF* tif, uint32 strip)
|
|
|
e89a5c |
if ((tif->tif_flags&TIFF_NOREADRAW)==0)
|
|
|
e89a5c |
{
|
|
|
e89a5c |
uint64 bytecount = td->td_stripbytecount[strip];
|
|
|
e89a5c |
- if ((int64)bytecount <= 0) {
|
|
|
e89a5c |
+ if( bytecount == 0 || bytecount > (uint64)TIFF_INT64_MAX ) {
|
|
|
e89a5c |
#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
|
|
|
e89a5c |
TIFFErrorExt(tif->tif_clientdata, module,
|
|
|
e89a5c |
"Invalid strip byte count %I64u, strip %lu",
|
|
|
e89a5c |
@@ -512,6 +660,39 @@ TIFFFillStrip(TIFF* tif, uint32 strip)
|
|
|
e89a5c |
#endif
|
|
|
e89a5c |
return (0);
|
|
|
e89a5c |
}
|
|
|
e89a5c |
+
|
|
|
e89a5c |
+ /* To avoid excessive memory allocations: */
|
|
|
e89a5c |
+ /* Byte count should normally not be larger than a number of */
|
|
|
e89a5c |
+ /* times the uncompressed size plus some margin */
|
|
|
e89a5c |
+ if( bytecount > 1024 * 1024 )
|
|
|
e89a5c |
+ {
|
|
|
e89a5c |
+ /* 10 and 4096 are just values that could be adjusted. */
|
|
|
e89a5c |
+ /* Hopefully they are safe enough for all codecs */
|
|
|
e89a5c |
+ tmsize_t stripsize = TIFFStripSize(tif);
|
|
|
e89a5c |
+ if( stripsize != 0 &&
|
|
|
e89a5c |
+ (bytecount - 4096) / 10 > (uint64)stripsize )
|
|
|
e89a5c |
+ {
|
|
|
e89a5c |
+ uint64 newbytecount = (uint64)stripsize * 10 + 4096;
|
|
|
e89a5c |
+ if( newbytecount == 0 || newbytecount > (uint64)TIFF_INT64_MAX )
|
|
|
e89a5c |
+ {
|
|
|
e89a5c |
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
|
|
|
e89a5c |
+ TIFFWarningExt(tif->tif_clientdata, module,
|
|
|
e89a5c |
+ "Too large strip byte count %I64u, strip %lu. Limiting to %I64u",
|
|
|
e89a5c |
+ (unsigned __int64) bytecount,
|
|
|
e89a5c |
+ (unsigned long) strip,
|
|
|
e89a5c |
+ (unsigned __int64) newbytecount);
|
|
|
e89a5c |
+#else
|
|
|
e89a5c |
+ TIFFErrorExt(tif->tif_clientdata, module,
|
|
|
e89a5c |
+ "Too large strip byte count %llu, strip %lu. Limiting to %llu",
|
|
|
e89a5c |
+ (unsigned long long) bytecount,
|
|
|
e89a5c |
+ (unsigned long) strip,
|
|
|
e89a5c |
+ (unsigned long long) newbytecount);
|
|
|
e89a5c |
+#endif
|
|
|
e89a5c |
+ bytecount = newbytecount;
|
|
|
e89a5c |
+ }
|
|
|
e89a5c |
+ }
|
|
|
e89a5c |
+ }
|
|
|
e89a5c |
+
|
|
|
e89a5c |
if (isMapped(tif) &&
|
|
|
e89a5c |
(isFillOrder(tif, td->td_fillorder)
|
|
|
e89a5c |
|| (tif->tif_flags & TIFF_NOBITREV))) {
|
|
|
e89a5c |
@@ -601,17 +782,36 @@ TIFFFillStrip(TIFF* tif, uint32 strip)
|
|
|
e89a5c |
(unsigned long) strip);
|
|
|
e89a5c |
return (0);
|
|
|
e89a5c |
}
|
|
|
e89a5c |
- if (!TIFFReadBufferSetup(tif, 0, bytecountm))
|
|
|
e89a5c |
- return (0);
|
|
|
e89a5c |
}
|
|
|
e89a5c |
if (tif->tif_flags&TIFF_BUFFERMMAP) {
|
|
|
e89a5c |
tif->tif_curstrip = NOSTRIP;
|
|
|
e89a5c |
- if (!TIFFReadBufferSetup(tif, 0, bytecountm))
|
|
|
e89a5c |
+ tif->tif_rawdata = NULL;
|
|
|
e89a5c |
+ tif->tif_rawdatasize = 0;
|
|
|
e89a5c |
+ tif->tif_flags &= ~TIFF_BUFFERMMAP;
|
|
|
e89a5c |
+ }
|
|
|
e89a5c |
+
|
|
|
e89a5c |
+ if( isMapped(tif) )
|
|
|
e89a5c |
+ {
|
|
|
e89a5c |
+ if (bytecountm > tif->tif_rawdatasize &&
|
|
|
e89a5c |
+ !TIFFReadBufferSetup(tif, 0, bytecountm))
|
|
|
e89a5c |
+ {
|
|
|
e89a5c |
+ return (0);
|
|
|
e89a5c |
+ }
|
|
|
e89a5c |
+ if (TIFFReadRawStrip1(tif, strip, tif->tif_rawdata,
|
|
|
e89a5c |
+ bytecountm, module) != bytecountm)
|
|
|
e89a5c |
+ {
|
|
|
e89a5c |
return (0);
|
|
|
e89a5c |
+ }
|
|
|
e89a5c |
+ }
|
|
|
e89a5c |
+ else
|
|
|
e89a5c |
+ {
|
|
|
e89a5c |
+ if (TIFFReadRawStripOrTile2(tif, strip, 1,
|
|
|
e89a5c |
+ bytecountm, module) != bytecountm)
|
|
|
e89a5c |
+ {
|
|
|
e89a5c |
+ return (0);
|
|
|
e89a5c |
+ }
|
|
|
e89a5c |
}
|
|
|
e89a5c |
- if (TIFFReadRawStrip1(tif, strip, tif->tif_rawdata,
|
|
|
e89a5c |
- bytecountm, module) != bytecountm)
|
|
|
e89a5c |
- return (0);
|
|
|
e89a5c |
+
|
|
|
e89a5c |
|
|
|
e89a5c |
tif->tif_rawdataoff = 0;
|
|
|
e89a5c |
tif->tif_rawdataloaded = bytecountm;
|
|
|
e89a5c |
@@ -717,7 +917,7 @@ TIFFReadRawTile1(TIFF* tif, uint32 tile, void* buf, tmsize_t size, const char* m
|
|
|
e89a5c |
tmsize_t n;
|
|
|
e89a5c |
ma=(tmsize_t)td->td_stripoffset[tile];
|
|
|
e89a5c |
mb=ma+size;
|
|
|
e89a5c |
- if (((uint64)ma!=td->td_stripoffset[tile])||(ma>tif->tif_size))
|
|
|
e89a5c |
+ if ((td->td_stripoffset[tile] > (uint64)TIFF_TMSIZE_T_MAX)||(ma>tif->tif_size))
|
|
|
e89a5c |
n=0;
|
|
|
e89a5c |
else if ((mb<ma)||(mb<size)||(mb>tif->tif_size))
|
|
|
e89a5c |
n=tif->tif_size-ma;
|
|
|
e89a5c |
@@ -776,10 +976,8 @@ TIFFReadRawTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size)
|
|
|
e89a5c |
bytecount64 = td->td_stripbytecount[tile];
|
|
|
e89a5c |
if (size != (tmsize_t)(-1) && (uint64)size < bytecount64)
|
|
|
e89a5c |
bytecount64 = (uint64)size;
|
|
|
e89a5c |
- bytecountm = (tmsize_t)bytecount64;
|
|
|
e89a5c |
- if ((uint64)bytecountm!=bytecount64)
|
|
|
e89a5c |
- {
|
|
|
e89a5c |
- TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
|
|
|
e89a5c |
+ bytecountm = _TIFFCastUInt64ToSSize(tif, bytecount64, module);
|
|
|
e89a5c |
+ if( bytecountm == 0 ) {
|
|
|
e89a5c |
return ((tmsize_t)(-1));
|
|
|
e89a5c |
}
|
|
|
e89a5c |
return (TIFFReadRawTile1(tif, tile, buf, bytecountm, module));
|
|
|
e89a5c |
@@ -801,7 +999,7 @@ TIFFFillTile(TIFF* tif, uint32 tile)
|
|
|
e89a5c |
if ((tif->tif_flags&TIFF_NOREADRAW)==0)
|
|
|
e89a5c |
{
|
|
|
e89a5c |
uint64 bytecount = td->td_stripbytecount[tile];
|
|
|
e89a5c |
- if ((int64)bytecount <= 0) {
|
|
|
e89a5c |
+ if( bytecount == 0 || bytecount > (uint64)TIFF_INT64_MAX ) {
|
|
|
e89a5c |
#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
|
|
|
e89a5c |
TIFFErrorExt(tif->tif_clientdata, module,
|
|
|
e89a5c |
"%I64u: Invalid tile byte count, tile %lu",
|
|
|
e89a5c |
@@ -815,6 +1013,39 @@ TIFFFillTile(TIFF* tif, uint32 tile)
|
|
|
e89a5c |
#endif
|
|
|
e89a5c |
return (0);
|
|
|
e89a5c |
}
|
|
|
e89a5c |
+
|
|
|
e89a5c |
+ /* To avoid excessive memory allocations: */
|
|
|
e89a5c |
+ /* Byte count should normally not be larger than a number of */
|
|
|
e89a5c |
+ /* times the uncompressed size plus some margin */
|
|
|
e89a5c |
+ if( bytecount > 1024 * 1024 )
|
|
|
e89a5c |
+ {
|
|
|
e89a5c |
+ /* 10 and 4096 are just values that could be adjusted. */
|
|
|
e89a5c |
+ /* Hopefully they are safe enough for all codecs */
|
|
|
e89a5c |
+ tmsize_t stripsize = TIFFTileSize(tif);
|
|
|
e89a5c |
+ if( stripsize != 0 &&
|
|
|
e89a5c |
+ (bytecount - 4096) / 10 > (uint64)stripsize )
|
|
|
e89a5c |
+ {
|
|
|
e89a5c |
+ uint64 newbytecount = (uint64)stripsize * 10 + 4096;
|
|
|
e89a5c |
+ if( newbytecount == 0 || newbytecount > (uint64)TIFF_INT64_MAX )
|
|
|
e89a5c |
+ {
|
|
|
e89a5c |
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
|
|
|
e89a5c |
+ TIFFWarningExt(tif->tif_clientdata, module,
|
|
|
e89a5c |
+ "Too large tile byte count %I64u, tile %lu. Limiting to %I64u",
|
|
|
e89a5c |
+ (unsigned __int64) bytecount,
|
|
|
e89a5c |
+ (unsigned long) tile,
|
|
|
e89a5c |
+ (unsigned __int64) newbytecount);
|
|
|
e89a5c |
+#else
|
|
|
e89a5c |
+ TIFFErrorExt(tif->tif_clientdata, module,
|
|
|
e89a5c |
+ "Too large tile byte count %llu, tile %lu. Limiting to %llu",
|
|
|
e89a5c |
+ (unsigned long long) bytecount,
|
|
|
e89a5c |
+ (unsigned long) tile,
|
|
|
e89a5c |
+ (unsigned long long) newbytecount);
|
|
|
e89a5c |
+#endif
|
|
|
e89a5c |
+ bytecount = newbytecount;
|
|
|
e89a5c |
+ }
|
|
|
e89a5c |
+ }
|
|
|
e89a5c |
+ }
|
|
|
e89a5c |
+
|
|
|
e89a5c |
if (isMapped(tif) &&
|
|
|
e89a5c |
(isFillOrder(tif, td->td_fillorder)
|
|
|
e89a5c |
|| (tif->tif_flags & TIFF_NOBITREV))) {
|
|
|
e89a5c |
@@ -876,18 +1107,36 @@ TIFFFillTile(TIFF* tif, uint32 tile)
|
|
|
e89a5c |
(unsigned long) tile);
|
|
|
e89a5c |
return (0);
|
|
|
e89a5c |
}
|
|
|
e89a5c |
- if (!TIFFReadBufferSetup(tif, 0, bytecountm))
|
|
|
e89a5c |
- return (0);
|
|
|
e89a5c |
}
|
|
|
e89a5c |
if (tif->tif_flags&TIFF_BUFFERMMAP) {
|
|
|
e89a5c |
tif->tif_curtile = NOTILE;
|
|
|
e89a5c |
- if (!TIFFReadBufferSetup(tif, 0, bytecountm))
|
|
|
e89a5c |
+ tif->tif_rawdata = NULL;
|
|
|
e89a5c |
+ tif->tif_rawdatasize = 0;
|
|
|
e89a5c |
+ tif->tif_flags &= ~TIFF_BUFFERMMAP;
|
|
|
e89a5c |
+ }
|
|
|
e89a5c |
+
|
|
|
e89a5c |
+ if( isMapped(tif) )
|
|
|
e89a5c |
+ {
|
|
|
e89a5c |
+ if (bytecountm > tif->tif_rawdatasize &&
|
|
|
e89a5c |
+ !TIFFReadBufferSetup(tif, 0, bytecountm))
|
|
|
e89a5c |
+ {
|
|
|
e89a5c |
+ return (0);
|
|
|
e89a5c |
+ }
|
|
|
e89a5c |
+ if (TIFFReadRawTile1(tif, tile, tif->tif_rawdata,
|
|
|
e89a5c |
+ bytecountm, module) != bytecountm)
|
|
|
e89a5c |
+ {
|
|
|
e89a5c |
return (0);
|
|
|
e89a5c |
+ }
|
|
|
e89a5c |
+ }
|
|
|
e89a5c |
+ else
|
|
|
e89a5c |
+ {
|
|
|
e89a5c |
+ if (TIFFReadRawStripOrTile2(tif, tile, 0,
|
|
|
e89a5c |
+ bytecountm, module) != bytecountm)
|
|
|
e89a5c |
+ {
|
|
|
e89a5c |
+ return (0);
|
|
|
e89a5c |
+ }
|
|
|
e89a5c |
}
|
|
|
e89a5c |
|
|
|
e89a5c |
- if (TIFFReadRawTile1(tif, tile, tif->tif_rawdata,
|
|
|
e89a5c |
- bytecountm, module) != bytecountm)
|
|
|
e89a5c |
- return (0);
|
|
|
e89a5c |
|
|
|
e89a5c |
tif->tif_rawdataoff = 0;
|
|
|
e89a5c |
tif->tif_rawdataloaded = bytecountm;
|
|
|
e89a5c |
diff --git a/libtiff/tif_strip.c b/libtiff/tif_strip.c
|
|
|
e89a5c |
index 568e489..206eeb8 100644
|
|
|
e89a5c |
--- a/libtiff/tif_strip.c
|
|
|
e89a5c |
+++ b/libtiff/tif_strip.c
|
|
|
e89a5c |
@@ -131,15 +131,8 @@ TIFFVStripSize(TIFF* tif, uint32 nrows)
|
|
|
e89a5c |
{
|
|
|
e89a5c |
static const char module[] = "TIFFVStripSize";
|
|
|
e89a5c |
uint64 m;
|
|
|
e89a5c |
- tmsize_t n;
|
|
|
e89a5c |
m=TIFFVStripSize64(tif,nrows);
|
|
|
e89a5c |
- n=(tmsize_t)m;
|
|
|
e89a5c |
- if ((uint64)n!=m)
|
|
|
e89a5c |
- {
|
|
|
e89a5c |
- TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
|
|
|
e89a5c |
- n=0;
|
|
|
e89a5c |
- }
|
|
|
e89a5c |
- return(n);
|
|
|
e89a5c |
+ return _TIFFCastUInt64ToSSize(tif, m, module);
|
|
|
e89a5c |
}
|
|
|
e89a5c |
|
|
|
e89a5c |
/*
|
|
|
e89a5c |
@@ -213,15 +206,8 @@ TIFFStripSize(TIFF* tif)
|
|
|
e89a5c |
{
|
|
|
e89a5c |
static const char module[] = "TIFFStripSize";
|
|
|
e89a5c |
uint64 m;
|
|
|
e89a5c |
- tmsize_t n;
|
|
|
e89a5c |
m=TIFFStripSize64(tif);
|
|
|
e89a5c |
- n=(tmsize_t)m;
|
|
|
e89a5c |
- if ((uint64)n!=m)
|
|
|
e89a5c |
- {
|
|
|
e89a5c |
- TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
|
|
|
e89a5c |
- n=0;
|
|
|
e89a5c |
- }
|
|
|
e89a5c |
- return(n);
|
|
|
e89a5c |
+ return _TIFFCastUInt64ToSSize(tif, m, module);
|
|
|
e89a5c |
}
|
|
|
e89a5c |
|
|
|
e89a5c |
/*
|
|
|
e89a5c |
@@ -362,15 +348,8 @@ TIFFRasterScanlineSize(TIFF* tif)
|
|
|
e89a5c |
{
|
|
|
e89a5c |
static const char module[] = "TIFFRasterScanlineSize";
|
|
|
e89a5c |
uint64 m;
|
|
|
e89a5c |
- tmsize_t n;
|
|
|
e89a5c |
m=TIFFRasterScanlineSize64(tif);
|
|
|
e89a5c |
- n=(tmsize_t)m;
|
|
|
e89a5c |
- if ((uint64)n!=m)
|
|
|
e89a5c |
- {
|
|
|
e89a5c |
- TIFFErrorExt(tif->tif_clientdata,module,"Integer arithmetic overflow");
|
|
|
e89a5c |
- n=0;
|
|
|
e89a5c |
- }
|
|
|
e89a5c |
- return(n);
|
|
|
e89a5c |
+ return _TIFFCastUInt64ToSSize(tif, m, module);
|
|
|
e89a5c |
}
|
|
|
e89a5c |
|
|
|
e89a5c |
/* vim: set ts=8 sts=8 sw=8 noet: */
|
|
|
e89a5c |
diff --git a/libtiff/tif_tile.c b/libtiff/tif_tile.c
|
|
|
e89a5c |
index 0ff7e85..57a063b 100644
|
|
|
e89a5c |
--- a/libtiff/tif_tile.c
|
|
|
e89a5c |
+++ b/libtiff/tif_tile.c
|
|
|
e89a5c |
@@ -160,15 +160,8 @@ TIFFTileRowSize(TIFF* tif)
|
|
|
e89a5c |
{
|
|
|
e89a5c |
static const char module[] = "TIFFTileRowSize";
|
|
|
e89a5c |
uint64 m;
|
|
|
e89a5c |
- tmsize_t n;
|
|
|
e89a5c |
m=TIFFTileRowSize64(tif);
|
|
|
e89a5c |
- n=(tmsize_t)m;
|
|
|
e89a5c |
- if ((uint64)n!=m)
|
|
|
e89a5c |
- {
|
|
|
e89a5c |
- TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
|
|
|
e89a5c |
- n=0;
|
|
|
e89a5c |
- }
|
|
|
e89a5c |
- return(n);
|
|
|
e89a5c |
+ return _TIFFCastUInt64ToSSize(tif, m, module);
|
|
|
e89a5c |
}
|
|
|
e89a5c |
|
|
|
e89a5c |
/*
|
|
|
e89a5c |
@@ -227,15 +220,8 @@ TIFFVTileSize(TIFF* tif, uint32 nrows)
|
|
|
e89a5c |
{
|
|
|
e89a5c |
static const char module[] = "TIFFVTileSize";
|
|
|
e89a5c |
uint64 m;
|
|
|
e89a5c |
- tmsize_t n;
|
|
|
e89a5c |
m=TIFFVTileSize64(tif,nrows);
|
|
|
e89a5c |
- n=(tmsize_t)m;
|
|
|
e89a5c |
- if ((uint64)n!=m)
|
|
|
e89a5c |
- {
|
|
|
e89a5c |
- TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
|
|
|
e89a5c |
- n=0;
|
|
|
e89a5c |
- }
|
|
|
e89a5c |
- return(n);
|
|
|
e89a5c |
+ return _TIFFCastUInt64ToSSize(tif, m, module);
|
|
|
e89a5c |
}
|
|
|
e89a5c |
|
|
|
e89a5c |
/*
|
|
|
e89a5c |
@@ -251,15 +237,8 @@ TIFFTileSize(TIFF* tif)
|
|
|
e89a5c |
{
|
|
|
e89a5c |
static const char module[] = "TIFFTileSize";
|
|
|
e89a5c |
uint64 m;
|
|
|
e89a5c |
- tmsize_t n;
|
|
|
e89a5c |
m=TIFFTileSize64(tif);
|
|
|
e89a5c |
- n=(tmsize_t)m;
|
|
|
e89a5c |
- if ((uint64)n!=m)
|
|
|
e89a5c |
- {
|
|
|
e89a5c |
- TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
|
|
|
e89a5c |
- n=0;
|
|
|
e89a5c |
- }
|
|
|
e89a5c |
- return(n);
|
|
|
e89a5c |
+ return _TIFFCastUInt64ToSSize(tif, m, module);
|
|
|
e89a5c |
}
|
|
|
e89a5c |
|
|
|
e89a5c |
/*
|
|
|
e89a5c |
diff --git a/libtiff/tiffiop.h b/libtiff/tiffiop.h
|
|
|
e89a5c |
index 8d1357b..d0987e2 100644
|
|
|
e89a5c |
--- a/libtiff/tiffiop.h
|
|
|
e89a5c |
+++ b/libtiff/tiffiop.h
|
|
|
e89a5c |
@@ -73,6 +73,9 @@ extern void *lfind(const void *, const void *, size_t *, size_t,
|
|
|
e89a5c |
#define FALSE 0
|
|
|
e89a5c |
#endif
|
|
|
e89a5c |
|
|
|
e89a5c |
+#define TIFF_SIZE_T_MAX ((size_t) ~ ((size_t)0))
|
|
|
e89a5c |
+#define TIFF_TMSIZE_T_MAX (tmsize_t)(TIFF_SIZE_T_MAX >> 1)
|
|
|
e89a5c |
+
|
|
|
e89a5c |
typedef struct client_info {
|
|
|
e89a5c |
struct client_info *next;
|
|
|
e89a5c |
void *data;
|
|
|
e89a5c |
@@ -251,7 +254,7 @@ struct tiff {
|
|
|
e89a5c |
#define TIFFhowmany8_64(x) (((x)&0x07)?((uint64)(x)>>3)+1:(uint64)(x)>>3)
|
|
|
e89a5c |
#define TIFFroundup_64(x, y) (TIFFhowmany_64(x,y)*(y))
|
|
|
e89a5c |
|
|
|
e89a5c |
-/* Safe multiply which returns zero if there is an integer overflow */
|
|
|
e89a5c |
+/* Safe multiply which returns zero if there is an *unsigned* integer overflow. This macro is not safe for *signed* integer types */
|
|
|
e89a5c |
#define TIFFSafeMultiply(t,v,m) ((((t)(m) != (t)0) && (((t)(((v)*(m))/(m))) == (t)(v))) ? (t)((v)*(m)) : (t)0)
|
|
|
e89a5c |
|
|
|
e89a5c |
#define TIFFmax(A,B) ((A)>(B)?(A):(B))
|
|
|
e89a5c |
@@ -303,6 +306,8 @@ extern TIFFErrorHandlerExt _TIFFerrorHandlerExt;
|
|
|
e89a5c |
|
|
|
e89a5c |
extern uint32 _TIFFMultiply32(TIFF*, uint32, uint32, const char*);
|
|
|
e89a5c |
extern uint64 _TIFFMultiply64(TIFF*, uint64, uint64, const char*);
|
|
|
e89a5c |
+extern tmsize_t _TIFFMultiplySSize(TIFF*, tmsize_t, tmsize_t, const char*);
|
|
|
e89a5c |
+extern tmsize_t _TIFFCastUInt64ToSSize(TIFF*, uint64, const char*);
|
|
|
e89a5c |
extern void* _TIFFCheckMalloc(TIFF*, tmsize_t, tmsize_t, const char*);
|
|
|
e89a5c |
extern void* _TIFFCheckRealloc(TIFF*, void*, tmsize_t, tmsize_t, const char*);
|
|
|
e89a5c |
|
|
|
e89a5c |
--
|
|
|
e89a5c |
2.21.1
|
|
|
e89a5c |
|