Potential memory leak fixed in TIFFReadDirectory(). Always check the return

values, returned by the _TIFFmalloc() (Dmitry V. Levin).
This commit is contained in:
Andrey Kiselev 2004-09-25 11:05:10 +00:00
parent bfeb12aa9d
commit 9da27e9da7

View File

@ -1,4 +1,4 @@
/* $Id: tif_dirread.c,v 1.39 2004-09-24 08:10:18 dron Exp $ */ /* $Id: tif_dirread.c,v 1.40 2004-09-25 11:05:10 dron Exp $ */
/* /*
* Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1988-1997 Sam Leffler
@ -102,6 +102,7 @@ TIFFReadDirectory(TIFF* tif)
toff_t nextdiroff; toff_t nextdiroff;
char* cp; char* cp;
int diroutoforderwarning = 0; int diroutoforderwarning = 0;
toff_t* new_dirlist;
tif->tif_diroff = tif->tif_nextdiroff; tif->tif_diroff = tif->tif_nextdiroff;
if (tif->tif_diroff == 0) /* no more directories */ if (tif->tif_diroff == 0) /* no more directories */
@ -117,14 +118,15 @@ TIFFReadDirectory(TIFF* tif)
return (0); return (0);
} }
tif->tif_dirnumber++; tif->tif_dirnumber++;
tif->tif_dirlist = _TIFFrealloc(tif->tif_dirlist, new_dirlist = _TIFFrealloc(tif->tif_dirlist,
tif->tif_dirnumber * sizeof(toff_t)); tif->tif_dirnumber * sizeof(toff_t));
if (!tif->tif_dirlist) { if (!new_dirlist) {
TIFFError(module, TIFFError(module,
"%.1000s: Failed to allocate space for IFD list", "%s: Failed to allocate space for IFD list",
tif->tif_name); tif->tif_name);
return (0); return (0);
} }
tif->tif_dirlist = new_dirlist;
tif->tif_dirlist[tif->tif_dirnumber - 1] = tif->tif_diroff; tif->tif_dirlist[tif->tif_dirnumber - 1] = tif->tif_diroff;
/* /*
@ -136,13 +138,13 @@ TIFFReadDirectory(TIFF* tif)
if (!isMapped(tif)) { if (!isMapped(tif)) {
if (!SeekOK(tif, tif->tif_diroff)) { if (!SeekOK(tif, tif->tif_diroff)) {
TIFFError(module, TIFFError(module,
"%.1000s: Seek error accessing TIFF directory", "%s: Seek error accessing TIFF directory",
tif->tif_name); tif->tif_name);
return (0); return (0);
} }
if (!ReadOK(tif, &dircount, sizeof (uint16))) { if (!ReadOK(tif, &dircount, sizeof (uint16))) {
TIFFError(module, TIFFError(module,
"%.1000s: Can not read TIFF directory count", "%s: Can not read TIFF directory count",
tif->tif_name); tif->tif_name);
return (0); return (0);
} }
@ -167,7 +169,7 @@ TIFFReadDirectory(TIFF* tif)
if (off + sizeof (uint16) > tif->tif_size) { if (off + sizeof (uint16) > tif->tif_size) {
TIFFError(module, TIFFError(module,
"%.1000s: Can not read TIFF directory count", "%s: Can not read TIFF directory count",
tif->tif_name); tif->tif_name);
return (0); return (0);
} else } else
@ -181,7 +183,7 @@ TIFFReadDirectory(TIFF* tif)
return (0); return (0);
if (off + dircount*sizeof (TIFFDirEntry) > tif->tif_size) { if (off + dircount*sizeof (TIFFDirEntry) > tif->tif_size) {
TIFFError(module, TIFFError(module,
"%.1000s: Can not read TIFF directory", "%s: Can not read TIFF directory",
tif->tif_name); tif->tif_name);
goto bad; goto bad;
} else } else
@ -268,7 +270,7 @@ TIFFReadDirectory(TIFF* tif)
if (dp->tdir_tag < tif->tif_fieldinfo[fix]->field_tag) { if (dp->tdir_tag < tif->tif_fieldinfo[fix]->field_tag) {
if (!diroutoforderwarning) { if (!diroutoforderwarning) {
TIFFWarning(module, TIFFWarning(module,
"%.1000s: invalid TIFF directory; tags are not sorted in ascending order", "%s: invalid TIFF directory; tags are not sorted in ascending order",
tif->tif_name); tif->tif_name);
diroutoforderwarning = 1; diroutoforderwarning = 1;
} }
@ -281,7 +283,7 @@ TIFFReadDirectory(TIFF* tif)
tif->tif_fieldinfo[fix]->field_tag != dp->tdir_tag) { tif->tif_fieldinfo[fix]->field_tag != dp->tdir_tag) {
TIFFWarning(module, TIFFWarning(module,
"%.1000s: unknown field with tag %d (0x%x) encountered", "%s: unknown field with tag %d (0x%x) encountered",
tif->tif_name, dp->tdir_tag, dp->tdir_tag, tif->tif_name, dp->tdir_tag, dp->tdir_tag,
dp->tdir_type); dp->tdir_type);
@ -315,7 +317,7 @@ TIFFReadDirectory(TIFF* tif)
if (fix >= tif->tif_nfields || if (fix >= tif->tif_nfields ||
fip->field_tag != dp->tdir_tag) { fip->field_tag != dp->tdir_tag) {
TIFFWarning(module, TIFFWarning(module,
"%.1000s: wrong data type %d for \"%s\"; tag ignored", "%s: wrong data type %d for \"%s\"; tag ignored",
tif->tif_name, dp->tdir_type, tif->tif_name, dp->tdir_type,
tif->tif_fieldinfo[fix-1]->field_name); tif->tif_fieldinfo[fix-1]->field_name);
goto ignore; goto ignore;
@ -553,7 +555,7 @@ TIFFReadDirectory(TIFF* tif)
goto bad; goto bad;
} }
TIFFWarning(module, TIFFWarning(module,
"%.1000s: TIFF directory is missing required " "%s: TIFF directory is missing required "
"\"%s\" field, calculating from imagelength", "\"%s\" field, calculating from imagelength",
tif->tif_name, tif->tif_name,
_TIFFFieldWithTag(tif,TIFFTAG_STRIPBYTECOUNTS)->field_name); _TIFFFieldWithTag(tif,TIFFTAG_STRIPBYTECOUNTS)->field_name);
@ -578,7 +580,7 @@ TIFFReadDirectory(TIFF* tif)
* strip image. * strip image.
*/ */
TIFFWarning(module, TIFFWarning(module,
"%.1000s: Bogus \"%s\" field, ignoring and calculating from imagelength", "%s: Bogus \"%s\" field, ignoring and calculating from imagelength",
tif->tif_name, tif->tif_name,
_TIFFFieldWithTag(tif,TIFFTAG_STRIPBYTECOUNTS)->field_name); _TIFFFieldWithTag(tif,TIFFTAG_STRIPBYTECOUNTS)->field_name);
if(EstimateStripByteCounts(tif, dir, dircount) < 0) if(EstimateStripByteCounts(tif, dir, dircount) < 0)
@ -649,7 +651,7 @@ EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16 dircount)
uint32 cc = TIFFDataWidth((TIFFDataType) dp->tdir_type); uint32 cc = TIFFDataWidth((TIFFDataType) dp->tdir_type);
if (cc == 0) { if (cc == 0) {
TIFFError(module, TIFFError(module,
"%.1000s: Cannot determine size of unknown tag type %d", "%s: Cannot determine size of unknown tag type %d",
tif->tif_name, dp->tdir_type); tif->tif_name, dp->tdir_type);
return -1; return -1;
} }
@ -692,7 +694,7 @@ MissingRequired(TIFF* tif, const char* tagname)
static const char module[] = "MissingRequired"; static const char module[] = "MissingRequired";
TIFFError(module, TIFFError(module,
"%.1000s: TIFF directory is missing required \"%s\" field", "%s: TIFF directory is missing required \"%s\" field",
tif->tif_name, tagname); tif->tif_name, tagname);
} }
@ -1246,8 +1248,9 @@ TIFFFetchPerSampleShorts(TIFF* tif, TIFFDirEntry* dir, int* pl)
uint16* v = buf; uint16* v = buf;
if (samples > NITEMS(buf)) if (samples > NITEMS(buf))
v = (uint16*) _TIFFmalloc(samples * sizeof (uint16)); v = (uint16*) CheckMalloc(tif, samples, sizeof (uint16),
if (TIFFFetchShortArray(tif, dir, v)) { "to fetch per-sample values");
if (v && TIFFFetchShortArray(tif, dir, v)) {
int i; int i;
for (i = 1; i < samples; i++) for (i = 1; i < samples; i++)
if (v[i] != v[0]) { if (v[i] != v[0]) {
@ -1260,7 +1263,7 @@ TIFFFetchPerSampleShorts(TIFF* tif, TIFFDirEntry* dir, int* pl)
status = 1; status = 1;
} }
bad: bad:
if (v != buf) if (v && v != buf)
_TIFFfree((char*) v); _TIFFfree((char*) v);
} }
return (status); return (status);
@ -1282,8 +1285,9 @@ TIFFFetchPerSampleAnys(TIFF* tif, TIFFDirEntry* dir, double* pl)
double* v = buf; double* v = buf;
if (samples > NITEMS(buf)) if (samples > NITEMS(buf))
v = (double*) _TIFFmalloc(samples * sizeof (double)); v = (double*) CheckMalloc(tif, samples, sizeof (double),
if (TIFFFetchAnyArray(tif, dir, v)) { "to fetch per-sample values");
if (v && TIFFFetchAnyArray(tif, dir, v)) {
int i; int i;
for (i = 1; i < samples; i++) for (i = 1; i < samples; i++)
if (v[i] != v[0]) { if (v[i] != v[0]) {
@ -1296,7 +1300,7 @@ TIFFFetchPerSampleAnys(TIFF* tif, TIFFDirEntry* dir, double* pl)
status = 1; status = 1;
} }
bad: bad:
if (v != buf) if (v && v != buf)
_TIFFfree(v); _TIFFfree(v);
} }
return (status); return (status);
@ -1379,8 +1383,12 @@ TIFFFetchExtraSamples(TIFF* tif, TIFFDirEntry* dir)
uint16* v = buf; uint16* v = buf;
int status; int status;
if (dir->tdir_count > NITEMS(buf)) if (dir->tdir_count > NITEMS(buf)) {
v = (uint16*) _TIFFmalloc(dir->tdir_count * sizeof (uint16)); v = (uint16*) CheckMalloc(tif, dir->tdir_count, sizeof (uint16),
"to fetch extra samples");
if (!v)
return (0);
}
if (dir->tdir_type == TIFF_BYTE) if (dir->tdir_type == TIFF_BYTE)
status = TIFFFetchByteArray(tif, dir, v); status = TIFFFetchByteArray(tif, dir, v);
else else