Move IFD looping checking code in the separate function TIFFCheckDirOffset().
This commit is contained in:
parent
c0e99e81f8
commit
0a27311394
@ -1,4 +1,4 @@
|
||||
/* $Id: tif_dirread.c,v 1.84 2006-04-04 02:00:08 joris Exp $ */
|
||||
/* $Id: tif_dirread.c,v 1.85 2006-06-08 14:27:17 dron Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988-1997 Sam Leffler
|
||||
@ -41,9 +41,11 @@ extern void TIFFCvtIEEEFloatToNative(TIFF*, uint32, float*);
|
||||
extern void TIFFCvtIEEEDoubleToNative(TIFF*, uint32, double*);
|
||||
#endif
|
||||
|
||||
static TIFFDirEntry* TIFFReadDirectoryFind(TIFFDirEntry* dir, uint16 dircount, uint16 tagid);
|
||||
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*);
|
||||
static int CheckDirCount(TIFF*, TIFFDirEntry*, uint32);
|
||||
static tsize_t TIFFFetchData(TIFF*, TIFFDirEntry*, char*);
|
||||
static tsize_t TIFFFetchString(TIFF*, TIFFDirEntry*, char*);
|
||||
@ -82,32 +84,21 @@ TIFFReadDirectory(TIFF* tif)
|
||||
uint16 dircount;
|
||||
toff_t nextdiroff;
|
||||
int diroutoforderwarning = 0;
|
||||
toff_t* new_dirlist;
|
||||
|
||||
tif->tif_diroff = tif->tif_nextdiroff;
|
||||
if (tif->tif_diroff == 0) /* no more directories */
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* XXX: Check offset to prevent IFD looping.
|
||||
*/
|
||||
if (!TIFFCheckDirOffset(tif))
|
||||
return 0;
|
||||
/*
|
||||
* XXX: Trick to prevent IFD looping. The one can create TIFF file
|
||||
* with looped directory pointers. We will maintain a list of already
|
||||
* seen directories and check every IFD offset against this list.
|
||||
*/
|
||||
for (n = 0; n < tif->tif_dirnumber; n++) {
|
||||
if (tif->tif_dirlist[n] == tif->tif_diroff)
|
||||
return (0);
|
||||
}
|
||||
tif->tif_dirnumber++;
|
||||
new_dirlist = (toff_t *)_TIFFrealloc(tif->tif_dirlist,
|
||||
tif->tif_dirnumber * sizeof(toff_t));
|
||||
if (!new_dirlist) {
|
||||
TIFFErrorExt(tif->tif_clientdata, module,
|
||||
"%s: Failed to allocate space for IFD list",
|
||||
tif->tif_name);
|
||||
return (0);
|
||||
}
|
||||
tif->tif_dirlist = new_dirlist;
|
||||
tif->tif_dirlist[tif->tif_dirnumber - 1] = tif->tif_diroff;
|
||||
|
||||
/*
|
||||
* Cleanup any previous compression state.
|
||||
@ -1048,10 +1039,49 @@ MissingRequired(TIFF* tif, const char* tagname)
|
||||
}
|
||||
|
||||
/*
|
||||
* Check the count field of a directory
|
||||
* entry against a known value. The caller
|
||||
* is expected to skip/ignore the tag if
|
||||
* there is a mismatch.
|
||||
* Check the directory offset against the list of already seen directory
|
||||
* offsets. This is a trick to prevent IFD looping. The one can create TIFF
|
||||
* file with looped directory pointers. We will maintain a list of already
|
||||
* seen directories and check every IFD offset against that list.
|
||||
*/
|
||||
static int
|
||||
TIFFCheckDirOffset(TIFF* tif)
|
||||
{
|
||||
uint16 n;
|
||||
|
||||
for (n = 0; n < tif->tif_dirnumber && tif->tif_dirlist; n++) {
|
||||
if (tif->tif_dirlist[n] == tif->tif_diroff)
|
||||
return 0;
|
||||
}
|
||||
|
||||
tif->tif_dirnumber++;
|
||||
|
||||
if (tif->tif_dirnumber > tif->tif_dirlistsize) {
|
||||
toff_t* new_dirlist;
|
||||
|
||||
/*
|
||||
* XXX: Reduce memory allocation granularity of the dirlist
|
||||
* array.
|
||||
*/
|
||||
new_dirlist = (toff_t *)_TIFFCheckRealloc(tif,
|
||||
tif->tif_dirlist,
|
||||
tif->tif_dirnumber,
|
||||
2 * sizeof(toff_t),
|
||||
"for IFD list");
|
||||
if (!new_dirlist)
|
||||
return 0;
|
||||
tif->tif_dirlistsize = 2 * tif->tif_dirnumber;
|
||||
tif->tif_dirlist = new_dirlist;
|
||||
}
|
||||
|
||||
tif->tif_dirlist[tif->tif_dirnumber - 1] = tif->tif_diroff;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check the count field of a directory entry against a known value. The
|
||||
* caller is expected to skip/ignore the tag if there is a mismatch.
|
||||
*/
|
||||
static int
|
||||
CheckDirCount(TIFF* tif, TIFFDirEntry* dir, uint32 count)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: tif_open.c,v 1.32 2006-03-25 03:09:24 joris Exp $ */
|
||||
/* $Id: tif_open.c,v 1.33 2006-06-08 14:27:17 dron Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988-1997 Sam Leffler
|
||||
@ -307,7 +307,8 @@ TIFFClientOpen(
|
||||
if (tif->tif_mode & O_TRUNC ||
|
||||
!ReadOK(tif, &tif->tif_header, sizeof (TIFFHeader))) {
|
||||
if (tif->tif_mode == O_RDONLY) {
|
||||
TIFFErrorExt(tif->tif_clientdata, name, "Cannot read TIFF header");
|
||||
TIFFErrorExt(tif->tif_clientdata, name,
|
||||
"Cannot read TIFF header");
|
||||
goto bad;
|
||||
}
|
||||
/*
|
||||
@ -336,7 +337,8 @@ TIFFClientOpen(
|
||||
TIFFSeekFile( tif, 0, SEEK_SET );
|
||||
|
||||
if (!WriteOK(tif, &tif->tif_header, sizeof (TIFFHeader))) {
|
||||
TIFFErrorExt(tif->tif_clientdata, name, "Error writing TIFF header");
|
||||
TIFFErrorExt(tif->tif_clientdata, name,
|
||||
"Error writing TIFF header");
|
||||
goto bad;
|
||||
}
|
||||
/*
|
||||
@ -350,6 +352,7 @@ TIFFClientOpen(
|
||||
goto bad;
|
||||
tif->tif_diroff = 0;
|
||||
tif->tif_dirlist = NULL;
|
||||
tif->tif_dirlistsize = 0;
|
||||
tif->tif_dirnumber = 0;
|
||||
return (tif);
|
||||
}
|
||||
@ -366,10 +369,12 @@ TIFFClientOpen(
|
||||
tif->tif_header.tiff_magic != MDI_LITTLEENDIAN
|
||||
#endif
|
||||
) {
|
||||
TIFFErrorExt(tif->tif_clientdata, name, "Not a TIFF or MDI file, bad magic number %d (0x%x)",
|
||||
TIFFErrorExt(tif->tif_clientdata, name,
|
||||
"Not a TIFF or MDI file, bad magic number %d (0x%x)",
|
||||
#else
|
||||
) {
|
||||
TIFFErrorExt(tif->tif_clientdata, name, "Not a TIFF file, bad magic number %d (0x%x)",
|
||||
TIFFErrorExt(tif->tif_clientdata, name,
|
||||
"Not a TIFF file, bad magic number %d (0x%x)",
|
||||
#endif
|
||||
tif->tif_header.tiff_magic,
|
||||
tif->tif_header.tiff_magic);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: tiffiop.h,v 1.47 2006-03-25 03:09:24 joris Exp $ */
|
||||
/* $Id: tiffiop.h,v 1.48 2006-06-08 14:27:17 dron Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988-1997 Sam Leffler
|
||||
@ -120,6 +120,7 @@ struct tiff {
|
||||
toff_t tif_nextdiroff; /* file offset of following directory */
|
||||
toff_t* tif_dirlist; /* list of offsets to already seen */
|
||||
/* directories to prevent IFD looping */
|
||||
tsize_t tif_dirlistsize;/* number of entires in offset list */
|
||||
uint16 tif_dirnumber; /* number of already seen directories */
|
||||
TIFFDirectory tif_dir; /* internal rep of current directory */
|
||||
TIFFHeader tif_header; /* file's header block */
|
||||
@ -275,6 +276,7 @@ extern TIFFErrorHandlerExt _TIFFwarningHandlerExt;
|
||||
extern TIFFErrorHandlerExt _TIFFerrorHandlerExt;
|
||||
|
||||
extern tdata_t _TIFFCheckMalloc(TIFF*, size_t, size_t, const char*);
|
||||
extern tdata_t _TIFFCheckRealloc(TIFF*, tdata_t, size_t, size_t, const char*);
|
||||
|
||||
extern int TIFFInitDumpMode(TIFF*, int);
|
||||
#ifdef PACKBITS_SUPPORT
|
||||
|
Loading…
Reference in New Issue
Block a user