summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2021-12-05 15:10:12 +0100
committerEven Rouault <even.rouault@spatialys.com>2021-12-05 15:10:12 +0100
commite01a3de226c179df0e32f37e7fa7dd8c3a3c28a2 (patch)
treebe61f3b59ffb546716d0b7a1402ffda84a8c9f9c
parent2d5fc85647809e4a17bc06f23ea736331ebd2d43 (diff)
downloadlibtiff-git-e01a3de226c179df0e32f37e7fa7dd8c3a3c28a2.tar.gz
tiffinfo: add a -M switch to define the maximum heap allocation, and default it to 256 MiB (fixes #287)
-rw-r--r--tools/tiffinfo.c67
1 files changed, 47 insertions, 20 deletions
diff --git a/tools/tiffinfo.c b/tools/tiffinfo.c
index 0ab8ca95..3db22280 100644
--- a/tools/tiffinfo.c
+++ b/tools/tiffinfo.c
@@ -57,6 +57,11 @@ static int stoponerr = 1; /* stop on first read error */
static void usage(int);
static void tiffinfo(TIFF*, uint16_t, long, int);
+#define DEFAULT_MAX_MALLOC (256 * 1024 * 1024)
+/* malloc size limit (in bytes)
+ * disabled when set to 0 */
+static tmsize_t maxMalloc = DEFAULT_MAX_MALLOC;
+
static void
PrivateErrorHandler(const char* module, const char* fmt, va_list ap)
{
@@ -79,7 +84,7 @@ main(int argc, char* argv[])
uint64_t diroff = 0;
int chopstrips = 0; /* disable strip chopping */
- while ((c = getopt(argc, argv, "f:o:cdDSjilmrsvwz0123456789h")) != -1)
+ while ((c = getopt(argc, argv, "f:o:M:cdDSjilmrsvwz0123456789h")) != -1)
switch (c) {
case '0': case '1': case '2': case '3':
case '4': case '5': case '6': case '7':
@@ -106,6 +111,9 @@ main(int argc, char* argv[])
case 'i':
stoponerr = 0;
break;
+ case 'M':
+ maxMalloc = (tmsize_t)strtoul(optarg, NULL, 0) << 20;
+ break;
case 'o':
diroff = strtoul(optarg, NULL, 0);
break;
@@ -197,6 +205,7 @@ static const char usage_info[] =
" -s display strip offsets and byte counts\n"
" -w display raw data in words rather than bytes\n"
" -z enable strip chopping\n"
+" -M size set the memory allocation limit in MiB. 0 to disable limit\n"
" -# set initial directory (first directory is # 0)\n"
;
@@ -432,20 +441,29 @@ TIFFReadRawDataStriped(TIFF* tif, int bitrev)
TIFFGetField(tif, TIFFTAG_STRIPBYTECOUNTS, &stripbc);
if (stripbc != NULL && nstrips > 0) {
- uint32_t bufsize = (uint32_t) stripbc[0];
- tdata_t buf = _TIFFmalloc(bufsize);
+ uint32_t bufsize = 0;
+ tdata_t buf = NULL;
tstrip_t s;
for (s = 0; s < nstrips; s++) {
- if (stripbc[s] > bufsize) {
- buf = _TIFFrealloc(buf, (tmsize_t)stripbc[s]);
+ if (stripbc[s] > bufsize || buf == NULL) {
+ tdata_t newbuf;
+ if (maxMalloc != 0 && stripbc[s] > (uint64_t)maxMalloc)
+ {
+ fprintf(stderr,
+ "Memory allocation attempt %" TIFF_SSIZE_FORMAT " over memory limit (%" TIFF_SSIZE_FORMAT ")",
+ (tmsize_t)stripbc[s], maxMalloc);
+ break;
+ }
+ newbuf = _TIFFrealloc(buf, (tmsize_t)stripbc[s]);
+ if (newbuf == NULL) {
+ fprintf(stderr,
+ "Cannot allocate buffer to read strip %"PRIu32"\n",
+ s);
+ break;
+ }
bufsize = (uint32_t) stripbc[s];
- }
- if (buf == NULL) {
- fprintf(stderr,
- "Cannot allocate buffer to read strip %"PRIu32"\n",
- s);
- break;
+ buf = newbuf;
}
if (TIFFReadRawStrip(tif, s, buf, (tmsize_t) stripbc[s]) < 0) {
fprintf(stderr, "Error reading strip %"PRIu32"\n",
@@ -485,15 +503,24 @@ TIFFReadRawDataTiled(TIFF* tif, int bitrev)
uint32_t t;
for (t = 0; t < ntiles; t++) {
- if (buf == NULL || tilebc[t] > bufsize) {
- buf = _TIFFrealloc(buf, (tmsize_t)tilebc[t]);
- bufsize = tilebc[t];
- }
- if (buf == NULL) {
- fprintf(stderr,
- "Cannot allocate buffer to read tile %"PRIu32"\n",
- t);
- break;
+ if (tilebc[t] > bufsize || buf == NULL) {
+ tdata_t newbuf;
+ if (maxMalloc != 0 && tilebc[t] > (uint64_t)maxMalloc)
+ {
+ fprintf(stderr,
+ "Memory allocation attempt %" TIFF_SSIZE_FORMAT " over memory limit (%" TIFF_SSIZE_FORMAT ")",
+ (tmsize_t)tilebc[t], maxMalloc);
+ break;
+ }
+ newbuf = _TIFFrealloc(buf, (tmsize_t)tilebc[t]);
+ if (newbuf == NULL) {
+ fprintf(stderr,
+ "Cannot allocate buffer to read tile %"PRIu32"\n",
+ t);
+ break;
+ }
+ bufsize = (uint32_t) tilebc[t];
+ buf = newbuf;
}
if (TIFFReadRawTile(tif, t, buf, (tmsize_t)tilebc[t]) < 0) {
fprintf(stderr, "Error reading tile %"PRIu32"\n",