summaryrefslogtreecommitdiff
path: root/source/l/libtiff/tiff-3.8.2.goo-sec.diff
diff options
context:
space:
mode:
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 00000000..a5f9e6d5
--- /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);
+ }