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
|
* Copyright (c) 1988-1997 Sam Leffler
|
||||||
@ -41,9 +41,11 @@ extern void TIFFCvtIEEEFloatToNative(TIFF*, uint32, float*);
|
|||||||
extern void TIFFCvtIEEEDoubleToNative(TIFF*, uint32, double*);
|
extern void TIFFCvtIEEEDoubleToNative(TIFF*, uint32, double*);
|
||||||
#endif
|
#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 int EstimateStripByteCounts(TIFF*, TIFFDirEntry*, uint16);
|
||||||
static void MissingRequired(TIFF*, const char*);
|
static void MissingRequired(TIFF*, const char*);
|
||||||
|
static int TIFFCheckDirOffset(TIFF*);
|
||||||
static int CheckDirCount(TIFF*, TIFFDirEntry*, uint32);
|
static int CheckDirCount(TIFF*, TIFFDirEntry*, uint32);
|
||||||
static tsize_t TIFFFetchData(TIFF*, TIFFDirEntry*, char*);
|
static tsize_t TIFFFetchData(TIFF*, TIFFDirEntry*, char*);
|
||||||
static tsize_t TIFFFetchString(TIFF*, TIFFDirEntry*, char*);
|
static tsize_t TIFFFetchString(TIFF*, TIFFDirEntry*, char*);
|
||||||
@ -82,32 +84,21 @@ TIFFReadDirectory(TIFF* tif)
|
|||||||
uint16 dircount;
|
uint16 dircount;
|
||||||
toff_t nextdiroff;
|
toff_t nextdiroff;
|
||||||
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 */
|
||||||
return (0);
|
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
|
* XXX: Trick to prevent IFD looping. The one can create TIFF file
|
||||||
* with looped directory pointers. We will maintain a list of already
|
* with looped directory pointers. We will maintain a list of already
|
||||||
* seen directories and check every IFD offset against this list.
|
* 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.
|
* Cleanup any previous compression state.
|
||||||
@ -1048,10 +1039,49 @@ MissingRequired(TIFF* tif, const char* tagname)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check the count field of a directory
|
* Check the directory offset against the list of already seen directory
|
||||||
* entry against a known value. The caller
|
* offsets. This is a trick to prevent IFD looping. The one can create TIFF
|
||||||
* is expected to skip/ignore the tag if
|
* file with looped directory pointers. We will maintain a list of already
|
||||||
* there is a mismatch.
|
* 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
|
static int
|
||||||
CheckDirCount(TIFF* tif, TIFFDirEntry* dir, uint32 count)
|
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
|
* Copyright (c) 1988-1997 Sam Leffler
|
||||||
@ -307,7 +307,8 @@ TIFFClientOpen(
|
|||||||
if (tif->tif_mode & O_TRUNC ||
|
if (tif->tif_mode & O_TRUNC ||
|
||||||
!ReadOK(tif, &tif->tif_header, sizeof (TIFFHeader))) {
|
!ReadOK(tif, &tif->tif_header, sizeof (TIFFHeader))) {
|
||||||
if (tif->tif_mode == O_RDONLY) {
|
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;
|
goto bad;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@ -336,7 +337,8 @@ TIFFClientOpen(
|
|||||||
TIFFSeekFile( tif, 0, SEEK_SET );
|
TIFFSeekFile( tif, 0, SEEK_SET );
|
||||||
|
|
||||||
if (!WriteOK(tif, &tif->tif_header, sizeof (TIFFHeader))) {
|
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;
|
goto bad;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@ -350,6 +352,7 @@ TIFFClientOpen(
|
|||||||
goto bad;
|
goto bad;
|
||||||
tif->tif_diroff = 0;
|
tif->tif_diroff = 0;
|
||||||
tif->tif_dirlist = NULL;
|
tif->tif_dirlist = NULL;
|
||||||
|
tif->tif_dirlistsize = 0;
|
||||||
tif->tif_dirnumber = 0;
|
tif->tif_dirnumber = 0;
|
||||||
return (tif);
|
return (tif);
|
||||||
}
|
}
|
||||||
@ -366,10 +369,12 @@ TIFFClientOpen(
|
|||||||
tif->tif_header.tiff_magic != MDI_LITTLEENDIAN
|
tif->tif_header.tiff_magic != MDI_LITTLEENDIAN
|
||||||
#endif
|
#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
|
#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
|
#endif
|
||||||
tif->tif_header.tiff_magic,
|
tif->tif_header.tiff_magic,
|
||||||
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
|
* Copyright (c) 1988-1997 Sam Leffler
|
||||||
@ -120,6 +120,7 @@ struct tiff {
|
|||||||
toff_t tif_nextdiroff; /* file offset of following directory */
|
toff_t tif_nextdiroff; /* file offset of following directory */
|
||||||
toff_t* tif_dirlist; /* list of offsets to already seen */
|
toff_t* tif_dirlist; /* list of offsets to already seen */
|
||||||
/* directories to prevent IFD looping */
|
/* directories to prevent IFD looping */
|
||||||
|
tsize_t tif_dirlistsize;/* number of entires in offset list */
|
||||||
uint16 tif_dirnumber; /* number of already seen directories */
|
uint16 tif_dirnumber; /* number of already seen directories */
|
||||||
TIFFDirectory tif_dir; /* internal rep of current directory */
|
TIFFDirectory tif_dir; /* internal rep of current directory */
|
||||||
TIFFHeader tif_header; /* file's header block */
|
TIFFHeader tif_header; /* file's header block */
|
||||||
@ -275,6 +276,7 @@ extern TIFFErrorHandlerExt _TIFFwarningHandlerExt;
|
|||||||
extern TIFFErrorHandlerExt _TIFFerrorHandlerExt;
|
extern TIFFErrorHandlerExt _TIFFerrorHandlerExt;
|
||||||
|
|
||||||
extern tdata_t _TIFFCheckMalloc(TIFF*, size_t, size_t, const char*);
|
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);
|
extern int TIFFInitDumpMode(TIFF*, int);
|
||||||
#ifdef PACKBITS_SUPPORT
|
#ifdef PACKBITS_SUPPORT
|
||||||
|
Loading…
Reference in New Issue
Block a user