diff -uprk.orig tiff-v3.5.7.orig/libtiff/tif_aux.c tiff-v3.5.7/libtiff/tif_aux.c --- tiff-v3.5.7.orig/libtiff/tif_aux.c 2000-03-03 18:22:00 +0300 +++ tiff-v3.5.7/libtiff/tif_aux.c 2004-10-04 00:54:12 +0400 @@ -34,36 +34,59 @@ #ifdef COLORIMETRY_SUPPORT #include <math.h> -static void +static int TIFFDefaultTransferFunction(TIFFDirectory* td) { uint16 **tf = td->td_transferfunction; - long i, n = 1<<td->td_bitspersample; + tsize_t i, n, nbytes; - tf[0] = (uint16 *)_TIFFmalloc(n * sizeof (uint16)); + tf[0] = tf[1] = tf[2] = 0; + if (td->td_bitspersample >= sizeof(tsize_t) * 8 - 2) + return 0; + + n = 1<<td->td_bitspersample; + nbytes = n * sizeof (uint16); + if (!(tf[0] = (uint16 *)_TIFFmalloc(nbytes))) + return 0; tf[0][0] = 0; for (i = 1; i < n; i++) { double t = (double)i/((double) n-1.); tf[0][i] = (uint16)floor(65535.*pow(t, 2.2) + .5); } + if (td->td_samplesperpixel - td->td_extrasamples > 1) { - tf[1] = (uint16 *)_TIFFmalloc(n * sizeof (uint16)); - _TIFFmemcpy(tf[1], tf[0], n * sizeof (uint16)); - tf[2] = (uint16 *)_TIFFmalloc(n * sizeof (uint16)); - _TIFFmemcpy(tf[2], tf[0], n * sizeof (uint16)); + if (!(tf[1] = (uint16 *)_TIFFmalloc(nbytes))) + goto bad; + _TIFFmemcpy(tf[1], tf[0], nbytes); + if (!(tf[2] = (uint16 *)_TIFFmalloc(nbytes))) + goto bad; + _TIFFmemcpy(tf[2], tf[0], nbytes); } + return 1; + +bad: + if (tf[0]) + _TIFFfree(tf[0]); + if (tf[1]) + _TIFFfree(tf[1]); + if (tf[2]) + _TIFFfree(tf[2]); + tf[0] = tf[1] = tf[2] = 0; + return 0; } -static void +static int TIFFDefaultRefBlackWhite(TIFFDirectory* td) { int i; - td->td_refblackwhite = (float *)_TIFFmalloc(6*sizeof (float)); + if (!(td->td_refblackwhite = (float *)_TIFFmalloc(6*sizeof (float)))) + return 0; for (i = 0; i < 3; i++) { td->td_refblackwhite[2*i+0] = 0; td->td_refblackwhite[2*i+1] = (float)((1L<<td->td_bitspersample)-1L); } + return 1; } #endif @@ -154,6 +177,8 @@ TIFFVGetFieldDefaulted(TIFF* tif, ttag_t if (!td->td_ycbcrcoeffs) { td->td_ycbcrcoeffs = (float *) _TIFFmalloc(3*sizeof (float)); + if (!td->td_ycbcrcoeffs) + return (0); /* defaults are from CCIR Recommendation 601-1 */ td->td_ycbcrcoeffs[0] = 0.299f; td->td_ycbcrcoeffs[1] = 0.587f; @@ -171,8 +196,11 @@ TIFFVGetFieldDefaulted(TIFF* tif, ttag_t #endif #ifdef COLORIMETRY_SUPPORT case TIFFTAG_TRANSFERFUNCTION: - if (!td->td_transferfunction[0]) - TIFFDefaultTransferFunction(td); + if (!td->td_transferfunction[0] && + !TIFFDefaultTransferFunction(td)) { + TIFFError(tif->tif_name, "No space for \"TransferFunction\" tag"); + return (0); + } *va_arg(ap, uint16 **) = td->td_transferfunction[0]; if (td->td_samplesperpixel - td->td_extrasamples > 1) { *va_arg(ap, uint16 **) = td->td_transferfunction[1]; @@ -180,8 +208,8 @@ TIFFVGetFieldDefaulted(TIFF* tif, ttag_t } return (1); case TIFFTAG_REFERENCEBLACKWHITE: - if (!td->td_refblackwhite) - TIFFDefaultRefBlackWhite(td); + if (!td->td_refblackwhite && !TIFFDefaultRefBlackWhite(td)) + return (0); *va_arg(ap, float **) = td->td_refblackwhite; return (1); #endif diff -uprk.orig tiff-v3.5.7.orig/libtiff/tif_compress.c tiff-v3.5.7/libtiff/tif_compress.c --- tiff-v3.5.7.orig/libtiff/tif_compress.c 1999-12-21 20:03:03 +0300 +++ tiff-v3.5.7/libtiff/tif_compress.c 2004-10-04 00:54:12 +0400 @@ -208,9 +208,11 @@ TIFFRegisterCODEC(uint16 scheme, const c cd->info->init = init; cd->next = registeredCODECS; registeredCODECS = cd; - } else + } else { TIFFError("TIFFRegisterCODEC", "No space to register compression scheme %s", name); + return NULL; + } return (cd->info); } diff -uprk.orig tiff-v3.5.7.orig/libtiff/tif_dir.c tiff-v3.5.7/libtiff/tif_dir.c --- tiff-v3.5.7.orig/libtiff/tif_dir.c 2001-09-25 05:33:54 +0400 +++ tiff-v3.5.7/libtiff/tif_dir.c 2004-10-04 00:54:12 +0400 @@ -40,26 +40,33 @@ #define DATATYPE_UINT 2 /* !unsigned integer data */ #define DATATYPE_IEEEFP 3 /* !IEEE floating point data */ -void -_TIFFsetByteArray(void** vpp, void* vp, long n) +static void +setByteArray(void** vpp, void* vp, size_t nmemb, size_t elem_size) { if (*vpp) _TIFFfree(*vpp), *vpp = 0; - if (vp && (*vpp = (void*) _TIFFmalloc(n))) - _TIFFmemcpy(*vpp, vp, n); + if (vp) { + tsize_t bytes = nmemb * elem_size; + if (elem_size && bytes / elem_size == nmemb) + *vpp = (void*) _TIFFmalloc(bytes); + if (*vpp) + _TIFFmemcpy(*vpp, vp, bytes); + } } +void _TIFFsetByteArray(void** vpp, void* vp, long n) + { setByteArray(vpp, vp, n, 1); } void _TIFFsetString(char** cpp, char* cp) - { _TIFFsetByteArray((void**) cpp, (void*) cp, (long) (strlen(cp)+1)); } + { setByteArray((void**) cpp, (void*) cp, strlen(cp)+1, 1); } void _TIFFsetNString(char** cpp, char* cp, long n) - { _TIFFsetByteArray((void**) cpp, (void*) cp, n); } + { setByteArray((void**) cpp, (void*) cp, n, 1); } void _TIFFsetShortArray(uint16** wpp, uint16* wp, long n) - { _TIFFsetByteArray((void**) wpp, (void*) wp, n*sizeof (uint16)); } + { setByteArray((void**) wpp, (void*) wp, n, sizeof (uint16)); } void _TIFFsetLongArray(uint32** lpp, uint32* lp, long n) - { _TIFFsetByteArray((void**) lpp, (void*) lp, n*sizeof (uint32)); } + { setByteArray((void**) lpp, (void*) lp, n, sizeof (uint32)); } void _TIFFsetFloatArray(float** fpp, float* fp, long n) - { _TIFFsetByteArray((void**) fpp, (void*) fp, n*sizeof (float)); } + { setByteArray((void**) fpp, (void*) fp, n, sizeof (float)); } void _TIFFsetDoubleArray(double** dpp, double* dp, long n) - { _TIFFsetByteArray((void**) dpp, (void*) dp, n*sizeof (double)); } + { setByteArray((void**) dpp, (void*) dp, n, sizeof (double)); } /* * Install extra samples information. diff -uprk.orig tiff-v3.5.7.orig/libtiff/tif_dirinfo.c tiff-v3.5.7/libtiff/tif_dirinfo.c --- tiff-v3.5.7.orig/libtiff/tif_dirinfo.c 2001-05-09 05:33:16 +0400 +++ tiff-v3.5.7/libtiff/tif_dirinfo.c 2004-10-04 00:54:12 +0400 @@ -31,6 +31,8 @@ */ #include "tiffiop.h" #include <stdlib.h> +#include <assert.h> +#include <stdio.h> /* * NB: NB: THIS ARRAY IS ASSUMED TO BE SORTED BY TAG. @@ -301,6 +303,7 @@ _TIFFMergeFieldInfo(TIFF* tif, const TIF tif->tif_fieldinfo = (TIFFFieldInfo**) _TIFFmalloc(n * sizeof (TIFFFieldInfo*)); } + assert(tif->tif_fieldinfo != NULL); tp = &tif->tif_fieldinfo[tif->tif_nfields]; for (i = 0; i < n; i++) tp[i] = (TIFFFieldInfo*) &info[i]; /* XXX */ @@ -357,7 +360,7 @@ const int tiffDataWidth[] = { TIFFDataType _TIFFSampleToTagType(TIFF* tif) { - int bps = (int) TIFFhowmany(tif->tif_dir.td_bitspersample, 8); + uint32 bps = TIFFhowmany8(tif->tif_dir.td_bitspersample); switch (tif->tif_dir.td_sampleformat) { case SAMPLEFORMAT_IEEEFP: @@ -394,9 +397,6 @@ _TIFFFindFieldInfo(TIFF* tif, ttag_t tag return ((const TIFFFieldInfo *)0); } -#include <assert.h> -#include <stdio.h> - const TIFFFieldInfo* _TIFFFieldWithTag(TIFF* tif, ttag_t tag) { diff -uprk.orig tiff-v3.5.7.orig/libtiff/tif_dirread.c tiff-v3.5.7/libtiff/tif_dirread.c --- tiff-v3.5.7.orig/libtiff/tif_dirread.c 2001-05-22 18:15:18 +0400 +++ tiff-v3.5.7/libtiff/tif_dirread.c 2004-10-04 01:29:52 +0400 @@ -62,11 +62,17 @@ static int TIFFFetchShortPair(TIFF*, TIF static void ChopUpSingleUncompressedStrip(TIFF*); static char * -CheckMalloc(TIFF* tif, tsize_t n, const char* what) +CheckMalloc(TIFF* tif, size_t nmemb, size_t elem_size, const char* what) { - char *cp = (char*)_TIFFmalloc(n); + char *cp = NULL; + tsize_t bytes = nmemb * elem_size; + + if (elem_size && bytes / elem_size == nmemb) + cp = (char*)_TIFFmalloc(bytes); + if (cp == NULL) TIFFError(tif->tif_name, "No space %s", what); + return (cp); } @@ -115,7 +121,7 @@ TIFFReadDirectory(TIFF* tif) if (tif->tif_flags & TIFF_SWAB) TIFFSwabShort(&dircount); dir = (TIFFDirEntry *)CheckMalloc(tif, - dircount * sizeof (TIFFDirEntry), "to read TIFF directory"); + dircount, sizeof (TIFFDirEntry), "to read TIFF directory"); if (dir == NULL) return (0); if (!ReadOK(tif, dir, dircount*sizeof (TIFFDirEntry))) { @@ -139,15 +145,16 @@ TIFFReadDirectory(TIFF* tif) if (tif->tif_flags & TIFF_SWAB) TIFFSwabShort(&dircount); dir = (TIFFDirEntry *)CheckMalloc(tif, - dircount * sizeof (TIFFDirEntry), "to read TIFF directory"); + dircount, sizeof (TIFFDirEntry), "to read TIFF directory"); if (dir == NULL) return (0); if (off + dircount*sizeof (TIFFDirEntry) > tif->tif_size) { TIFFError(tif->tif_name, "Can not read TIFF directory"); goto bad; - } else + } else { _TIFFmemcpy(dir, tif->tif_base + off, - dircount*sizeof (TIFFDirEntry)); + dircount*sizeof (TIFFDirEntry)); + } off += dircount* sizeof (TIFFDirEntry); if (off + sizeof (uint32) <= tif->tif_size) _TIFFmemcpy(&nextdiroff, tif->tif_base+off, sizeof (uint32)); @@ -350,6 +357,11 @@ TIFFReadDirectory(TIFF* tif) td->td_nstrips = TIFFNumberOfTiles(tif); tif->tif_flags |= TIFF_ISTILED; } + if (!td->td_nstrips) { + TIFFError("TIFFReadDirectory", "%s: cannot handle zero number of %s", + tif->tif_name, isTiled(tif) ? "tiles" : "strips"); + goto bad; + } td->td_stripsperimage = td->td_nstrips; if (td->td_planarconfig == PLANARCONFIG_SEPARATE) td->td_stripsperimage /= td->td_samplesperpixel; @@ -426,7 +438,7 @@ TIFFReadDirectory(TIFF* tif) break; } v *= sizeof (uint16); - cp = CheckMalloc(tif, dp->tdir_count * sizeof (uint16), + cp = CheckMalloc(tif, dp->tdir_count, sizeof (uint16), "to read \"TransferFunction\" tag"); if (cp != NULL) { if (TIFFFetchData(tif, dp, cp)) { @@ -522,8 +534,10 @@ TIFFReadDirectory(TIFF* tif) _TIFFFieldWithTag(tif,TIFFTAG_STRIPBYTECOUNTS)->field_name); EstimateStripByteCounts(tif, dir, dircount); } - if (dir) + if (dir) { _TIFFfree((char *)dir); + dir = NULL; + } if (!TIFFFieldSet(tif, FIELD_MAXSAMPLEVALUE)) td->td_maxsamplevalue = (uint16)((1L<<td->td_bitspersample)-1); /* @@ -552,6 +566,17 @@ TIFFReadDirectory(TIFF* tif) tif->tif_curtile = (ttile_t) -1; tif->tif_tilesize = TIFFTileSize(tif); tif->tif_scanlinesize = TIFFScanlineSize(tif); + + if (!tif->tif_tilesize) { + TIFFError("TIFFReadDirectory", "%s: cannot handle zero tile size", + tif->tif_name); + return (0); + } + if (!tif->tif_scanlinesize) { + TIFFError("TIFFReadDirectory", "%s: cannot handle zero scanline size", + tif->tif_name); + return (0); + } return (1); bad: if (dir) @@ -569,7 +594,7 @@ EstimateStripByteCounts(TIFF* tif, TIFFD if (td->td_stripbytecount) _TIFFfree(td->td_stripbytecount); td->td_stripbytecount = (uint32*) - CheckMalloc(tif, td->td_nstrips * sizeof (uint32), + CheckMalloc(tif, td->td_nstrips, sizeof (uint32), "for \"StripByteCounts\" array"); if (td->td_compression != COMPRESSION_NONE) { uint32 space = (uint32)(sizeof (TIFFHeader) @@ -850,7 +875,7 @@ TIFFFetchRationalArray(TIFF* tif, TIFFDi uint32* l; l = (uint32*)CheckMalloc(tif, - dir->tdir_count*tiffDataWidth[dir->tdir_type], + dir->tdir_count, tiffDataWidth[dir->tdir_type], "to fetch array of rationals"); if (l) { if (TIFFFetchData(tif, dir, (char *)l)) { @@ -1006,35 +1031,35 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEnt case TIFF_SBYTE: /* NB: always expand BYTE values to shorts */ cp = CheckMalloc(tif, - dp->tdir_count * sizeof (uint16), mesg); + dp->tdir_count, sizeof (uint16), mesg); ok = cp && TIFFFetchByteArray(tif, dp, (uint16*) cp); break; case TIFF_SHORT: case TIFF_SSHORT: cp = CheckMalloc(tif, - dp->tdir_count * sizeof (uint16), mesg); + dp->tdir_count, sizeof (uint16), mesg); ok = cp && TIFFFetchShortArray(tif, dp, (uint16*) cp); break; case TIFF_LONG: case TIFF_SLONG: cp = CheckMalloc(tif, - dp->tdir_count * sizeof (uint32), mesg); + dp->tdir_count, sizeof (uint32), mesg); ok = cp && TIFFFetchLongArray(tif, dp, (uint32*) cp); break; case TIFF_RATIONAL: case TIFF_SRATIONAL: cp = CheckMalloc(tif, - dp->tdir_count * sizeof (float), mesg); + dp->tdir_count, sizeof (float), mesg); ok = cp && TIFFFetchRationalArray(tif, dp, (float*) cp); break; case TIFF_FLOAT: cp = CheckMalloc(tif, - dp->tdir_count * sizeof (float), mesg); + dp->tdir_count, sizeof (float), mesg); ok = cp && TIFFFetchFloatArray(tif, dp, (float*) cp); break; case TIFF_DOUBLE: cp = CheckMalloc(tif, - dp->tdir_count * sizeof (double), mesg); + dp->tdir_count, sizeof (double), mesg); ok = cp && TIFFFetchDoubleArray(tif, dp, (double*) cp); break; case TIFF_ASCII: @@ -1043,7 +1068,7 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEnt * Some vendors write strings w/o the trailing * NULL byte, so always append one just in case. */ - cp = CheckMalloc(tif, dp->tdir_count+1, mesg); + cp = CheckMalloc(tif, dp->tdir_count+1, 1, mesg); if( (ok = (cp && TIFFFetchString(tif, dp, cp))) != 0 ) cp[dp->tdir_count] = '\0'; /* XXX */ break; @@ -1145,8 +1170,9 @@ TIFFFetchPerSampleShorts(TIFF* tif, TIFF uint16* v = buf; if (samples > NITEMS(buf)) - v = (uint16*) _TIFFmalloc(samples * sizeof (uint16)); - if (TIFFFetchShortArray(tif, dir, v)) { + v = (uint16*) CheckMalloc(tif, samples, sizeof (uint16), + "to fetch per-sample values"); + if (v && TIFFFetchShortArray(tif, dir, v)) { int i; for (i = 1; i < samples; i++) if (v[i] != v[0]) { @@ -1159,7 +1185,7 @@ TIFFFetchPerSampleShorts(TIFF* tif, TIFF status = 1; } bad: - if (v != buf) + if (v && v != buf) _TIFFfree((char*) v); } return (status); @@ -1181,8 +1207,9 @@ TIFFFetchPerSampleAnys(TIFF* tif, TIFFDi double* v = buf; if (samples > NITEMS(buf)) - v = (double*) _TIFFmalloc(samples * sizeof (double)); - if (TIFFFetchAnyArray(tif, dir, v)) { + v = (double*) CheckMalloc(tif, samples, sizeof (double), + "to fetch per-sample values"); + if (v && TIFFFetchAnyArray(tif, dir, v)) { int i; for (i = 1; i < samples; i++) if (v[i] != v[0]) { @@ -1195,7 +1222,7 @@ TIFFFetchPerSampleAnys(TIFF* tif, TIFFDi status = 1; } bad: - if (v != buf) + if (v && v != buf) _TIFFfree(v); } return (status); @@ -1220,7 +1247,7 @@ TIFFFetchStripThing(TIFF* tif, TIFFDirEn */ if (*lpp == NULL && (*lpp = (uint32 *)CheckMalloc(tif, - nstrips * sizeof (uint32), "for strip array")) == NULL) + nstrips, sizeof (uint32), "for strip array")) == NULL) return (0); lp = *lpp; if (dir->tdir_type == (int)TIFF_SHORT) { @@ -1228,7 +1255,7 @@ TIFFFetchStripThing(TIFF* tif, TIFFDirEn * Handle uint16->uint32 expansion. */ uint16* dp = (uint16*) CheckMalloc(tif, - dir->tdir_count* sizeof (uint16), "to fetch strip tag"); + dir->tdir_count, sizeof (uint16), "to fetch strip tag"); if (dp == NULL) return (0); if( (status = TIFFFetchShortArray(tif, dir, dp)) != 0 ) { @@ -1253,8 +1280,12 @@ TIFFFetchExtraSamples(TIFF* tif, TIFFDir uint16* v = buf; int status; - if (dir->tdir_count > NITEMS(buf)) - v = (uint16*) _TIFFmalloc(dir->tdir_count * sizeof (uint16)); + if (dir->tdir_count > NITEMS(buf)) { + v = (uint16*) CheckMalloc(tif, dir->tdir_count, sizeof (uint16), + "to fetch extra samples"); + if (!v) + return (0); + } if (dir->tdir_type == TIFF_BYTE) status = TIFFFetchByteArray(tif, dir, v); else @@ -1283,10 +1314,10 @@ TIFFFetchRefBlackWhite(TIFF* tif, TIFFDi /* * Handle LONG's for backward compatibility. */ - cp = CheckMalloc(tif, dir->tdir_count * sizeof (uint32), mesg); + cp = CheckMalloc(tif, dir->tdir_count, sizeof (uint32), mesg); if( (ok = (cp && TIFFFetchLongArray(tif, dir, (uint32*) cp))) != 0) { float* fp = (float*) - CheckMalloc(tif, dir->tdir_count * sizeof (float), mesg); + CheckMalloc(tif, dir->tdir_count, sizeof (float), mesg); if( (ok = (fp != NULL)) != 0 ) { uint32 i; for (i = 0; i < dir->tdir_count; i++) @@ -1334,9 +1365,9 @@ ChopUpSingleUncompressedStrip(TIFF* tif) if (rowsperstrip >= td->td_rowsperstrip) return; nstrips = (tstrip_t) TIFFhowmany(bytecount, stripbytes); - newcounts = (uint32*) CheckMalloc(tif, nstrips * sizeof (uint32), + newcounts = (uint32*) CheckMalloc(tif, nstrips, sizeof (uint32), "for chopped \"StripByteCounts\" array"); - newoffsets = (uint32*) CheckMalloc(tif, nstrips * sizeof (uint32), + newoffsets = (uint32*) CheckMalloc(tif, nstrips, sizeof (uint32), "for chopped \"StripOffsets\" array"); if (newcounts == NULL || newoffsets == NULL) { /* diff -uprk.orig tiff-v3.5.7.orig/libtiff/tif_dirwrite.c tiff-v3.5.7/libtiff/tif_dirwrite.c --- tiff-v3.5.7.orig/libtiff/tif_dirwrite.c 2001-09-26 21:42:18 +0400 +++ tiff-v3.5.7/libtiff/tif_dirwrite.c 2004-10-04 01:16:49 +0400 @@ -564,8 +564,14 @@ TIFFWritePerSampleShorts(TIFF* tif, ttag uint16* w = buf; int i, status, samples = tif->tif_dir.td_samplesperpixel; - if (samples > NITEMS(buf)) + if (samples > NITEMS(buf)) { w = (uint16*) _TIFFmalloc(samples * sizeof (uint16)); + if (w == NULL) { + TIFFError(tif->tif_name, + "No space to write per-sample shorts"); + return (0); + } + } TIFFGetField(tif, tag, &v); for (i = 0; i < samples; i++) w[i] = v; @@ -589,8 +595,14 @@ TIFFWritePerSampleAnys(TIFF* tif, int i, status; int samples = (int) tif->tif_dir.td_samplesperpixel; - if (samples > NITEMS(buf)) + if (samples > NITEMS(buf)) { w = (double*) _TIFFmalloc(samples * sizeof (double)); + if (w == NULL) { + TIFFError(tif->tif_name, + "No space to write per-sample values"); + return (0); + } + } TIFFGetField(tif, tag, &v); for (i = 0; i < samples; i++) w[i] = v; @@ -712,6 +724,11 @@ TIFFWriteRationalArray(TIFF* tif, dir->tdir_type = (short) type; dir->tdir_count = n; t = (uint32*) _TIFFmalloc(2*n * sizeof (uint32)); + if (t == NULL) { + TIFFError(tif->tif_name, + "No space to write RATIONAL array"); + return (0); + } for (i = 0; i < n; i++) { float fv = v[i]; int sign = 1; @@ -782,8 +799,13 @@ TIFFWriteAnyArray(TIFF* tif, char* w = buf; int i, status = 0; - if (n * tiffDataWidth[type] > sizeof buf) + if (n * tiffDataWidth[type] > sizeof buf) { w = (char*) _TIFFmalloc(n * tiffDataWidth[type]); + if (w == NULL) { + TIFFError(tif->tif_name, "No space to write array"); + return (0); + } + } switch (type) { case TIFF_BYTE: { uint8* bp = (uint8*) w; diff -uprk.orig tiff-v3.5.7.orig/libtiff/tif_fax3.c tiff-v3.5.7/libtiff/tif_fax3.c --- tiff-v3.5.7.orig/libtiff/tif_fax3.c 2001-09-09 20:10:37 +0400 +++ tiff-v3.5.7/libtiff/tif_fax3.c 2004-10-04 01:19:18 +0400 @@ -443,6 +443,21 @@ _TIFFFax3fillruns(u_char* buf, uint32* r #undef ZERO #undef FILL +static char * +CheckMalloc(TIFF* tif, size_t nmemb, size_t elem_size, const char* what) +{ + char *cp = NULL; + tsize_t bytes = nmemb * elem_size; + + if (elem_size && bytes / elem_size == nmemb) + cp = (char*) _TIFFmalloc(bytes); + + if (cp == NULL) + TIFFError(tif->tif_name, "No space %s", what); + + return (cp); +} + /* * Setup G3/G4-related compression/decompression state * before data is processed. This routine is called once @@ -487,13 +502,10 @@ Fax3SetupState(TIFF* tif) uint32 nruns = needsRefLine ? 2*TIFFroundup(rowpixels,32) : rowpixels; - dsp->runs = (uint32*) _TIFFmalloc((2*nruns+3)*sizeof (uint32)); - if (dsp->runs == NULL) { - TIFFError("Fax3SetupState", - "%s: No space for Group 3/4 run arrays", - tif->tif_name); + dsp->runs = (uint32*) CheckMalloc(tif, 2*nruns+3, sizeof (uint32), + "for Group 3/4 run arrays"); + if (dsp->runs == NULL) return (0); - } dsp->curruns = dsp->runs; if (needsRefLine) dsp->refruns = dsp->runs + (nruns>>1); diff -uprk.orig tiff-v3.5.7.orig/libtiff/tiffiop.h tiff-v3.5.7/libtiff/tiffiop.h --- tiff-v3.5.7.orig/libtiff/tiffiop.h 2000-01-28 23:56:59 +0300 +++ tiff-v3.5.7/libtiff/tiffiop.h 2004-10-04 00:55:05 +0400 @@ -192,8 +192,9 @@ struct tiff { #endif /* NB: the uint32 casts are to silence certain ANSI-C compilers */ -#define TIFFhowmany(x, y) ((((uint32)(x))+(((uint32)(y))-1))/((uint32)(y))) -#define TIFFroundup(x, y) (TIFFhowmany(x,y)*((uint32)(y))) +#define TIFFhowmany(x, y) ((((uint32)(x))+(((uint32)(y))-1))/((uint32)(y))) +#define TIFFhowmany8(x) (((x)&0x07)?((uint32)(x)>>3)+1:(uint32)(x)>>3) +#define TIFFroundup(x, y) (TIFFhowmany(x,y)*(y)) #if defined(__cplusplus) extern "C" { diff -uprk.orig tiff-v3.5.7.orig/libtiff/tif_getimage.c tiff-v3.5.7/libtiff/tif_getimage.c --- tiff-v3.5.7.orig/libtiff/tif_getimage.c 2001-09-24 23:40:37 +0400 +++ tiff-v3.5.7/libtiff/tif_getimage.c 2004-10-04 01:22:05 +0400 @@ -467,6 +467,7 @@ gtTileContig(TIFFRGBAImage* img, uint32* TIFFError(TIFFFileName(tif), "No space for tile buffer"); return (0); } + _TIFFmemset(buf, 0, TIFFTileSize(tif)); TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw); TIFFGetField(tif, TIFFTAG_TILELENGTH, &th); y = setorientation(img, h); @@ -542,6 +543,7 @@ gtTileSeparate(TIFFRGBAImage* img, uint3 TIFFError(TIFFFileName(tif), "No space for tile buffer"); return (0); } + _TIFFmemset(buf, 0, 4*tilesize); r = buf; g = r + tilesize; b = g + tilesize; @@ -597,9 +599,7 @@ gtTileSeparate(TIFFRGBAImage* img, uint3 (*put)(img, raster+y*w+col, col, y, npix, nrow, fromskew, toskew + fromskew, r + pos, g + pos, b + pos, a + pos); - } - else - { + } else { (*put)(img, raster+y*w+col, col, y, tw, nrow, 0, toskew, r + pos, g + pos, b + pos, a + pos); } @@ -637,6 +637,7 @@ gtStripContig(TIFFRGBAImage* img, uint32 TIFFError(TIFFFileName(tif), "No space for strip buffer"); return (0); } + _TIFFmemset(buf, 0, TIFFStripSize(tif)); y = setorientation(img, h); orientation = img->orientation; toskew = -(int32) (orientation == ORIENTATION_TOPLEFT ? w+w : w-w); @@ -695,6 +696,7 @@ gtStripSeparate(TIFFRGBAImage* img, uint TIFFError(TIFFFileName(tif), "No space for tile buffer"); return (0); } + _TIFFmemset(buf, 0, 4*stripsize); g = r + stripsize; b = g + stripsize; a = b + stripsize; diff -uprk.orig tiff-v3.5.7.orig/libtiff/tif_luv.c tiff-v3.5.7/libtiff/tif_luv.c --- tiff-v3.5.7.orig/libtiff/tif_luv.c 2001-03-02 07:57:42 +0300 +++ tiff-v3.5.7/libtiff/tif_luv.c 2004-10-04 00:55:05 +0400 @@ -1161,6 +1161,17 @@ LogL16GuessDataFmt(TIFFDirectory *td) return (SGILOGDATAFMT_UNKNOWN); } +static uint32 +multiply(size_t m1, size_t m2) +{ + uint32 bytes = m1 * m2; + + if (m1 && bytes / m1 != m2) + bytes = 0; + + return bytes; +} + static int LogL16InitState(TIFF* tif) { @@ -1189,9 +1200,9 @@ LogL16InitState(TIFF* tif) "No support for converting user data format to LogL"); return (0); } - sp->tbuflen = td->td_imagewidth * td->td_rowsperstrip; - sp->tbuf = (tidata_t*) _TIFFmalloc(sp->tbuflen * sizeof (int16)); - if (sp->tbuf == NULL) { + sp->tbuflen = multiply(td->td_imagewidth, td->td_rowsperstrip); + if (multiply(sp->tbuflen, sizeof (int16)) == 0 || + (sp->tbuf = (tidata_t*) _TIFFmalloc(sp->tbuflen * sizeof (int16))) == NULL) { TIFFError(module, "%s: No space for SGILog translation buffer", tif->tif_name); return (0); @@ -1287,9 +1298,9 @@ LogLuvInitState(TIFF* tif) "No support for converting user data format to LogLuv"); return (0); } - sp->tbuflen = td->td_imagewidth * td->td_rowsperstrip; - sp->tbuf = (tidata_t*) _TIFFmalloc(sp->tbuflen * sizeof (uint32)); - if (sp->tbuf == NULL) { + sp->tbuflen = multiply(td->td_imagewidth, td->td_rowsperstrip); + if (multiply(sp->tbuflen, sizeof (uint32)) == 0 || + (sp->tbuf = (tidata_t*) _TIFFmalloc(sp->tbuflen * sizeof (uint32))) == NULL) { TIFFError(module, "%s: No space for SGILog translation buffer", tif->tif_name); return (0); diff -uprk.orig tiff-v3.5.7.orig/libtiff/tif_pixarlog.c tiff-v3.5.7/libtiff/tif_pixarlog.c --- tiff-v3.5.7.orig/libtiff/tif_pixarlog.c 1999-07-28 01:50:27 +0400 +++ tiff-v3.5.7/libtiff/tif_pixarlog.c 2004-10-04 00:55:05 +0400 @@ -632,11 +632,23 @@ PixarLogGuessDataFmt(TIFFDirectory *td) return guess; } +static uint32 +multiply(size_t m1, size_t m2) +{ + uint32 bytes = m1 * m2; + + if (m1 && bytes / m1 != m2) + bytes = 0; + + return bytes; +} + static int PixarLogSetupDecode(TIFF* tif) { TIFFDirectory *td = &tif->tif_dir; PixarLogState* sp = DecoderState(tif); + tsize_t tbuf_size; static const char module[] = "PixarLogSetupDecode"; assert(sp != NULL); @@ -649,8 +661,13 @@ PixarLogSetupDecode(TIFF* tif) sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ? td->td_samplesperpixel : 1); - sp->tbuf = (uint16 *) _TIFFmalloc(sp->stride * - td->td_imagewidth * td->td_rowsperstrip * sizeof(uint16)); + tbuf_size = multiply(multiply(multiply(sp->stride, td->td_imagewidth), + td->td_rowsperstrip), sizeof(uint16)); + if (tbuf_size == 0) + return (0); + sp->tbuf = (uint16 *) _TIFFmalloc(tbuf_size); + if (sp->tbuf == NULL) + return (0); if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) sp->user_datafmt = PixarLogGuessDataFmt(td); if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) { @@ -801,6 +818,7 @@ PixarLogSetupEncode(TIFF* tif) { TIFFDirectory *td = &tif->tif_dir; PixarLogState* sp = EncoderState(tif); + tsize_t tbuf_size; static const char module[] = "PixarLogSetupEncode"; assert(sp != NULL); @@ -809,8 +827,13 @@ PixarLogSetupEncode(TIFF* tif) sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ? td->td_samplesperpixel : 1); - sp->tbuf = (uint16 *) _TIFFmalloc(sp->stride * - td->td_imagewidth * td->td_rowsperstrip * sizeof(uint16)); + tbuf_size = multiply(multiply(multiply(sp->stride, td->td_imagewidth), + td->td_rowsperstrip), sizeof(uint16)); + if (tbuf_size == 0) + return (0); + sp->tbuf = (uint16 *) _TIFFmalloc(tbuf_size); + if (sp->tbuf == NULL) + return (0); if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) sp->user_datafmt = PixarLogGuessDataFmt(td); if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) { diff -uprk.orig tiff-v3.5.7.orig/libtiff/tif_strip.c tiff-v3.5.7/libtiff/tif_strip.c --- tiff-v3.5.7.orig/libtiff/tif_strip.c 2000-10-19 18:18:07 +0400 +++ tiff-v3.5.7/libtiff/tif_strip.c 2004-10-04 01:27:15 +0400 @@ -31,6 +31,32 @@ */ #include "tiffiop.h" +static uint32 +summarize(TIFF* tif, size_t summand1, size_t summand2, const char* where) +{ + uint32 bytes = summand1 + summand2; + + if (bytes - summand1 != summand2) { + TIFFError(tif->tif_name, "Integer overflow in %s", where); + bytes = 0; + } + + return (bytes); +} + +static uint32 +multiply(TIFF* tif, size_t nmemb, size_t elem_size, const char* where) +{ + uint32 bytes = nmemb * elem_size; + + if (elem_size && bytes / elem_size != nmemb) { + TIFFError(tif->tif_name, "Integer overflow in %s", where); + bytes = 0; + } + + return (bytes); +} + /* * Compute which strip a (row,sample) value is in. */ @@ -66,7 +92,8 @@ TIFFNumberOfStrips(TIFF* tif) (td->td_imagelength != 0 ? 1 : 0) : TIFFhowmany(td->td_imagelength, td->td_rowsperstrip)); if (td->td_planarconfig == PLANARCONFIG_SEPARATE) - nstrips *= td->td_samplesperpixel; + nstrips = multiply(tif, nstrips, td->td_samplesperpixel, + "TIFFNumberOfStrips"); return (nstrips); } @@ -94,16 +121,20 @@ TIFFVStripSize(TIFF* tif, uint32 nrows) */ tsize_t w = TIFFroundup(td->td_imagewidth, td->td_ycbcrsubsampling[0]); - tsize_t scanline = TIFFhowmany(w*td->td_bitspersample, 8); + tsize_t scanline = + TIFFhowmany8(multiply(tif, w, td->td_bitspersample, "TIFFVStripSize")); tsize_t samplingarea = td->td_ycbcrsubsampling[0]*td->td_ycbcrsubsampling[1]; nrows = TIFFroundup(nrows, td->td_ycbcrsubsampling[1]); /* NB: don't need TIFFhowmany here 'cuz everything is rounded */ + scanline = multiply(tif, nrows, scanline, "TIFFVStripSize"); return ((tsize_t) - (nrows*scanline + 2*(nrows*scanline / samplingarea))); + summarize(tif, scanline, + multiply(tif, 2, scanline / samplingarea, + "TIFFVStripSize"), "TIFFVStripSize")); } else #endif - return ((tsize_t)(nrows * TIFFScanlineSize(tif))); + return ((tsize_t) multiply(tif, nrows, TIFFScanlineSize(tif), "TIFFVStripSize")); } /* @@ -164,10 +195,12 @@ TIFFScanlineSize(TIFF* tif) TIFFDirectory *td = &tif->tif_dir; tsize_t scanline; - scanline = td->td_bitspersample * td->td_imagewidth; + scanline = multiply (tif, td->td_bitspersample, td->td_imagewidth, + "TIFFScanlineSize"); if (td->td_planarconfig == PLANARCONFIG_CONTIG) - scanline *= td->td_samplesperpixel; - return ((tsize_t) TIFFhowmany(scanline, 8)); + scanline = multiply (tif, scanline, td->td_samplesperpixel, + "TIFFScanlineSize"); + return ((tsize_t) TIFFhowmany8(scanline)); } /* @@ -182,11 +215,14 @@ TIFFRasterScanlineSize(TIFF* tif) TIFFDirectory *td = &tif->tif_dir; tsize_t scanline; - scanline = td->td_bitspersample * td->td_imagewidth; + scanline = multiply (tif, td->td_bitspersample, td->td_imagewidth, + "TIFFRasterScanlineSize"); if (td->td_planarconfig == PLANARCONFIG_CONTIG) { - scanline *= td->td_samplesperpixel; - return ((tsize_t) TIFFhowmany(scanline, 8)); + scanline = multiply (tif, scanline, td->td_samplesperpixel, + "TIFFRasterScanlineSize"); + return ((tsize_t) TIFFhowmany8(scanline)); } else - return ((tsize_t) - TIFFhowmany(scanline, 8)*td->td_samplesperpixel); + return ((tsize_t) multiply (tif, TIFFhowmany8(scanline), + td->td_samplesperpixel, + "TIFFRasterScanlineSize")); } diff -uprk.orig tiff-v3.5.7.orig/libtiff/tif_tile.c tiff-v3.5.7/libtiff/tif_tile.c --- tiff-v3.5.7.orig/libtiff/tif_tile.c 1999-07-28 01:50:27 +0400 +++ tiff-v3.5.7/libtiff/tif_tile.c 2004-10-04 00:55:05 +0400 @@ -31,6 +31,32 @@ */ #include "tiffiop.h" +static uint32 +summarize(TIFF* tif, size_t summand1, size_t summand2, const char* where) +{ + uint32 bytes = summand1 + summand2; + + if (bytes - summand1 != summand2) { + TIFFError(tif->tif_name, "Integer overflow in %s", where); + bytes = 0; + } + + return (bytes); +} + +static uint32 +multiply(TIFF* tif, size_t nmemb, size_t elem_size, const char* where) +{ + uint32 bytes = nmemb * elem_size; + + if (elem_size && bytes / elem_size != nmemb) { + TIFFError(tif->tif_name, "Integer overflow in %s", where); + bytes = 0; + } + + return (bytes); +} + /* * Compute which tile an (x,y,z,s) value is in. */ @@ -119,11 +145,13 @@ TIFFNumberOfTiles(TIFF* tif) if (dz == (uint32) -1) dz = td->td_imagedepth; ntiles = (dx == 0 || dy == 0 || dz == 0) ? 0 : - (TIFFhowmany(td->td_imagewidth, dx) * - TIFFhowmany(td->td_imagelength, dy) * - TIFFhowmany(td->td_imagedepth, dz)); + multiply(tif, multiply(tif, TIFFhowmany(td->td_imagewidth, dx), + TIFFhowmany(td->td_imagelength, dy), + "TIFFNumberOfTiles"), + TIFFhowmany(td->td_imagedepth, dz), "TIFFNumberOfTiles"); if (td->td_planarconfig == PLANARCONFIG_SEPARATE) - ntiles *= td->td_samplesperpixel; + ntiles = multiply(tif, ntiles, td->td_samplesperpixel, + "TIFFNumberOfTiles"); return (ntiles); } @@ -138,10 +166,12 @@ TIFFTileRowSize(TIFF* tif) if (td->td_tilelength == 0 || td->td_tilewidth == 0) return ((tsize_t) 0); - rowsize = td->td_bitspersample * td->td_tilewidth; + rowsize = multiply(tif, td->td_bitspersample, td->td_tilewidth, + "TIFFTileRowSize"); if (td->td_planarconfig == PLANARCONFIG_CONTIG) - rowsize *= td->td_samplesperpixel; - return ((tsize_t) TIFFhowmany(rowsize, 8)); + rowsize = multiply(tif, rowsize, td->td_samplesperpixel, + "TIFFTileRowSize"); + return ((tsize_t) TIFFhowmany8(rowsize)); } /* @@ -170,16 +200,24 @@ TIFFVTileSize(TIFF* tif, uint32 nrows) */ tsize_t w = TIFFroundup(td->td_tilewidth, td->td_ycbcrsubsampling[0]); - tsize_t rowsize = TIFFhowmany(w*td->td_bitspersample, 8); + tsize_t rowsize = + TIFFhowmany8(multiply(tif, w, td->td_bitspersample, + "TIFFVTileSize")); tsize_t samplingarea = td->td_ycbcrsubsampling[0]*td->td_ycbcrsubsampling[1]; nrows = TIFFroundup(nrows, td->td_ycbcrsubsampling[1]); /* NB: don't need TIFFhowmany here 'cuz everything is rounded */ - tilesize = nrows*rowsize + 2*(nrows*rowsize / samplingarea); + tilesize = multiply(tif, nrows, rowsize, "TIFFVTileSize"); + tilesize = summarize(tif, tilesize, + multiply(tif, 2, tilesize / samplingarea, + "TIFFVTileSize"), + "TIFFVTileSize"); } else #endif - tilesize = nrows * TIFFTileRowSize(tif); - return ((tsize_t)(tilesize * td->td_tiledepth)); + tilesize = multiply(tif, nrows, TIFFTileRowSize(tif), + "TIFFVTileSize"); + return ((tsize_t) + multiply(tif, tilesize, td->td_tiledepth, "TIFFVTileSize")); } /* diff -uprk.orig tiff-v3.5.7.orig/libtiff/tif_write.c tiff-v3.5.7/libtiff/tif_write.c --- tiff-v3.5.7.orig/libtiff/tif_write.c 2000-02-11 22:28:17 +0300 +++ tiff-v3.5.7/libtiff/tif_write.c 2004-10-04 00:55:05 +0400 @@ -566,21 +566,30 @@ TIFFWriteBufferSetup(TIFF* tif, tdata_t static int TIFFGrowStrips(TIFF* tif, int delta, const char* module) { - TIFFDirectory *td = &tif->tif_dir; + TIFFDirectory *td = &tif->tif_dir; + uint32 *new_stripoffset, *new_stripbytecount; assert(td->td_planarconfig == PLANARCONFIG_CONTIG); - td->td_stripoffset = (uint32*)_TIFFrealloc(td->td_stripoffset, - (td->td_nstrips + delta) * sizeof (uint32)); - td->td_stripbytecount = (uint32*)_TIFFrealloc(td->td_stripbytecount, - (td->td_nstrips + delta) * sizeof (uint32)); - if (td->td_stripoffset == NULL || td->td_stripbytecount == NULL) { + new_stripoffset = (uint32*)_TIFFrealloc(td->td_stripoffset, + (td->td_nstrips + delta) * sizeof (uint32)); + new_stripbytecount = (uint32*)_TIFFrealloc(td->td_stripbytecount, + (td->td_nstrips + delta) * sizeof (uint32)); + if (new_stripoffset == NULL || new_stripbytecount == NULL) { + if (new_stripoffset) + _TIFFfree(new_stripoffset); + if (new_stripbytecount) + _TIFFfree(new_stripbytecount); td->td_nstrips = 0; TIFFError(module, "%s: No space to expand strip arrays", - tif->tif_name); + tif->tif_name); return (0); } - _TIFFmemset(td->td_stripoffset+td->td_nstrips, 0, delta*sizeof (uint32)); - _TIFFmemset(td->td_stripbytecount+td->td_nstrips, 0, delta*sizeof (uint32)); + td->td_stripoffset = new_stripoffset; + td->td_stripbytecount = new_stripbytecount; + _TIFFmemset(td->td_stripoffset + td->td_nstrips, + 0, delta*sizeof (uint32)); + _TIFFmemset(td->td_stripbytecount + td->td_nstrips, + 0, delta*sizeof (uint32)); td->td_nstrips += delta; return (1); }