summaryrefslogtreecommitdiffstats
path: root/source/l/libtiff/tiff-3.8.2.goo-sec.diff
diff options
context:
space:
mode:
author Patrick J Volkerding <volkerdi@slackware.com>2009-08-26 10:00:38 -0500
committer Eric Hameleers <alien@slackware.com>2018-05-31 22:41:17 +0200
commit5a12e7c134274dba706667107d10d231517d3e05 (patch)
tree55718d5acb710fde798d9f38d0bbaf594ed4b296 /source/l/libtiff/tiff-3.8.2.goo-sec.diff
downloadcurrent-5a12e7c134274dba706667107d10d231517d3e05.tar.gz
current-5a12e7c134274dba706667107d10d231517d3e05.tar.xz
Slackware 13.0slackware-13.0
Wed Aug 26 10:00:38 CDT 2009 Slackware 13.0 x86_64 is released as stable! Thanks to everyone who helped make this release possible -- see the RELEASE_NOTES for the credits. The ISOs are off to the replicator. This time it will be a 6 CD-ROM 32-bit set and a dual-sided 32-bit/64-bit x86/x86_64 DVD. We're taking pre-orders now at store.slackware.com. Please consider picking up a copy to help support the project. Once again, thanks to the entire Slackware community for all the help testing and fixing things and offering suggestions during this development cycle. As always, have fun and enjoy! -P.
Diffstat (limited to 'source/l/libtiff/tiff-3.8.2.goo-sec.diff')
-rw-r--r--source/l/libtiff/tiff-3.8.2.goo-sec.diff661
1 files changed, 661 insertions, 0 deletions
diff --git a/source/l/libtiff/tiff-3.8.2.goo-sec.diff b/source/l/libtiff/tiff-3.8.2.goo-sec.diff
new file mode 100644
index 000000000..a5f9e6d5a
--- /dev/null
+++ b/source/l/libtiff/tiff-3.8.2.goo-sec.diff
@@ -0,0 +1,661 @@
+--- ./libtiff/tif_read.c.orig 2005-12-21 06:33:56.000000000 -0600
++++ ./libtiff/tif_read.c 2006-08-17 22:02:40.000000000 -0500
+@@ -31,6 +31,8 @@
+ #include "tiffiop.h"
+ #include <stdio.h>
+
++#include <limits.h>
++
+ int TIFFFillStrip(TIFF*, tstrip_t);
+ int TIFFFillTile(TIFF*, ttile_t);
+ static int TIFFStartStrip(TIFF*, tstrip_t);
+@@ -272,7 +274,13 @@
+ if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)
+ _TIFFfree(tif->tif_rawdata);
+ tif->tif_flags &= ~TIFF_MYBUFFER;
+- if ( td->td_stripoffset[strip] + bytecount > tif->tif_size) {
++ /*
++ * This sanity check could potentially overflow, causing an OOB read.
++ * verify that offset + bytecount is > offset.
++ * -- taviso@google.com 14 Jun 2006
++ */
++ if ( td->td_stripoffset[strip] + bytecount > tif->tif_size ||
++ bytecount > (UINT_MAX - td->td_stripoffset[strip])) {
+ /*
+ * This error message might seem strange, but it's
+ * what would happen if a read were done instead.
+@@ -470,7 +478,13 @@
+ if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)
+ _TIFFfree(tif->tif_rawdata);
+ tif->tif_flags &= ~TIFF_MYBUFFER;
+- if ( td->td_stripoffset[tile] + bytecount > tif->tif_size) {
++ /*
++ * We must check this calculation doesnt overflow, potentially
++ * causing an OOB read.
++ * -- taviso@google.com 15 Jun 2006
++ */
++ if (td->td_stripoffset[tile] + bytecount > tif->tif_size ||
++ bytecount > (UINT_MAX - td->td_stripoffset[tile])) {
+ tif->tif_curtile = NOTILE;
+ return (0);
+ }
+--- ./libtiff/tif_next.c.orig 2005-12-21 06:33:56.000000000 -0600
++++ ./libtiff/tif_next.c 2006-08-17 22:02:40.000000000 -0500
+@@ -105,11 +105,16 @@
+ * as codes of the form <color><npixels>
+ * until we've filled the scanline.
+ */
++ /*
++ * Ensure the run does not exceed the scanline
++ * bounds, potentially resulting in a security issue.
++ * -- taviso@google.com 14 Jun 2006.
++ */
+ op = row;
+ for (;;) {
+ grey = (n>>6) & 0x3;
+ n &= 0x3f;
+- while (n-- > 0)
++ while (n-- > 0 && npixels < imagewidth)
+ SETPIXEL(op, grey);
+ if (npixels >= (int) imagewidth)
+ break;
+--- ./libtiff/tif_jpeg.c.orig 2006-03-21 10:42:50.000000000 -0600
++++ ./libtiff/tif_jpeg.c 2006-08-17 22:02:40.000000000 -0500
+@@ -722,15 +722,31 @@
+ segment_width = TIFFhowmany(segment_width, sp->h_sampling);
+ segment_height = TIFFhowmany(segment_height, sp->v_sampling);
+ }
+- if (sp->cinfo.d.image_width != segment_width ||
+- sp->cinfo.d.image_height != segment_height) {
++ if (sp->cinfo.d.image_width < segment_width ||
++ sp->cinfo.d.image_height < segment_height) {
+ TIFFWarningExt(tif->tif_clientdata, module,
+ "Improper JPEG strip/tile size, expected %dx%d, got %dx%d",
+ segment_width,
+ segment_height,
+ sp->cinfo.d.image_width,
+ sp->cinfo.d.image_height);
++ }
++
++ if (sp->cinfo.d.image_width > segment_width ||
++ sp->cinfo.d.image_height > segment_height) {
++ /*
++ * This case could be dangerous, if the strip or tile size has been
++ * reported as less than the amount of data jpeg will return, some
++ * potential security issues arise. Catch this case and error out.
++ * -- taviso@google.com 14 Jun 2006
++ */
++ TIFFErrorExt(tif->tif_clientdata, module,
++ "JPEG strip/tile size exceeds expected dimensions,"
++ "expected %dx%d, got %dx%d", segment_width, segment_height,
++ sp->cinfo.d.image_width, sp->cinfo.d.image_height);
++ return (0);
+ }
++
+ if (sp->cinfo.d.num_components !=
+ (td->td_planarconfig == PLANARCONFIG_CONTIG ?
+ td->td_samplesperpixel : 1)) {
+@@ -761,6 +777,22 @@
+ sp->cinfo.d.comp_info[0].v_samp_factor,
+ sp->h_sampling, sp->v_sampling);
+
++ /*
++ * There are potential security issues here for decoders that
++ * have already allocated buffers based on the expected sampling
++ * factors. Lets check the sampling factors dont exceed what
++ * we were expecting.
++ * -- taviso@google.com 14 June 2006
++ */
++ if (sp->cinfo.d.comp_info[0].h_samp_factor > sp->h_sampling ||
++ sp->cinfo.d.comp_info[0].v_samp_factor > sp->v_sampling) {
++ TIFFErrorExt(tif->tif_clientdata, module,
++ "Cannot honour JPEG sampling factors that"
++ " exceed those specified.");
++ return (0);
++ }
++
++
+ /*
+ * XXX: Files written by the Intergraph software
+ * has different sampling factors stored in the
+@@ -1521,15 +1553,18 @@
+ {
+ JPEGState *sp = JState(tif);
+
+- assert(sp != 0);
++ /* assert(sp != 0); */
+
+ tif->tif_tagmethods.vgetfield = sp->vgetparent;
+ tif->tif_tagmethods.vsetfield = sp->vsetparent;
+
+- if( sp->cinfo_initialized )
+- TIFFjpeg_destroy(sp); /* release libjpeg resources */
+- if (sp->jpegtables) /* tag value */
+- _TIFFfree(sp->jpegtables);
++ if (sp != NULL) {
++ if( sp->cinfo_initialized )
++ TIFFjpeg_destroy(sp); /* release libjpeg resources */
++ if (sp->jpegtables) /* tag value */
++ _TIFFfree(sp->jpegtables);
++ }
++
+ _TIFFfree(tif->tif_data); /* release local state */
+ tif->tif_data = NULL;
+
+@@ -1541,6 +1576,7 @@
+ {
+ JPEGState* sp = JState(tif);
+ TIFFDirectory* td = &tif->tif_dir;
++ const TIFFFieldInfo* fip;
+ uint32 v32;
+
+ assert(sp != NULL);
+@@ -1606,7 +1642,13 @@
+ default:
+ return (*sp->vsetparent)(tif, tag, ap);
+ }
+- TIFFSetFieldBit(tif, _TIFFFieldWithTag(tif, tag)->field_bit);
++
++ if ((fip = _TIFFFieldWithTag(tif, tag))) {
++ TIFFSetFieldBit(tif, fip->field_bit);
++ } else {
++ return (0);
++ }
++
+ tif->tif_flags |= TIFF_DIRTYDIRECT;
+ return (1);
+ }
+@@ -1726,7 +1768,11 @@
+ {
+ JPEGState* sp = JState(tif);
+
+- assert(sp != NULL);
++ /* assert(sp != NULL); */
++ if (sp == NULL) {
++ TIFFWarningExt(tif->tif_clientdata, "JPEGPrintDir", "Unknown JPEGState");
++ return;
++ }
+
+ (void) flags;
+ if (TIFFFieldSet(tif,FIELD_JPEGTABLES))
+--- ./libtiff/tif_dir.c.orig 2006-03-21 10:42:50.000000000 -0600
++++ ./libtiff/tif_dir.c 2006-08-17 22:02:40.000000000 -0500
+@@ -122,6 +122,7 @@
+ {
+ static const char module[] = "_TIFFVSetField";
+
++ const TIFFFieldInfo* fip = _TIFFFindFieldInfo(tif, tag, TIFF_ANY);
+ TIFFDirectory* td = &tif->tif_dir;
+ int status = 1;
+ uint32 v32, i, v;
+@@ -195,10 +196,12 @@
+ break;
+ case TIFFTAG_ORIENTATION:
+ v = va_arg(ap, uint32);
++ const TIFFFieldInfo* fip;
+ if (v < ORIENTATION_TOPLEFT || ORIENTATION_LEFTBOT < v) {
++ fip = _TIFFFieldWithTag(tif, tag);
+ TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
+ "Bad value %lu for \"%s\" tag ignored",
+- v, _TIFFFieldWithTag(tif, tag)->field_name);
++ v, fip ? fip->field_name : "Unknown");
+ } else
+ td->td_orientation = (uint16) v;
+ break;
+@@ -387,11 +390,15 @@
+ * happens, for example, when tiffcp is used to convert between
+ * compression schemes and codec-specific tags are blindly copied.
+ */
++ /*
++ * better not dereference fip if it is NULL.
++ * -- taviso@google.com 15 Jun 2006
++ */
+ if(fip == NULL || fip->field_bit != FIELD_CUSTOM) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "%s: Invalid %stag \"%s\" (not supported by codec)",
+ tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "",
+- _TIFFFieldWithTag(tif, tag)->field_name);
++ fip ? fip->field_name : "Unknown");
+ status = 0;
+ break;
+ }
+@@ -468,7 +475,7 @@
+ if (fip->field_type == TIFF_ASCII)
+ _TIFFsetString((char **)&tv->value, va_arg(ap, char *));
+ else {
+- tv->value = _TIFFmalloc(tv_size * tv->count);
++ tv->value = _TIFFCheckMalloc(tif, tv_size, tv->count, "Tag Value");
+ if (!tv->value) {
+ status = 0;
+ goto end;
+@@ -563,7 +570,7 @@
+ }
+ }
+ if (status) {
+- TIFFSetFieldBit(tif, _TIFFFieldWithTag(tif, tag)->field_bit);
++ TIFFSetFieldBit(tif, fip->field_bit);
+ tif->tif_flags |= TIFF_DIRTYDIRECT;
+ }
+
+@@ -572,12 +579,12 @@
+ return (status);
+ badvalue:
+ TIFFErrorExt(tif->tif_clientdata, module, "%s: Bad value %d for \"%s\"",
+- tif->tif_name, v, _TIFFFieldWithTag(tif, tag)->field_name);
++ tif->tif_name, v, fip ? fip->field_name : "Unknown");
+ va_end(ap);
+ return (0);
+ badvalue32:
+ TIFFErrorExt(tif->tif_clientdata, module, "%s: Bad value %ld for \"%s\"",
+- tif->tif_name, v32, _TIFFFieldWithTag(tif, tag)->field_name);
++ tif->tif_name, v32, fip ? fip->field_name : "Unknown");
+ va_end(ap);
+ return (0);
+ }
+@@ -813,12 +820,16 @@
+ * If the client tries to get a tag that is not valid
+ * for the image's codec then we'll arrive here.
+ */
++ /*
++ * dont dereference fip if it's NULL.
++ * -- taviso@google.com 15 Jun 2006
++ */
+ if( fip == NULL || fip->field_bit != FIELD_CUSTOM )
+ {
+ TIFFErrorExt(tif->tif_clientdata, "_TIFFVGetField",
+ "%s: Invalid %stag \"%s\" (not supported by codec)",
+ tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "",
+- _TIFFFieldWithTag(tif, tag)->field_name);
++ fip ? fip->field_name : "Unknown");
+ ret_val = 0;
+ break;
+ }
+--- ./libtiff/tif_pixarlog.c.orig 2006-03-21 10:42:50.000000000 -0600
++++ ./libtiff/tif_pixarlog.c 2006-08-17 22:02:40.000000000 -0500
+@@ -768,7 +768,19 @@
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabArrayOfShort(up, nsamples);
+
+- for (i = 0; i < nsamples; i += llen, up += llen) {
++ /*
++ * if llen is not an exact multiple of nsamples, the decode operation
++ * may overflow the output buffer, so truncate it enough to prevent that
++ * but still salvage as much data as possible.
++ * -- taviso@google.com 14th June 2006
++ */
++ if (nsamples % llen)
++ TIFFWarningExt(tif->tif_clientdata, module,
++ "%s: stride %lu is not a multiple of sample count, "
++ "%lu, data truncated.", tif->tif_name, llen, nsamples);
++
++
++ for (i = 0; i < nsamples - (nsamples % llen); i += llen, up += llen) {
+ switch (sp->user_datafmt) {
+ case PIXARLOGDATAFMT_FLOAT:
+ horizontalAccumulateF(up, llen, sp->stride,
+--- ./libtiff/tif_dirread.c.orig 2006-03-21 10:42:50.000000000 -0600
++++ ./libtiff/tif_dirread.c 2006-08-17 22:02:40.000000000 -0500
+@@ -29,6 +29,9 @@
+ *
+ * Directory Read Support Routines.
+ */
++
++#include <limits.h>
++
+ #include "tiffiop.h"
+
+ #define IGNORE 0 /* tag placeholder used below */
+@@ -81,6 +84,7 @@
+ uint16 dircount;
+ toff_t nextdiroff;
+ int diroutoforderwarning = 0;
++ int compressionknown = 0;
+ toff_t* new_dirlist;
+
+ tif->tif_diroff = tif->tif_nextdiroff;
+@@ -147,13 +151,20 @@
+ } else {
+ toff_t off = tif->tif_diroff;
+
+- if (off + sizeof (uint16) > tif->tif_size) {
+- TIFFErrorExt(tif->tif_clientdata, module,
+- "%s: Can not read TIFF directory count",
+- tif->tif_name);
+- return (0);
++ /*
++ * Check for integer overflow when validating the dir_off, otherwise
++ * a very high offset may cause an OOB read and crash the client.
++ * -- taviso@google.com, 14 Jun 2006.
++ */
++ if (off + sizeof (uint16) > tif->tif_size ||
++ off > (UINT_MAX - sizeof(uint16))) {
++ TIFFErrorExt(tif->tif_clientdata, module,
++ "%s: Can not read TIFF directory count",
++ tif->tif_name);
++ return (0);
+ } else
+- _TIFFmemcpy(&dircount, tif->tif_base + off, sizeof (uint16));
++ _TIFFmemcpy(&dircount, tif->tif_base + off,
++ sizeof (uint16));
+ off += sizeof (uint16);
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabShort(&dircount);
+@@ -254,6 +265,7 @@
+ while (fix < tif->tif_nfields &&
+ tif->tif_fieldinfo[fix]->field_tag < dp->tdir_tag)
+ fix++;
++
+ if (fix >= tif->tif_nfields ||
+ tif->tif_fieldinfo[fix]->field_tag != dp->tdir_tag) {
+
+@@ -264,17 +276,23 @@
+ 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.
++ * -- taviso@google.com 15 Jun 2006
++ */
++ if (compressionknown)
++ TIFFMergeFieldInfo(tif, _TIFFCreateAnonFieldInfo(tif, dp->tdir_tag,
++ (TIFFDataType) dp->tdir_type), 1 );
++ else goto ignore;
++
+ fix = 0;
+ while (fix < tif->tif_nfields &&
+ tif->tif_fieldinfo[fix]->field_tag < dp->tdir_tag)
+ fix++;
+ }
++
+ /*
+ * Null out old tags that we ignore.
+ */
+@@ -326,6 +344,7 @@
+ dp->tdir_type, dp->tdir_offset);
+ if (!TIFFSetField(tif, dp->tdir_tag, (uint16)v))
+ goto bad;
++ else compressionknown++;
+ break;
+ /* XXX: workaround for broken TIFFs */
+ } else if (dp->tdir_type == TIFF_LONG) {
+@@ -540,6 +559,7 @@
+ * Attempt to deal with a missing StripByteCounts tag.
+ */
+ if (!TIFFFieldSet(tif, FIELD_STRIPBYTECOUNTS)) {
++ const TIFFFieldInfo* fip = _TIFFFieldWithTag(tif, TIFFTAG_STRIPBYTECOUNTS);
+ /*
+ * Some manufacturers violate the spec by not giving
+ * the size of the strips. In this case, assume there
+@@ -556,7 +576,7 @@
+ "%s: TIFF directory is missing required "
+ "\"%s\" field, calculating from imagelength",
+ tif->tif_name,
+- _TIFFFieldWithTag(tif,TIFFTAG_STRIPBYTECOUNTS)->field_name);
++ fip ? fip->field_name : "Unknown");
+ if (EstimateStripByteCounts(tif, dir, dircount) < 0)
+ goto bad;
+ /*
+@@ -580,6 +600,7 @@
+ } else if (td->td_nstrips == 1
+ && td->td_stripoffset[0] != 0
+ && BYTECOUNTLOOKSBAD) {
++ const TIFFFieldInfo* fip = _TIFFFieldWithTag(tif, TIFFTAG_STRIPBYTECOUNTS);
+ /*
+ * XXX: Plexus (and others) sometimes give a value of zero for
+ * a tag when they don't know what the correct value is! Try
+@@ -589,13 +610,14 @@
+ TIFFWarningExt(tif->tif_clientdata, module,
+ "%s: Bogus \"%s\" field, ignoring and calculating from imagelength",
+ tif->tif_name,
+- _TIFFFieldWithTag(tif,TIFFTAG_STRIPBYTECOUNTS)->field_name);
++ fip ? fip->field_name : "Unknown");
+ if(EstimateStripByteCounts(tif, dir, dircount) < 0)
+ goto bad;
+ } else if (td->td_planarconfig == PLANARCONFIG_CONTIG
+ && td->td_nstrips > 2
+ && td->td_compression == COMPRESSION_NONE
+ && td->td_stripbytecount[0] != td->td_stripbytecount[1]) {
++ const TIFFFieldInfo* fip = _TIFFFieldWithTag(tif, TIFFTAG_STRIPBYTECOUNTS);
+ /*
+ * XXX: Some vendors fill StripByteCount array with absolutely
+ * wrong values (it can be equal to StripOffset array, for
+@@ -604,7 +626,7 @@
+ TIFFWarningExt(tif->tif_clientdata, module,
+ "%s: Wrong \"%s\" field, ignoring and calculating from imagelength",
+ tif->tif_name,
+- _TIFFFieldWithTag(tif,TIFFTAG_STRIPBYTECOUNTS)->field_name);
++ fip ? fip->field_name : "Unknown");
+ if (EstimateStripByteCounts(tif, dir, dircount) < 0)
+ goto bad;
+ }
+@@ -870,7 +892,13 @@
+
+ register TIFFDirEntry *dp;
+ register TIFFDirectory *td = &tif->tif_dir;
+- uint16 i;
++
++ /* i is used to iterate over td->td_nstrips, so must be
++ * at least the same width.
++ * -- taviso@google.com 15 Jun 2006
++ */
++
++ uint32 i;
+
+ if (td->td_stripbytecount)
+ _TIFFfree(td->td_stripbytecount);
+@@ -947,16 +975,18 @@
+ static int
+ CheckDirCount(TIFF* tif, TIFFDirEntry* dir, uint32 count)
+ {
++ const TIFFFieldInfo* fip = _TIFFFieldWithTag(tif, dir->tdir_tag);
++
+ 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,
++ fip ? fip->field_name : "Unknown",
+ 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,
++ fip ? fip->field_name : "Unknown",
+ dir->tdir_count, count);
+ return (1);
+ }
+@@ -970,6 +1000,7 @@
+ TIFFFetchData(TIFF* tif, TIFFDirEntry* dir, char* cp)
+ {
+ int w = TIFFDataWidth((TIFFDataType) dir->tdir_type);
++ const TIFFFieldInfo* fip = _TIFFFieldWithTag(tif, dir->tdir_tag);
+ tsize_t cc = dir->tdir_count * w;
+
+ /* Check for overflow. */
+@@ -1013,7 +1044,7 @@
+ bad:
+ TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+ "Error fetching data for field \"%s\"",
+- _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name);
++ fip ? fip->field_name : "Unknown");
+ return (tsize_t) 0;
+ }
+
+@@ -1039,10 +1070,12 @@
+ static int
+ cvtRational(TIFF* tif, TIFFDirEntry* dir, uint32 num, uint32 denom, float* rv)
+ {
++ const TIFFFieldInfo* fip;
+ if (denom == 0) {
++ fip = _TIFFFieldWithTag(tif, dir->tdir_tag);
+ TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+ "%s: Rational with zero denominator (num = %lu)",
+- _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name, num);
++ fip ? fip->field_name : "Unknown", num);
+ return (0);
+ } else {
+ if (dir->tdir_type == TIFF_RATIONAL)
+@@ -1159,6 +1192,20 @@
+ static int
+ TIFFFetchShortPair(TIFF* tif, TIFFDirEntry* dir)
+ {
++ /*
++ * Prevent overflowing the v stack arrays below by performing a sanity
++ * check on tdir_count, this should never be greater than two.
++ * -- taviso@google.com 14 Jun 2006.
++ */
++ if (dir->tdir_count > 2) {
++ const TIFFFieldInfo* fip = _TIFFFieldWithTag(tif, dir->tdir_tag);
++ TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
++ "unexpected count for field \"%s\", %lu, expected 2; ignored.",
++ fip ? fip->field_name : "Unknown",
++ dir->tdir_count);
++ return 0;
++ }
++
+ switch (dir->tdir_type) {
+ case TIFF_BYTE:
+ case TIFF_SBYTE:
+@@ -1329,14 +1376,15 @@
+ case TIFF_DOUBLE:
+ return (TIFFFetchDoubleArray(tif, dir, (double*) v));
+ default:
++ { const TIFFFieldInfo* fip = _TIFFFieldWithTag(tif, dir->tdir_tag);
+ /* TIFF_NOTYPE */
+ /* TIFF_ASCII */
+ /* TIFF_UNDEFINED */
+ TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+ "cannot read TIFF_ANY type %d for field \"%s\"",
+ dir->tdir_type,
+- _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name);
+- return (0);
++ fip ? fip->field_name : "Unknown");
++ return (0); }
+ }
+ return (1);
+ }
+@@ -1351,6 +1399,9 @@
+ int ok = 0;
+ const TIFFFieldInfo* fip = _TIFFFieldWithTag(tif, dp->tdir_tag);
+
++ if (fip == NULL) {
++ return (0);
++ }
+ if (dp->tdir_count > 1) { /* array of values */
+ char* cp = NULL;
+
+@@ -1493,6 +1544,7 @@
+ TIFFFetchPerSampleShorts(TIFF* tif, TIFFDirEntry* dir, uint16* pl)
+ {
+ uint16 samples = tif->tif_dir.td_samplesperpixel;
++ const TIFFFieldInfo* fip;
+ int status = 0;
+
+ if (CheckDirCount(tif, dir, (uint32) samples)) {
+@@ -1510,9 +1562,10 @@
+
+ for (i = 1; i < check_count; i++)
+ if (v[i] != v[0]) {
++ fip = _TIFFFieldWithTag(tif, dir->tdir_tag);
+ TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+ "Cannot handle different per-sample values for field \"%s\"",
+- _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name);
++ fip ? fip->field_name : "Unknown");
+ goto bad;
+ }
+ *pl = v[0];
+@@ -1534,6 +1587,7 @@
+ TIFFFetchPerSampleLongs(TIFF* tif, TIFFDirEntry* dir, uint32* pl)
+ {
+ uint16 samples = tif->tif_dir.td_samplesperpixel;
++ const TIFFFieldInfo* fip;
+ int status = 0;
+
+ if (CheckDirCount(tif, dir, (uint32) samples)) {
+@@ -1551,9 +1605,10 @@
+ check_count = samples;
+ for (i = 1; i < check_count; i++)
+ if (v[i] != v[0]) {
++ fip = _TIFFFieldWithTag(tif, dir->tdir_tag);
+ TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+ "Cannot handle different per-sample values for field \"%s\"",
+- _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name);
++ fip ? fip->field_name : "Unknown");
+ goto bad;
+ }
+ *pl = v[0];
+@@ -1574,6 +1629,7 @@
+ TIFFFetchPerSampleAnys(TIFF* tif, TIFFDirEntry* dir, double* pl)
+ {
+ uint16 samples = tif->tif_dir.td_samplesperpixel;
++ const TIFFFieldInfo* fip;
+ int status = 0;
+
+ if (CheckDirCount(tif, dir, (uint32) samples)) {
+@@ -1591,9 +1647,10 @@
+
+ for (i = 1; i < check_count; i++)
+ if (v[i] != v[0]) {
++ fip = _TIFFFieldWithTag(tif, dir->tdir_tag);
+ TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+ "Cannot handle different per-sample values for field \"%s\"",
+- _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name);
++ fip ? fip->field_name : "Unknown");
+ goto bad;
+ }
+ *pl = v[0];
+--- ./libtiff/tif_dirinfo.c.orig 2006-02-07 07:51:03.000000000 -0600
++++ ./libtiff/tif_dirinfo.c 2006-08-17 22:02:40.000000000 -0500
+@@ -775,7 +775,8 @@
+ TIFFErrorExt(tif->tif_clientdata, "TIFFFieldWithTag",
+ "Internal error, unknown tag 0x%x",
+ (unsigned int) tag);
+- assert(fip != NULL);
++ /* assert(fip != NULL); */
++
+ /*NOTREACHED*/
+ }
+ return (fip);
+@@ -789,7 +790,8 @@
+ if (!fip) {
+ TIFFErrorExt(tif->tif_clientdata, "TIFFFieldWithName",
+ "Internal error, unknown tag %s", field_name);
+- assert(fip != NULL);
++ /* assert(fip != NULL); */
++
+ /*NOTREACHED*/
+ }
+ return (fip);
+--- ./libtiff/tif_fax3.c.orig 2006-03-21 10:42:50.000000000 -0600
++++ ./libtiff/tif_fax3.c 2006-08-17 22:02:40.000000000 -0500
+@@ -1136,6 +1136,7 @@
+ Fax3VSetField(TIFF* tif, ttag_t tag, va_list ap)
+ {
+ Fax3BaseState* sp = Fax3State(tif);
++ const TIFFFieldInfo* fip;
+
+ assert(sp != 0);
+ assert(sp->vsetparent != 0);
+@@ -1181,7 +1182,13 @@
+ default:
+ return (*sp->vsetparent)(tif, tag, ap);
+ }
+- TIFFSetFieldBit(tif, _TIFFFieldWithTag(tif, tag)->field_bit);
++
++ if ((fip = _TIFFFieldWithTag(tif, tag))) {
++ TIFFSetFieldBit(tif, fip->field_bit);
++ } else {
++ return (0);
++ }
++
+ tif->tif_flags |= TIFF_DIRTYDIRECT;
+ return (1);
+ }