From ea593c11a76b47ae6020c9849314e93761c18211 Mon Sep 17 00:00:00 2001
From: Andrey Kiselev <[EMAIL REDACTED]>
Date: Sat, 7 Apr 2007 14:58:30 +0000
Subject: [PATCH] Finally fix bug
http://bugzilla.remotesensing.org/show_bug.cgi?id=1274 by introducing
_TIFFMergeFieldInfo() returning integer error status instead of void in case
of problems with field merging (e.g., if the field with such a tag already
registered). TIFFMergeFieldInfo() in public API remains void. Use
_TIFFMergeFieldInfo() everywhere and check returned value.
---
libtiff/tif_dir.h | 10 +-
libtiff/tif_dirinfo.c | 171 +++---
libtiff/tif_dirread.c | 1230 +++++++++++++++-------------------------
libtiff/tif_fax3.c | 35 +-
libtiff/tif_jbig.c | 19 +-
libtiff/tif_jpeg.c | 20 +-
libtiff/tif_luv.c | 18 +-
libtiff/tif_ojpeg.c | 14 +-
libtiff/tif_pixarlog.c | 18 +-
libtiff/tif_predict.c | 17 +-
libtiff/tif_zip.c | 19 +-
11 files changed, 676 insertions(+), 895 deletions(-)
diff --git a/libtiff/tif_dir.h b/libtiff/tif_dir.h
index eaf7855a..87959e31 100644
--- a/libtiff/tif_dir.h
+++ b/libtiff/tif_dir.h
@@ -1,4 +1,4 @@
-/* $Id: tif_dir.h,v 1.31 2007-03-17 04:41:29 joris Exp $ */
+/* $Id: tif_dir.h,v 1.30.2.1 2007-04-07 14:58:30 dron Exp $ */
/*
* Copyright (c) 1988-1997 Sam Leffler
@@ -156,11 +156,11 @@ typedef struct {
#define FIELD_LAST (32*FIELD_SETLONGS-1)
#define TIFFExtractData(tif, type, v) \
- ((uint32) ((tif)->tif_header.common.tiff_magic == TIFF_BIGENDIAN ? \
- ((v) >> (tif)->tif_typeshift[type]) & (tif)->tif_typemask[type] : \
+ ((uint32) ((tif)->tif_header.tiff_magic == TIFF_BIGENDIAN ? \
+ ((v) >> (tif)->tif_typeshift[type]) & (tif)->tif_typemask[type] : \
(v) & (tif)->tif_typemask[type]))
#define TIFFInsertData(tif, type, v) \
- ((uint32) ((tif)->tif_header.common.tiff_magic == TIFF_BIGENDIAN ? \
+ ((uint32) ((tif)->tif_header.tiff_magic == TIFF_BIGENDIAN ? \
((v) & (tif)->tif_typemask[type]) << (tif)->tif_typeshift[type] : \
(v) & (tif)->tif_typemask[type]))
@@ -180,6 +180,7 @@ extern "C" {
extern const TIFFFieldInfo *_TIFFGetFieldInfo(size_t *);
extern const TIFFFieldInfo *_TIFFGetExifFieldInfo(size_t *);
extern void _TIFFSetupFieldInfo(TIFF*, const TIFFFieldInfo[], size_t);
+extern int _TIFFMergeFieldInfo(TIFF*, const TIFFFieldInfo[], int);
extern void _TIFFPrintFieldInfo(TIFF*, FILE*);
extern TIFFDataType _TIFFSampleToTagType(TIFF*);
extern const TIFFFieldInfo* _TIFFFindOrRegisterFieldInfo( TIFF *tif,
@@ -188,7 +189,6 @@ extern const TIFFFieldInfo* _TIFFFindOrRegisterFieldInfo( TIFF *tif,
extern TIFFFieldInfo* _TIFFCreateAnonFieldInfo( TIFF *tif, ttag_t tag,
TIFFDataType dt );
-#define _TIFFMergeFieldInfo TIFFMergeFieldInfo
#define _TIFFFindFieldInfo TIFFFindFieldInfo
#define _TIFFFindFieldInfoByName TIFFFindFieldInfoByName
#define _TIFFFieldWithTag TIFFFieldWithTag
diff --git a/libtiff/tif_dirinfo.c b/libtiff/tif_dirinfo.c
index 515e04c0..9c75e4a3 100644
--- a/libtiff/tif_dirinfo.c
+++ b/libtiff/tif_dirinfo.c
@@ -1,4 +1,4 @@
-/* $Id: tif_dirinfo.c,v 1.66 2007-03-17 04:41:29 joris Exp $ */
+/* $Id: tif_dirinfo.c,v 1.65.2.1 2007-04-07 14:58:30 dron Exp $ */
/*
* Copyright (c) 1988-1997 Sam Leffler
@@ -544,7 +544,11 @@ _TIFFSetupFieldInfo(TIFF* tif, const TIFFFieldInfo info[], size_t n)
_TIFFfree(tif->tif_fieldinfo);
tif->tif_nfields = 0;
}
- _TIFFMergeFieldInfo(tif, info, n);
+ if (!_TIFFMergeFieldInfo(tif, info, n))
+ {
+ TIFFErrorExt(tif->tif_clientdata, "_TIFFSetupFieldInfo",
+ "Setting up field info failed");
+ }
}
static int
@@ -554,9 +558,10 @@ tagCompare(const void* a, const void* b)
const TIFFFieldInfo* tb = *(const TIFFFieldInfo**) b;
/* NB: be careful of return values for 16-bit platforms */
if (ta->field_tag != tb->field_tag)
- return (ta->field_tag < tb->field_tag ? -1 : 1);
+ return (int)ta->field_tag - (int)tb->field_tag;
else
- return ((int)tb->field_type - (int)ta->field_type);
+ return (ta->field_type == TIFF_ANY) ?
+ 0 : ((int)tb->field_type - (int)ta->field_type);
}
static int
@@ -564,22 +569,49 @@ tagNameCompare(const void* a, const void* b)
{
const TIFFFieldInfo* ta = *(const TIFFFieldInfo**) a;
const TIFFFieldInfo* tb = *(const TIFFFieldInfo**) b;
+ int ret = strcmp(ta->field_name, tb->field_name);
- return strcmp(ta->field_name, tb->field_name);
+ if (ret)
+ return ret;
+ else
+ return (ta->field_type == TIFF_ANY) ?
+ 0 : ((int)tb->field_type - (int)ta->field_type);
}
void
+TIFFMergeFieldInfo(TIFF* tif, const TIFFFieldInfo info[], int n)
+{
+ if (_TIFFMergeFieldInfo(tif, info, n) < 0)
+ {
+ TIFFErrorExt(tif->tif_clientdata, "TIFFMergeFieldInfo",
+ "Merging block of %d fields failed", n);
+ }
+}
+
+int
_TIFFMergeFieldInfo(TIFF* tif, const TIFFFieldInfo info[], int n)
{
TIFFFieldInfo** tp;
int i;
+ for (i = 0; i < n; i++) {
+ const TIFFFieldInfo *fip =
+ _TIFFFindFieldInfo(tif, info[i].field_tag, TIFF_ANY);
+ if (fip) {
+ TIFFErrorExt(tif->tif_clientdata, "_TIFFMergeFieldInfo",
+ "Field with tag %lu is already registered as \"%s\"",
+ (unsigned int) info[i].field_tag,
+ fip->field_name);
+ return 0;
+ }
+ }
+
tif->tif_foundfield = NULL;
if (tif->tif_nfields > 0) {
tif->tif_fieldinfo = (TIFFFieldInfo**)
_TIFFrealloc(tif->tif_fieldinfo,
- (tif->tif_nfields+n) * sizeof (TIFFFieldInfo*));
+ (tif->tif_nfields + n) * sizeof (TIFFFieldInfo*));
} else {
tif->tif_fieldinfo = (TIFFFieldInfo**)
_TIFFmalloc(n * sizeof (TIFFFieldInfo*));
@@ -592,6 +624,8 @@ _TIFFMergeFieldInfo(TIFF* tif, const TIFFFieldInfo info[], int n)
/* Sort the field info by tag number */
qsort(tif->tif_fieldinfo, tif->tif_nfields += n,
sizeof (TIFFFieldInfo*), tagCompare);
+
+ return n;
}
void
@@ -623,29 +657,26 @@ TIFFDataWidth(TIFFDataType type)
{
switch(type)
{
- case 0: /* nothing */
- case TIFF_BYTE:
- case TIFF_ASCII:
- case TIFF_SBYTE:
- case TIFF_UNDEFINED:
- return 1;
- case TIFF_SHORT:
- case TIFF_SSHORT:
- return 2;
- case TIFF_LONG:
- case TIFF_SLONG:
- case TIFF_FLOAT:
- case TIFF_IFD:
- return 4;
- case TIFF_RATIONAL:
- case TIFF_SRATIONAL:
- case TIFF_DOUBLE:
- case TIFF_LONG8:
- case TIFF_SLONG8:
- case TIFF_IFD8:
- return 8;
- default:
- return 0; /* will return 0 for unknown types */
+ case 0: /* nothing */
+ case 1: /* TIFF_BYTE */
+ case 2: /* TIFF_ASCII */
+ case 6: /* TIFF_SBYTE */
+ case 7: /* TIFF_UNDEFINED */
+ return 1;
+ case 3: /* TIFF_SHORT */
+ case 8: /* TIFF_SSHORT */
+ return 2;
+ case 4: /* TIFF_LONG */
+ case 9: /* TIFF_SLONG */
+ case 11: /* TIFF_FLOAT */
+ case 13: /* TIFF_IFD */
+ return 4;
+ case 5: /* TIFF_RATIONAL */
+ case 10: /* TIFF_SRATIONAL */
+ case 12: /* TIFF_DOUBLE */
+ return 8;
+ default:
+ return 0; /* will return 0 for unknown types */
}
}
@@ -659,8 +690,7 @@ TIFFDataWidth(TIFFDataType type)
int
_TIFFDataSize(TIFFDataType type)
{
- switch (type)
- {
+ switch (type) {
case TIFF_BYTE:
case TIFF_SBYTE:
case TIFF_ASCII:
@@ -677,9 +707,6 @@ _TIFFDataSize(TIFFDataType type)
case TIFF_SRATIONAL:
return 4;
case TIFF_DOUBLE:
- case TIFF_LONG8:
- case TIFF_SLONG8:
- case TIFF_IFD8:
return 8;
default:
return 0;
@@ -713,67 +740,46 @@ _TIFFSampleToTagType(TIFF* tif)
const TIFFFieldInfo*
_TIFFFindFieldInfo(TIFF* tif, ttag_t tag, TIFFDataType dt)
{
- int i, n;
-
if (tif->tif_foundfield && tif->tif_foundfield->field_tag == tag &&
(dt == TIFF_ANY || dt == tif->tif_foundfield->field_type))
return tif->tif_foundfield;
/* NB: use sorted search (e.g. binary search) */
- if(dt != TIFF_ANY) {
- TIFFFieldInfo key = {0, 0, 0, TIFF_NOTYPE, 0, 0, 0, 0};
- TIFFFieldInfo* pkey = &key;
- const TIFFFieldInfo **ret;
-
- key.field_tag = tag;
- key.field_type = dt;
-
- ret = (const TIFFFieldInfo **) bsearch(&pkey,
- tif->tif_fieldinfo,
- tif->tif_nfields,
- sizeof(TIFFFieldInfo *),
- tagCompare);
- return ret ? *ret : NULL;
- } else for (i = 0, n = tif->tif_nfields; i < n; i++) {
- const TIFFFieldInfo* fip = tif->tif_fieldinfo[i];
- if (fip->field_tag == tag &&
- (dt == TIFF_ANY || fip->field_type == dt))
- return (tif->tif_foundfield = fip);
- }
- return (const TIFFFieldInfo *)0;
+ TIFFFieldInfo key = {0, 0, 0, TIFF_NOTYPE, 0, 0, 0, 0};
+ TIFFFieldInfo* pkey = &key;
+ const TIFFFieldInfo **ret;
+
+ key.field_tag = tag;
+ key.field_type = dt;
+
+ ret = (const TIFFFieldInfo **) bsearch(&pkey,
+ tif->tif_fieldinfo,
+ tif->tif_nfields,
+ sizeof(TIFFFieldInfo *),
+ tagCompare);
+ return tif->tif_foundfield = (ret ? *ret : NULL);
}
const TIFFFieldInfo*
_TIFFFindFieldInfoByName(TIFF* tif, const char *field_name, TIFFDataType dt)
{
- int i, n;
-
if (tif->tif_foundfield
&& streq(tif->tif_foundfield->field_name, field_name)
&& (dt == TIFF_ANY || dt == tif->tif_foundfield->field_type))
return (tif->tif_foundfield);
/* NB: use sorted search (e.g. binary search) */
- if(dt != TIFF_ANY) {
- TIFFFieldInfo key = {0, 0, 0, TIFF_NOTYPE, 0, 0, 0, 0};
- TIFFFieldInfo* pkey = &key;
- const TIFFFieldInfo **ret;
-
- key.field_name = (char *)field_name;
- key.field_type = dt;
-
- ret = (const TIFFFieldInfo **) lfind(&pkey,
- tif->tif_fieldinfo,
- &tif->tif_nfields,
- sizeof(TIFFFieldInfo *),
- tagNameCompare);
- return (ret) ? (*ret) : NULL;
- } else
- for (i = 0, n = tif->tif_nfields; i < n; i++) {
- const TIFFFieldInfo* fip = tif->tif_fieldinfo[i];
- if (streq(fip->field_name, field_name) &&
- (dt == TIFF_ANY || fip->field_type == dt))
- return (tif->tif_foundfield = fip);
- }
- return ((const TIFFFieldInfo *)0);
+ TIFFFieldInfo key = {0, 0, 0, TIFF_NOTYPE, 0, 0, 0, 0};
+ TIFFFieldInfo* pkey = &key;
+ const TIFFFieldInfo **ret;
+
+ key.field_name = (char *)field_name;
+ key.field_type = dt;
+
+ ret = (const TIFFFieldInfo **) lfind(&pkey,
+ tif->tif_fieldinfo,
+ &tif->tif_nfields,
+ sizeof(TIFFFieldInfo *),
+ tagNameCompare);
+ return tif->tif_foundfield = (ret ? *ret : NULL);
}
const TIFFFieldInfo*
@@ -814,7 +820,8 @@ _TIFFFindOrRegisterFieldInfo( TIFF *tif, ttag_t tag, TIFFDataType dt )
if( fld == NULL )
{
fld = _TIFFCreateAnonFieldInfo( tif, tag, dt );
- _TIFFMergeFieldInfo( tif, fld, 1 );
+ if (!_TIFFMergeFieldInfo(tif, fld, 1))
+ return NULL;
}
return fld;
diff --git a/libtiff/tif_dirread.c b/libtiff/tif_dirread.c
index 3b0a5918..cd1c6907 100644
--- a/libtiff/tif_dirread.c
+++ b/libtiff/tif_dirread.c
@@ -1,26 +1,26 @@
-/* $Id: tif_dirread.c,v 1.95 2007-03-19 12:11:15 joris Exp $ */
+/* $Id: tif_dirread.c,v 1.92.2.1 2007-04-07 14:58:30 dron Exp $ */
/*
* Copyright (c) 1988-1997 Sam Leffler
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
*
- * Permission to use, copy, modify, distribute, and sell this software and
+ * Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee, provided
* that (i) the above copyright notices and this permission notice appear in
* all copies of the software and related documentation, and (ii) the names of
* Sam Leffler and Silicon Graphics may not be used in any advertising or
* publicity relating to the software without the specific, prior written
* permission of Sam Leffler and Silicon Graphics.
- *
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- *
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
@@ -37,35 +37,34 @@
# define TIFFCvtIEEEFloatToNative(tif, n, fp)
# define TIFFCvtIEEEDoubleToNative(tif, n, dp)
#else
-extern void TIFFCvtIEEEFloatToNative(TIFF*, uint32, float*);
-extern void TIFFCvtIEEEDoubleToNative(TIFF*, uint32, double*);
+extern void TIFFCvtIEEEFloatToNative(TIFF*, uint32, float*);
+extern void TIFFCvtIEEEDoubleToNative(TIFF*, uint32, double*);
#endif
-static TIFFDirEntryUnion* TIFFReadDirectoryFind(TIFF* tif, TIFFDirEntryUnion* dir, uint16 dircount, uint16 tagid);
-static int EstimateStripByteCountsClassic(TIFF*, TIFFDirEntryClassic*, uint16);
-static int EstimateStripByteCountsBig(TIFF*, TIFFDirEntryBig*, uint16);
-static void MissingRequired(TIFF*, const char*);
-static int TIFFCheckDirOffset(TIFF* tif, uint64 diroff);
-static int CheckDirCountClassic(TIFF*, TIFFDirEntryClassic*, uint32);
-static int CheckDirCountBig(TIFF*, TIFFDirEntryBig*, uint32);
-static uint16 TIFFFetchDirectory(TIFF* tif, uint64 diroff, TIFFDirEntryUnion** pdir, uint64* nextdiroff);
-static uint32 TIFFFetchData(TIFF*, TIFFDirEntryUnion*, char*);
-static uint32 TIFFFetchString(TIFF*, TIFFDirEntryUnion*, char*);
-static float TIFFFetchRational(TIFF*, TIFFDirEntryUnion*);
-static int TIFFFetchNormalTag(TIFF*, TIFFDirEntryUnion*);
-static int TIFFFetchPerSampleShorts(TIFF*, TIFFDirEntryUnion*, uint16*);
-static int TIFFFetchPerSampleLongs(TIFF*, TIFFDirEntryUnion*, uint32*);
-static int TIFFFetchPerSampleAnys(TIFF*, TIFFDirEntryUnion*, double*);
-static int TIFFFetchShortArray(TIFF*, TIFFDirEntryUnion*, uint16*);
-static int TIFFFetchStripThing(TIFF*, TIFFDirEntryUnion*, long, uint64**);
-static int TIFFFetchRefBlackWhite(TIFF*, TIFFDirEntryUnion*);
-static int TIFFFetchSubjectDistance(TIFF*, TIFFDirEntryUnion*);
-static float TIFFFetchFloat(TIFF*, TIFFDirEntryUnion*);
-static int TIFFFetchFloatArray(TIFF*, TIFFDirEntryUnion*, float*);
-static int TIFFFetchDoubleArray(TIFF*, TIFFDirEntryUnion*, double*);
-static int TIFFFetchAnyArray(TIFF*, TIFFDirEntryUnion*, double*);
-static int TIFFFetchShortPair(TIFF*, TIFFDirEntryUnion*);
-static void ChopUpSingleUncompressedStrip(TIFF*);
+static TIFFDirEntry* TIFFReadDirectoryFind(TIFFDirEntry* dir,
+ uint16 dircount, uint16 tagid);
+static int EstimateStripByteCounts(TIFF*, TIFFDirEntry*, uint16);
+static void MissingRequired(TIFF*, const char*);
+static int TIFFCheckDirOffset(TIFF*, toff_t);
+static int CheckDirCount(TIFF*, TIFFDirEntry*, uint32);
+static uint16 TIFFFetchDirectory(TIFF*, toff_t, TIFFDirEntry**, toff_t *);
+static tsize_t TIFFFetchData(TIFF*, TIFFDirEntry*, char*);
+static tsize_t TIFFFetchString(TIFF*, TIFFDirEntry*, char*);
+static float TIFFFetchRational(TIFF*, TIFFDirEntry*);
+static int TIFFFetchNormalTag(TIFF*, TIFFDirEntry*);
+static int TIFFFetchPerSampleShorts(TIFF*, TIFFDirEntry*, uint16*);
+static int TIFFFetchPerSampleLongs(TIFF*, TIFFDirEntry*, uint32*);
+static int TIFFFetchPerSampleAnys(TIFF*, TIFFDirEntry*, double*);
+static int TIFFFetchShortArray(TIFF*, TIFFDirEntry*, uint16*);
+static int TIFFFetchStripThing(TIFF*, TIFFDirEntry*, long, uint32**);
+static int TIFFFetchRefBlackWhite(TIFF*, TIFFDirEntry*);
+static int TIFFFetchSubjectDistance(TIFF*, TIFFDirEntry*);
+static float TIFFFetchFloat(TIFF*, TIFFDirEntry*);
+static int TIFFFetchFloatArray(TIFF*, TIFFDirEntry*, float*);
+static int TIFFFetchDoubleArray(TIFF*, TIFFDirEntry*, double*);
+static int TIFFFetchAnyArray(TIFF*, TIFFDirEntry*, double*);
+static int TIFFFetchShortPair(TIFF*, TIFFDirEntry*);
+static void ChopUpSingleUncompressedStrip(TIFF*);
/*
* Read the next TIFF directory from a file and convert it to the internal
@@ -78,7 +77,7 @@ TIFFReadDirectory(TIFF* tif)
int n;
TIFFDirectory* td;
- TIFFDirEntryUnion *dp, *dir = NULL;
+ TIFFDirEntry *dp, *dir = NULL;
uint16 iv;
uint32 v;
const TIFFFieldInfo* fip;
@@ -126,7 +125,11 @@ TIFFReadDirectory(TIFF* tif)
*/
TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
- /* We must process the Compression tag in the first pass
+ /*
+ * Sigh, we must make a separate pass through the
+ * directory for the following reason:
+ *
+ * We must process the Compression tag in the first pass
* in order to merge in codec-private tag definitions (otherwise
* we may get complaints about unknown tags). However, the
* Compression tag may be dependent on the SamplesPerPixel
@@ -136,20 +139,24 @@ TIFFReadDirectory(TIFF* tif)
* tag value then we may end up ignoring the Compression tag
* value because it has an incorrect count value (if the
* true value of SamplesPerPixel is not 1).
+ *
+ * It sure would have been nice if Aldus had really thought
+ * this stuff through carefully.
*/
- dp=TIFFReadDirectoryFind(tif,dir,dircount,TIFFTAG_SAMPLESPERPIXEL);
- if (dp)
- {
- if (!TIFFFetchNormalTag(tif,dp))
- goto bad;
- dp->common.tdir_tag=IGNORE;
+ for (dp = dir, n = dircount; n > 0; n--, dp++) {
+ if (tif->tif_flags & TIFF_SWAB) {
+ TIFFSwabArrayOfShort(&dp->tdir_tag, 2);
+ TIFFSwabArrayOfLong(&dp->tdir_count, 2);
+ }
+ if (dp->tdir_tag == TIFFTAG_SAMPLESPERPIXEL) {
+ if (!TIFFFetchNormalTag(tif, dp))
+ goto bad;
+ dp->tdir_tag = IGNORE;
+ }
}
/*
* First real pass over the directory.
*/
-
- dddd
-
fix = 0;
for (dp = dir, n = dircount; n > 0; n--, dp++) {
@@ -164,11 +171,11 @@ TIFFReadDirectory(TIFF* tif)
if (dp->tdir_tag < tif->tif_fieldinfo[fix]->field_tag) {
if (!diroutoforderwarning) {
TIFFWarningExt(tif->tif_clientdata, module,
- "%s: invalid TIFF directory; tags are not sorted in ascending order",
- tif->tif_name);
+ "%s: invalid TIFF directory; tags are not sorted in ascending order",
+ tif->tif_name);
diroutoforderwarning = 1;
}
- fix = 0; /* O(n^2) */
+ fix = 0; /* O(n^2) */
}
while (fix < tif->tif_nfields &&
tif->tif_fieldinfo[fix]->field_tag < dp->tdir_tag)
@@ -176,37 +183,30 @@ TIFFReadDirectory(TIFF* tif)
if (fix >= tif->tif_nfields ||
tif->tif_fieldinfo[fix]->field_tag != dp->tdir_tag) {
- TIFFWarningExt(tif->tif_clientdata,
- module,
- "%s: unknown field with tag %d (0x%x) encountered",
- tif->tif_name,
- dp->tdir_tag,
- dp->tdir_tag,
- dp->tdir_type);
-
- TIFFMergeFieldInfo(tif,
- _TIFFCreateAnonFieldInfo(tif,
- dp->tdir_tag,
- (TIFFDataType) dp->tdir_type),
- 1 );
- /*
- * creating anonymous fields prior to
- * knowing the compression algorithm
- * (ie, when the field info has been
- * merged) could cause crashes with
- * pathological directories.
- */
- if (compressionknown) {
- TIFFMergeFieldInfo(tif,
- _TIFFCreateAnonFieldInfo(tif,
- dp->tdir_tag,
- (TIFFDataType) dp->tdir_type),
- 1);
- } else
- goto ignore;
+ TIFFWarningExt(tif->tif_clientdata,
+ module,
+ "%s: unknown field with tag %d (0x%x) encountered",
+ tif->tif_name,
+ dp->tdir_tag,
+ dp->tdir_tag,
+ dp->tdir_type);
+
+ if (!_TIFFMergeFieldInfo(tif,
+ _TIFFCreateAnonFieldInfo(tif,
+ dp->tdir_tag,
+ (TIFFDataType) dp->tdir_type),
+ 1))
+ {
+ TIFFErrorExt(tif->tif_clientdata,
+ module,
+ "Registering anonymous field with tag %d (0x%x) failed",
+ dp->tdir_tag,
+ dp->tdir_tag);
+ goto ignore;
+ }
fix = 0;
while (fix < tif->tif_nfields &&
- tif->tif_fieldinfo[fix]->field_tag < dp->tdir_tag)
+ tif->tif_fieldinfo[fix]->field_tag < dp->tdir_tag)
fix++;
}
/*
@@ -229,9 +229,9 @@ TIFFReadDirectory(TIFF* tif)
if (fix >= tif->tif_nfields ||
fip->field_tag != dp->tdir_tag) {
TIFFWarningExt(tif->tif_clientdata, module,
- "%s: wrong data type %d for \"%s\"; tag ignored",
- tif->tif_name, dp->tdir_type,
- tif->tif_fieldinfo[fix-1]->field_name);
+ "%s: wrong data type %d for \"%s\"; tag ignored",
+ tif->tif_name, dp->tdir_type,
+ tif->tif_fieldinfo[fix-1]->field_name);
goto ignore;
}
}
@@ -742,28 +742,15 @@ TIFFReadDirectory(TIFF* tif)
return (0);
}
-static TIFFDirEntryUnion*
-TIFFReadDirectoryFind(TIFF* tif, TIFFDirEntryUnion* dir, uint16 dircount, uint16 tagid)
+static TIFFDirEntry*
+TIFFReadDirectoryFind(TIFFDirEntry* dir, uint16 dircount, uint16 tagid)
{
- if (!(tif->tif_flags&TIFF_BIGTIFF))
- {
- TIFFDirEntryClassic* m;
- uint16 n;
- for (m=dir, n=0; n<dircount; m++, n++)
- {
- if (m->tdir_tag==tagid)
- return((TIFFDirEntryUnion*)m);
- }
- }
- else
+ TIFFDirEntry* m;
+ uint16 n;
+ for (m=dir, n=0; n<dircount; m++, n++)
{
- TIFFDirEntryBig* m;
- uint16 n;
- for (m=dir, n=0; n<dircount; m++, n++)
- {
- if (m->tdir_tag==tagid)
- return((TIFFDirEntryUnion*)m);
- }
+ if (m->tdir_tag==tagid)
+ return(m);
}
return(0);
}
@@ -798,6 +785,10 @@ TIFFReadCustomDirectory(TIFF* tif, toff_t diroff,
fix = 0;
for (dp = dir, i = dircount; i > 0; i--, dp++) {
+ if (tif->tif_flags & TIFF_SWAB) {
+ TIFFSwabArrayOfShort(&dp->tdir_tag, 2);
+ TIFFSwabArrayOfLong(&dp->tdir_count, 2);
+ }
if (fix >= tif->tif_nfields || dp->tdir_tag == IGNORE)
continue;
@@ -813,12 +804,17 @@ TIFFReadCustomDirectory(TIFF* tif, toff_t diroff,
"%s: unknown field with tag %d (0x%x) encountered",
tif->tif_name, dp->tdir_tag, dp->tdir_tag,
dp->tdir_type);
-
- TIFFMergeFieldInfo(tif,
- _TIFFCreateAnonFieldInfo(tif,
- dp->tdir_tag,
- (TIFFDataType)dp->tdir_type),
- 1);
+ if (!_TIFFMergeFieldInfo(tif,
+ _TIFFCreateAnonFieldInfo(tif,
+ dp->tdir_tag,
+ (TIFFDataType) dp->tdir_type),
+ 1))
+ {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Registering anonymous field with tag %d (0x%x) failed",
+ dp->tdir_tag, dp->tdir_tag);
+ goto ignore;
+ }
fix = 0;
while (fix < tif->tif_nfields &&
@@ -875,7 +871,7 @@ TIFFReadCustomDirectory(TIFF* tif, toff_t diroff,
break;
}
}
-
+
if (dir)
_TIFFfree(dir);
return 1;
@@ -896,11 +892,11 @@ TIFFReadEXIFDirectory(TIFF* tif, toff_t diroff)
}
static int
-EstimateStripByteCountsClassic(TIFF* tif, TIFFDirEntryClassic* dir, uint16 dircount)
+EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16 dircount)
{
- static const char module[] = "EstimateStripByteCountsClassic";
+ static const char module[] = "EstimateStripByteCounts";
- TIFFDirEntryClassic *dp;
+ TIFFDirEntry *dp;
TIFFDirectory *td = &tif->tif_dir;
uint32 strip;
@@ -910,10 +906,9 @@ EstimateStripByteCountsClassic(TIFF* tif, TIFFDirEntryClassic* dir, uint16 dirco
_TIFFCheckMalloc(tif, td->td_nstrips, sizeof (uint32),
"for \"StripByteCounts\" array");
if (td->td_compression != COMPRESSION_NONE) {
- uint32 space = (uint32)(
- sizeof(TIFFHeaderClassic)
+ uint32 space = (uint32)(sizeof (TIFFHeader)
+ sizeof (uint16)
- + (dircount * sizeof (TIFFDirEntryClassic))
+ + (dircount * sizeof (TIFFDirEntry))
+ sizeof (uint32));
toff_t filesize = TIFFGetFileSize(tif);
uint16 n;
@@ -953,78 +948,7 @@ EstimateStripByteCountsClassic(TIFF* tif, TIFFDirEntryClassic* dir, uint16 dirco
uint32 bytespertile = TIFFTileSize(tif);
for (strip = 0; strip < td->td_nstrips; strip++)
- td->td_stripbytecount[strip] = bytespertile;
- } else {
- uint32 rowbytes = TIFFScanlineSize(tif);
- uint32 rowsperstrip = td->td_imagelength/td->td_stripsperimage;
- for (strip = 0; strip < td->td_nstrips; strip++)
- td->td_stripbytecount[strip] = rowbytes * rowsperstrip;
- }
- TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS);
- if (!TIFFFieldSet(tif, FIELD_ROWSPERSTRIP))
- td->td_rowsperstrip = td->td_imagelength;
- return 1;
-}
-
-static int
-EstimateStripByteCountsBig(TIFF* tif, TIFFDirEntryBig* dir, uint16 dircount)
-{
- static const char module[] = "EstimateStripByteCountsBig";
-
- TIFFDirEntryBig *dp;
- TIFFDirectory *td = &tif->tif_dir;
- uint32 strip;
-
- if (td->td_stripbytecount)
- _TIFFfree(td->td_stripbytecount);
- td->td_stripbytecount = (uint32*)
- _TIFFCheckMalloc(tif, td->td_nstrips, sizeof (uint32),
- "for \"StripByteCounts\" array");
- if (td->td_compression != COMPRESSION_NONE) {
- uint32 space = (uint32)(
- sizeof(TIFFHeaderBig)
- + sizeof (uint64)
- + (dircount * sizeof (TIFFDirEntryBig))
- + sizeof (uint64));
- toff_t filesize = TIFFGetFileSize(tif);
- uint16 n;
-
- /* calculate amount of space used by indirect values */
- for (dp = dir, n = dircount; n > 0; n--, dp++)
- {
- uint32 cc = TIFFDataWidth((TIFFDataType) dp->tdir_type);
- if (cc == 0) {
- TIFFErrorExt(tif->tif_clientdata, module,
- "%s: Cannot determine size of unknown tag type %d",
- tif->tif_name, dp->tdir_type);
- return -1;
- }
- cc = cc * dp->tdir_count;
- if (cc > sizeof (uint64))
- space += cc;
- }
- space = filesize - space;
- if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
- space /= td->td_samplesperpixel;
- for (strip = 0; strip < td->td_nstrips; strip++)
- td->td_stripbytecount[strip] = space;
- /*
- * This gross hack handles the case were the offset to
- * the last strip is past the place where we think the strip
- * should begin. Since a strip of data must be contiguous,
- * it's safe to assume that we've overestimated the amount
- * of data in the strip and trim this number back accordingly.
- */
- strip--;
- if (((toff_t)(td->td_stripoffset[strip]+
- td->td_stripbytecount[strip])) > filesize)
- td->td_stripbytecount[strip] =
- filesize - td->td_stripoffset[strip];
- } else if (isTiled(tif)) {
- uint32 bytespertile = TIFFTileSize(tif);
-
- for (strip = 0; strip < td->td_nstrips; strip++)
- td->td_stripbytecount[strip] = bytespertile;
+ td->td_stripbytecount[strip] = bytespertile;
} else {
uint32 rowbytes = TIFFScanlineSize(tif);
uint32 rowsperstrip = td->td_imagelength/td->td_stripsperimage;
@@ -1054,7 +978,7 @@ MissingRequired(TIFF* tif, const char* tagname)
* seen directories and check every IFD offset against that list.
*/
static int
-TIFFCheckDirOffset(TIFF* tif, uint64 diroff)
+TIFFCheckDirOffset(TIFF* tif, toff_t diroff)
{
uint16 n;
@@ -1069,16 +993,16 @@ TIFFCheckDirOffset(TIFF* tif, uint64 diroff)
tif->tif_dirnumber++;
if (tif->tif_dirnumber > tif->tif_dirlistsize) {
- uint64* new_dirlist;
+ toff_t* new_dirlist;
/*
* XXX: Reduce memory allocation granularity of the dirlist
* array.
*/
- new_dirlist = (uint64*)_TIFFCheckRealloc(tif,
+ new_dirlist = (toff_t *)_TIFFCheckRealloc(tif,
tif->tif_dirlist,
tif->tif_dirnumber,
- 2 * sizeof(uint64),
+ 2 * sizeof(toff_t),
"for IFD list");
if (!new_dirlist)
return 0;
@@ -1096,35 +1020,17 @@ TIFFCheckDirOffset(TIFF* tif, uint64 diroff)
* caller is expected to skip/ignore the tag if there is a mismatch.
*/
static int
-CheckDirCountClassic(TIFF* tif, TIFFDirEntryClassic* dir, uint32 count)
-{
- if (count > dir->tdir_count) {
- TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
- "incorrect count for field \"%s\" (%lu, expecting %lu); tag ignored",
- _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name,
- dir->tdir_count, count);
- return (0);
- } else if (count < dir->tdir_count) {
- TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
- "incorrect count for field \"%s\" (%lu, expecting %lu); tag trimmed",
- _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name,
- dir->tdir_count, count);
- return (1);
- }
- return (1);
-}
-static int
-CheckDirCountBig(TIFF* tif, TIFFDirEntryBig* dir, uint32 count)
+CheckDirCount(TIFF* tif, TIFFDirEntry* dir, uint32 count)
{
if (count > dir->tdir_count) {
TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
- "incorrect count for field \"%s\" (%lu, expecting %lu); tag ignored",
+ "incorrect count for field \"%s\" (%lu, expecting %lu); tag ignored",
_TIFFFieldWithTag(tif, dir->tdir_tag)->field_name,
dir->tdir_count, count);
return (0);
} else if (count < dir->tdir_count) {
TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
- "incorrect count for field \"%s\" (%lu, expecting %lu); tag trimmed",
+ "incorrect count for field \"%s\" (%lu, expecting %lu); tag trimmed",
_TIFFFieldWithTag(tif, dir->tdir_tag)->field_name,
dir->tdir_count, count);
return (1);
@@ -1138,15 +1044,13 @@ CheckDirCountBig(TIFF* tif, TIFFDirEntryBig* dir, uint32 count)
* number of fields in the directory or 0 if failed.
*/
static uint16
-TIFFFetchDirectory(TIFF* tif, uint64 diroff, TIFFDirEntryUnion** pdir,
- uint64 *nextdiroff)
+TIFFFetchDirectory(TIFF* tif, toff_t diroff, TIFFDirEntry **pdir,
+ toff_t *nextdiroff)
{
- static const char module[] = "TIFFFetchDirectoryClassic";
+ static const char module[] = "TIFFFetchDirectory";
- TIFFDirEntryUnion *dir;
- uint64 dircount64;
- uint16 dircount16;
- uint32 dirsize;
+ TIFFDirEntry *dir;
+ uint16 dircount;
assert(pdir);
@@ -1160,46 +1064,20 @@ TIFFFetchDirectory(TIFF* tif, uint64 diroff, TIFFDirEntryUnion** pdir,
tif->tif_name);
return 0;
}
- if (!(tif->tif_flags&TIFF_BIGTIFF))
- {
- if (!ReadOK(tif, &dircount16, sizeof (uint16))) {
- TIFFErrorExt(tif->tif_clientdata, module,
- "%s: Can not read TIFF directory count",
- tif->tif_name);
- return 0;
- }
- if (tif->tif_flags & TIFF_SWAB)
- TIFFSwabShort(&dircount);
- if (dircount16>4096)
- {
- TIFFErrorExt(tif->tif_clientdata, module,
- "Sanity check on directory count failed, this is probably not a valid IFD offset");
- return 0;
- }
- dirsize = sizeof(TIFFDirEntryClassic);
- } else {
- if (!ReadOK(tif, &dircount64, sizeof (uint64))) {
- TIFFErrorExt(tif->tif_clientdata, module,
- "%s: Can not read TIFF directory count",
- tif->tif_name);
- return 0;
- }
- if (tif->tif_flags & TIFF_SWAB)
- TIFFSwabLong8(&dircount64);
- if (dircount64>4096)
- {
- TIFFErrorExt(tif->tif_clientdata, module,
- "Sanity check on directory count failed, this is probably not a valid IFD offset");
- return 0;
- }
- dircount16 = (uint16)dircount64;
- dirsize = sizeof(TIFFDirEntryBig);
+ if (!ReadOK(tif, &dircount, sizeof (uint16))) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "%s: Can not read TIFF directory count",
+ tif->tif_name);
+ return 0;
}
- dir = (TIFFDirEntryUnion *)_TIFFCheckMalloc(tif, dircount,
- dirsize, "to read TIFF directory");
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabShort(&dircount);
+ dir = (TIFFDirEntry *)_TIFFCheckMalloc(tif, dircount,
+ sizeof (TIFFDirEntry),
+ "to read TIFF directory");
if (dir == NULL)
return 0;
- if (!ReadOK(tif, dir, dircount*dirsize)) {
+ if (!ReadOK(tif, dir, dircount*sizeof (TIFFDirEntry))) {
TIFFErrorExt(tif->t
(Patch may be truncated, please check the link at the top of this post.)