From cba7cb2ea0fbe12f4598b0795dd8996b574c993f Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 30 Oct 2024 14:27:17 +0100 Subject: [PATCH] Internal libtiff: resync with upstream --- frmts/gtiff/libtiff/tif_aux.c | 5 +++- frmts/gtiff/libtiff/tif_dir.c | 15 ++++++------ frmts/gtiff/libtiff/tif_dirinfo.c | 38 +++++++++++++++++++++--------- frmts/gtiff/libtiff/tif_dirwrite.c | 10 +++++++- frmts/gtiff/libtiff/tif_hash_set.c | 18 +++++++++++++- frmts/gtiff/libtiff/tif_hash_set.h | 18 +++++++++++++- frmts/gtiff/libtiff/tif_read.c | 21 +++++++++++++---- frmts/gtiff/libtiff/tiffvers.h | 8 +++---- 8 files changed, 101 insertions(+), 32 deletions(-) diff --git a/frmts/gtiff/libtiff/tif_aux.c b/frmts/gtiff/libtiff/tif_aux.c index e9606a42e0fe..31b240070c65 100644 --- a/frmts/gtiff/libtiff/tif_aux.c +++ b/frmts/gtiff/libtiff/tif_aux.c @@ -131,7 +131,10 @@ static int TIFFDefaultTransferFunction(TIFF *tif, TIFFDirectory *td) tmsize_t i, n, nbytes; tf[0] = tf[1] = tf[2] = 0; - if (td->td_bitspersample >= sizeof(tmsize_t) * 8 - 2) + // Do not try to generate a default TransferFunction beyond 24 bits. + // This otherwise leads to insane amounts, resulting in denial of service + // See https://github.com/OSGeo/gdal/issues/10875 + if (td->td_bitspersample > 24) return 0; n = ((tmsize_t)1) << td->td_bitspersample; diff --git a/frmts/gtiff/libtiff/tif_dir.c b/frmts/gtiff/libtiff/tif_dir.c index 459f9696fd3e..6c3d2581a0a3 100644 --- a/frmts/gtiff/libtiff/tif_dir.c +++ b/frmts/gtiff/libtiff/tif_dir.c @@ -806,14 +806,13 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap) if (tv->count == 0) { - status = 0; - TIFFErrorExtR(tif, module, - "%s: Null count for \"%s\" (type " - "%d, writecount %d, passcount %d)", - tif->tif_name, fip->field_name, - fip->field_type, fip->field_writecount, - fip->field_passcount); - goto end; + TIFFWarningExtR(tif, module, + "%s: Null count for \"%s\" (type " + "%d, writecount %d, passcount %d)", + tif->tif_name, fip->field_name, + fip->field_type, fip->field_writecount, + fip->field_passcount); + break; } tv->value = _TIFFCheckMalloc(tif, tv->count, tv_size, diff --git a/frmts/gtiff/libtiff/tif_dirinfo.c b/frmts/gtiff/libtiff/tif_dirinfo.c index 432e6e1e448c..fc065d197670 100644 --- a/frmts/gtiff/libtiff/tif_dirinfo.c +++ b/frmts/gtiff/libtiff/tif_dirinfo.c @@ -1198,15 +1198,27 @@ int TIFFMergeFieldInfo(TIFF *tif, const TIFFFieldInfo info[], uint32_t n) { tp->field_tag = info[i].field_tag; if (info[i].field_readcount < TIFF_VARIABLE2 || - info[i].field_readcount == 0 || - info[i].field_writecount < TIFF_VARIABLE2 || - info[i].field_writecount == 0) + info[i].field_writecount < TIFF_VARIABLE2) { /* The fields (field_readcount) and (field_writecount) may use the * values TIFF_VARIABLE (-1), TIFF_SPP (-2), TIFF_VARIABLE2 (-3). */ - TIFFErrorExtR(tif, module, - "The value of field_readcount and field_writecount " - "must be greater than or equal to -3 and not zero."); + TIFFErrorExtR( + tif, module, + "The value of field_readcount %d and field_writecount %d " + "must be greater than or equal to -3.", + info[i].field_readcount, info[i].field_writecount); + return -1; + } + if ((info[i].field_readcount == 0 || info[i].field_writecount == 0) && + info[i].field_bit != FIELD_IGNORE) + { + /* The fields (field_readcount) and (field_writecount) may only + be zero for pseudo_tags or ignored tags. */ + TIFFErrorExtR( + tif, module, + "The value of field_readcount %d and field_writecount %d " + "may only be zero for field_bit = 0 (i.e. ignored tags).", + info[i].field_readcount, info[i].field_writecount); return -1; } tp->field_readcount = info[i].field_readcount; @@ -1222,14 +1234,18 @@ int TIFFMergeFieldInfo(TIFF *tif, const TIFFFieldInfo info[], uint32_t n) tp->field_bit = info[i].field_bit; tp->field_oktochange = info[i].field_oktochange; tp->field_passcount = info[i].field_passcount; + /* Define an empty static string to be passed as field_name where a NULL + * pointer is passed in. Otherwise, this will lead to buffer overflow + * furtheron. */ if (info[i].field_name == NULL) { - TIFFErrorExtR(tif, module, - "Field_name of %d.th allocation tag %d is NULL", i, - info[i].field_tag); - return -1; + static const char *string_static_empty = ""; + tp->field_name = (char *)string_static_empty; + } + else + { + tp->field_name = info[i].field_name; } - tp->field_name = info[i].field_name; tp->field_subfields = NULL; tp++; } diff --git a/frmts/gtiff/libtiff/tif_dirwrite.c b/frmts/gtiff/libtiff/tif_dirwrite.c index facdeaf7b161..0187e76fb752 100644 --- a/frmts/gtiff/libtiff/tif_dirwrite.c +++ b/frmts/gtiff/libtiff/tif_dirwrite.c @@ -562,6 +562,8 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone, tif->tif_dir.td_dirdatasize_write = 0; if (isimage) { + /*-- Step 1: Process named tags for an image with FIELD bits + * assocciated. --*/ if (TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS)) { if (!TIFFWriteDirectoryTagShortLong(tif, &ndir, dir, @@ -860,6 +862,10 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone, if (!TIFFWriteDirectoryTagSubifd(tif, &ndir, dir)) goto bad; } + /*-- Step 2: Process named tags for an image with FIELD bits + added by a codec. + Attention: There is only code for some field_types, + which are actually used by current codecs. --*/ { uint32_t n; for (n = 0; n < tif->tif_nfields; n++) @@ -879,7 +885,7 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone, assert(o->field_readcount == TIFF_VARIABLE); assert(o->field_passcount == 0); TIFFGetField(tif, o->field_tag, &pb); - pa = (uint32_t)(strlen(pb)); + pa = (uint32_t)(strlen(pb) + 1); if (!TIFFWriteDirectoryTagAscii( tif, &ndir, dir, (uint16_t)o->field_tag, pa, pb)) @@ -938,6 +944,8 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone, } } } + /*-- Step 3: Process custom tags without FIELD bit for an image + * or for custom IFDs (e.g. EXIF) with !isimage. --*/ for (m = 0; m < (uint32_t)(tif->tif_dir.td_customValueCount); m++) { uint16_t tag = diff --git a/frmts/gtiff/libtiff/tif_hash_set.c b/frmts/gtiff/libtiff/tif_hash_set.c index d024fcb5eb90..81dea3fcf26a 100644 --- a/frmts/gtiff/libtiff/tif_hash_set.c +++ b/frmts/gtiff/libtiff/tif_hash_set.c @@ -7,7 +7,23 @@ ********************************************************************** * Copyright (c) 2008-2009, Even Rouault * - * SPDX-License-Identifier: MIT + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. ****************************************************************************/ #include "tif_config.h" diff --git a/frmts/gtiff/libtiff/tif_hash_set.h b/frmts/gtiff/libtiff/tif_hash_set.h index fd0323a98094..f60e2c675e53 100644 --- a/frmts/gtiff/libtiff/tif_hash_set.h +++ b/frmts/gtiff/libtiff/tif_hash_set.h @@ -9,7 +9,23 @@ ********************************************************************** * Copyright (c) 2008-2009, Even Rouault * - * SPDX-License-Identifier: MIT + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. ****************************************************************************/ #ifndef TIFF_HASH_SET_H_INCLUDED diff --git a/frmts/gtiff/libtiff/tif_read.c b/frmts/gtiff/libtiff/tif_read.c index 7efab59c6a38..964f119a78ca 100644 --- a/frmts/gtiff/libtiff/tif_read.c +++ b/frmts/gtiff/libtiff/tif_read.c @@ -466,7 +466,9 @@ int TIFFReadScanline(TIFF *tif, void *buf, uint32_t row, uint16_t sample) } else { - memset(buf, 0, (size_t)tif->tif_scanlinesize); + /* See TIFFReadEncodedStrip comment regarding TIFFTAG_FAXFILLFUNC. */ + if (buf) + memset(buf, 0, (size_t)tif->tif_scanlinesize); } return (e > 0 ? 1 : -1); } @@ -554,7 +556,10 @@ tmsize_t TIFFReadEncodedStrip(TIFF *tif, uint32_t strip, void *buf, stripsize = size; if (!TIFFFillStrip(tif, strip)) { - memset(buf, 0, (size_t)stripsize); + /* The output buf may be NULL, in particular if TIFFTAG_FAXFILLFUNC + is being used. Thus, memset must be conditional on buf not NULL. */ + if (buf) + memset(buf, 0, (size_t)stripsize); return ((tmsize_t)(-1)); } if ((*tif->tif_decodestrip)(tif, buf, stripsize, plane) <= 0) @@ -976,7 +981,9 @@ tmsize_t TIFFReadEncodedTile(TIFF *tif, uint32_t tile, void *buf, tmsize_t size) size = tilesize; if (!TIFFFillTile(tif, tile)) { - memset(buf, 0, (size_t)size); + /* See TIFFReadEncodedStrip comment regarding TIFFTAG_FAXFILLFUNC. */ + if (buf) + memset(buf, 0, (size_t)size); return ((tmsize_t)(-1)); } else if ((*tif->tif_decodetile)(tif, (uint8_t *)buf, size, @@ -1569,7 +1576,9 @@ int TIFFReadFromUserBuffer(TIFF *tif, uint32_t strile, void *inbuf, if (!TIFFStartTile(tif, strile)) { ret = 0; - memset(outbuf, 0, (size_t)outsize); + /* See related TIFFReadEncodedStrip comment. */ + if (outbuf) + memset(outbuf, 0, (size_t)outsize); } else if (!(*tif->tif_decodetile)( tif, (uint8_t *)outbuf, outsize, @@ -1596,7 +1605,9 @@ int TIFFReadFromUserBuffer(TIFF *tif, uint32_t strile, void *inbuf, if (!TIFFStartStrip(tif, strile)) { ret = 0; - memset(outbuf, 0, (size_t)outsize); + /* See related TIFFReadEncodedStrip comment. */ + if (outbuf) + memset(outbuf, 0, (size_t)outsize); } else if (!(*tif->tif_decodestrip)( tif, (uint8_t *)outbuf, outsize, diff --git a/frmts/gtiff/libtiff/tiffvers.h b/frmts/gtiff/libtiff/tiffvers.h index 892e9a0b2392..b606ea8e6171 100644 --- a/frmts/gtiff/libtiff/tiffvers.h +++ b/frmts/gtiff/libtiff/tiffvers.h @@ -8,7 +8,7 @@ * Furthermore, configure_file variables of type "@VAR@" are * modified by clang-format and won't be substituted by CMake. */ -#define TIFFLIB_VERSION_STR "LIBTIFF, Version 4.6.0\nCopyright (c) 1988-1996 Sam Leffler\nCopyright (c) 1991-1996 Silicon Graphics, Inc." +#define TIFFLIB_VERSION_STR "LIBTIFF, Version 4.7.0\nCopyright (c) 1988-1996 Sam Leffler\nCopyright (c) 1991-1996 Silicon Graphics, Inc." /* * This define can be used in code that requires * compilation-related definitions specific to a @@ -16,13 +16,13 @@ * version checking should be done based on the * string returned by TIFFGetVersion. */ -#define TIFFLIB_VERSION 20230908 +#define TIFFLIB_VERSION 20240911 /* The following defines have been added in 4.5.0 */ #define TIFFLIB_MAJOR_VERSION 4 -#define TIFFLIB_MINOR_VERSION 6 +#define TIFFLIB_MINOR_VERSION 7 #define TIFFLIB_MICRO_VERSION 0 -#define TIFFLIB_VERSION_STR_MAJ_MIN_MIC "4.6.0" +#define TIFFLIB_VERSION_STR_MAJ_MIN_MIC "4.7.0" /* Macro added in 4.5.0. Returns TRUE if the current libtiff version is * greater or equal to major.minor.micro