diff --git a/frmts/gtiff/libtiff/tif_color.c b/frmts/gtiff/libtiff/tif_color.c index 2d7dcac6fe68..a52fdacba59c 100644 --- a/frmts/gtiff/libtiff/tif_color.c +++ b/frmts/gtiff/libtiff/tif_color.c @@ -89,7 +89,7 @@ void TIFFCIELab16ToXYZ(TIFFCIELabToRGB *cielab, uint32_t l, int32_t a, void TIFFXYZToRGB(TIFFCIELabToRGB *cielab, float X, float Y, float Z, uint32_t *r, uint32_t *g, uint32_t *b) { - int i; + size_t i; float Yr, Yg, Yb; float *matrix = &cielab->display.d_mat[0][0]; @@ -109,16 +109,16 @@ void TIFFXYZToRGB(TIFFCIELabToRGB *cielab, float X, float Y, float Z, Yb = TIFFmin(Yb, cielab->display.d_YCB); /* Turn luminosity to colour value. */ - i = (int)((Yr - cielab->display.d_Y0R) / cielab->rstep); - i = TIFFmin(cielab->range, i); + i = (size_t)((Yr - cielab->display.d_Y0R) / cielab->rstep); + i = TIFFmin((size_t)cielab->range, i); *r = RINT(cielab->Yr2r[i]); - i = (int)((Yg - cielab->display.d_Y0G) / cielab->gstep); - i = TIFFmin(cielab->range, i); + i = (size_t)((Yg - cielab->display.d_Y0G) / cielab->gstep); + i = TIFFmin((size_t)cielab->range, i); *g = RINT(cielab->Yg2g[i]); - i = (int)((Yb - cielab->display.d_Y0B) / cielab->bstep); - i = TIFFmin(cielab->range, i); + i = (size_t)((Yb - cielab->display.d_Y0B) / cielab->bstep); + i = TIFFmin((size_t)cielab->range, i); *b = RINT(cielab->Yb2b[i]); /* Clip output. */ @@ -135,7 +135,7 @@ void TIFFXYZToRGB(TIFFCIELabToRGB *cielab, float X, float Y, float Z, int TIFFCIELabToRGBInit(TIFFCIELabToRGB *cielab, const TIFFDisplay *display, float *refWhite) { - int i; + size_t i; double dfGamma; cielab->range = CIELABTORGB_TABLE_RANGE; @@ -146,7 +146,7 @@ int TIFFCIELabToRGBInit(TIFFCIELabToRGB *cielab, const TIFFDisplay *display, dfGamma = 1.0 / cielab->display.d_gammaR; cielab->rstep = (cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range; - for (i = 0; i <= cielab->range; i++) + for (i = 0; i <= (size_t)cielab->range; i++) { cielab->Yr2r[i] = cielab->display.d_Vrwr * ((float)pow((double)i / cielab->range, dfGamma)); @@ -156,7 +156,7 @@ int TIFFCIELabToRGBInit(TIFFCIELabToRGB *cielab, const TIFFDisplay *display, dfGamma = 1.0 / cielab->display.d_gammaG; cielab->gstep = (cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range; - for (i = 0; i <= cielab->range; i++) + for (i = 0; i <= (size_t)cielab->range; i++) { cielab->Yg2g[i] = cielab->display.d_Vrwg * ((float)pow((double)i / cielab->range, dfGamma)); @@ -166,7 +166,7 @@ int TIFFCIELabToRGBInit(TIFFCIELabToRGB *cielab, const TIFFDisplay *display, dfGamma = 1.0 / cielab->display.d_gammaB; cielab->bstep = (cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range; - for (i = 0; i <= cielab->range; i++) + for (i = 0; i <= (size_t)cielab->range; i++) { cielab->Yb2b[i] = cielab->display.d_Vrwb * ((float)pow((double)i / cielab->range, dfGamma)); diff --git a/frmts/gtiff/libtiff/tif_dirread.c b/frmts/gtiff/libtiff/tif_dirread.c index b360deaeaa4c..3d94ea7d4f37 100644 --- a/frmts/gtiff/libtiff/tif_dirread.c +++ b/frmts/gtiff/libtiff/tif_dirread.c @@ -4282,8 +4282,6 @@ int TIFFReadDirectory(TIFF *tif) else tif->tif_curdir++; - (*tif->tif_cleanup)(tif); /* cleanup any previous compression state */ - TIFFReadDirectoryCheckOrder(tif, dir, dircount); /* @@ -4312,6 +4310,7 @@ int TIFFReadDirectory(TIFF *tif) tif->tif_flags &= ~TIFF_CHOPPEDUPARRAYS; /* free any old stuff and reinit */ + (*tif->tif_cleanup)(tif); /* cleanup any previous compression state */ TIFFFreeDirectory(tif); TIFFDefaultDirectory(tif); @@ -5281,8 +5280,7 @@ int TIFFReadCustomDirectory(TIFF *tif, toff_t diroff, uint16_t di; const TIFFField *fip; uint32_t fii; - (*tif->tif_cleanup)(tif); /* cleanup any previous compression state */ - _TIFFSetupFields(tif, infoarray); + dircount = TIFFFetchDirectory(tif, diroff, &dir, NULL); if (!dircount) { @@ -5291,9 +5289,41 @@ int TIFFReadCustomDirectory(TIFF *tif, toff_t diroff, diroff); return 0; } - TIFFFreeDirectory(tif); - _TIFFmemset(&tif->tif_dir, 0, sizeof(TIFFDirectory)); TIFFReadDirectoryCheckOrder(tif, dir, dircount); + + /* + * Mark duplicates of any tag to be ignored (bugzilla 1994) + * to avoid certain pathological problems. + */ + { + TIFFDirEntry *ma; + uint16_t mb; + for (ma = dir, mb = 0; mb < dircount; ma++, mb++) + { + TIFFDirEntry *na; + uint16_t nb; + for (na = ma + 1, nb = mb + 1; nb < dircount; na++, nb++) + { + if (ma->tdir_tag == na->tdir_tag) + { + na->tdir_ignore = TRUE; + } + } + } + } + + /* Free any old stuff and reinit. */ + (*tif->tif_cleanup)(tif); /* cleanup any previous compression state */ + TIFFFreeDirectory(tif); + /* Even if custom directories do not need the default settings of a standard + * IFD, the pointer to the TIFFSetField() and TIFFGetField() (i.e. + * tif->tif_tagmethods.vsetfield and tif->tif_tagmethods.vgetfield) need to + * be initialized, which is done in TIFFDefaultDirectory(). + * After that, the field array for the custom tags needs to be setup again. + */ + TIFFDefaultDirectory(tif); + _TIFFSetupFields(tif, infoarray); + /* Allocate arrays for offset values outside IFD entry for IFD data size * checking. Note: Counter are reset within TIFFFreeDirectory(). */ tif->tif_dir.td_dirdatasize_offsets = diff --git a/frmts/gtiff/libtiff/tif_luv.c b/frmts/gtiff/libtiff/tif_luv.c index 021756d5d6dd..d19653550c6b 100644 --- a/frmts/gtiff/libtiff/tif_luv.c +++ b/frmts/gtiff/libtiff/tif_luv.c @@ -951,7 +951,8 @@ static int uv_encode(double u, double v, int em) /* encode (u',v') coordinates */ { - register int vi, ui; + unsigned int vi; + int ui; /* check for NaN */ if (u != u || v != v) @@ -980,8 +981,9 @@ static int uv_decode(double *up, double *vp, int c) /* decode (u',v') index */ { - int upper, lower; - register int ui, vi; + unsigned int upper, lower; + int ui; + unsigned int vi; if (c < 0 || c >= UV_NDIVS) return (-1); diff --git a/frmts/gtiff/libtiff/tif_open.c b/frmts/gtiff/libtiff/tif_open.c index 56330d771a96..59a07bee0232 100644 --- a/frmts/gtiff/libtiff/tif_open.c +++ b/frmts/gtiff/libtiff/tif_open.c @@ -741,9 +741,17 @@ TIFF *TIFFClientOpenExt(const char *name, const char *mode, * example, it may be broken) and want to proceed to other * directories. I this case we use the TIFF_HEADERONLY flag to open * file and return immediately after reading TIFF header. + * However, the pointer to TIFFSetField() and TIFFGetField() + * (i.e. tif->tif_tagmethods.vsetfield and + * tif->tif_tagmethods.vgetfield) need to be initialized, which is + * done in TIFFDefaultDirectory(). */ if (tif->tif_flags & TIFF_HEADERONLY) + { + if (!TIFFDefaultDirectory(tif)) + goto bad; return (tif); + } /* * Setup initial directory. diff --git a/frmts/gtiff/libtiff/tif_strip.c b/frmts/gtiff/libtiff/tif_strip.c index 7ae7ce41dfa2..4dbcf37e48b2 100644 --- a/frmts/gtiff/libtiff/tif_strip.c +++ b/frmts/gtiff/libtiff/tif_strip.c @@ -38,6 +38,11 @@ uint32_t TIFFComputeStrip(TIFF *tif, uint32_t row, uint16_t sample) TIFFDirectory *td = &tif->tif_dir; uint32_t strip; + if (td->td_rowsperstrip == 0) + { + TIFFErrorExtR(tif, module, "Cannot compute strip: RowsPerStrip is zero"); + return 0; + } strip = row / td->td_rowsperstrip; if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {