enforce (configurable) memory limit in tiff2rgba

fixes #207
fixes #209
This commit is contained in:
Thomas Bernard 2020-11-15 17:02:51 +01:00
parent dadd8c7dce
commit 98a254f5b9

View File

@ -60,6 +60,10 @@ uint32 rowsperstrip = (uint32) -1;
int process_by_block = 0; /* default is whole image at once */ int process_by_block = 0; /* default is whole image at once */
int no_alpha = 0; int no_alpha = 0;
int bigtiff_output = 0; int bigtiff_output = 0;
#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 int tiffcvt(TIFF* in, TIFF* out); static int tiffcvt(TIFF* in, TIFF* out);
@ -75,8 +79,11 @@ main(int argc, char* argv[])
extern char *optarg; extern char *optarg;
#endif #endif
while ((c = getopt(argc, argv, "c:r:t:bn8h")) != -1) while ((c = getopt(argc, argv, "c:r:t:bn8hM:")) != -1)
switch (c) { switch (c) {
case 'M':
maxMalloc = (tmsize_t)strtoul(optarg, NULL, 0) << 20;
break;
case 'b': case 'b':
process_by_block = 1; process_by_block = 1;
break; break;
@ -405,6 +412,12 @@ cvt_whole_image( TIFF *in, TIFF *out )
(unsigned long)width, (unsigned long)height); (unsigned long)width, (unsigned long)height);
return 0; return 0;
} }
if (maxMalloc != 0 && (tmsize_t)pixel_count * (tmsize_t)sizeof(uint32) > maxMalloc) {
TIFFError(TIFFFileName(in),
"Raster size " TIFF_UINT64_FORMAT " over memory limit (" TIFF_UINT64_FORMAT "), try -b option.",
(uint64)pixel_count * sizeof(uint32), (uint64)maxMalloc);
return 0;
}
rowsperstrip = TIFFDefaultStripSize(out, rowsperstrip); rowsperstrip = TIFFDefaultStripSize(out, rowsperstrip);
TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, rowsperstrip); TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
@ -530,6 +543,13 @@ tiffcvt(TIFF* in, TIFF* out)
TIFFSetField(out, TIFFTAG_SOFTWARE, TIFFGetVersion()); TIFFSetField(out, TIFFTAG_SOFTWARE, TIFFGetVersion());
CopyField(TIFFTAG_DOCUMENTNAME, stringv); CopyField(TIFFTAG_DOCUMENTNAME, stringv);
if (maxMalloc != 0 && TIFFStripSize(in) > maxMalloc)
{
TIFFError(TIFFFileName(in),
"Strip Size " TIFF_UINT64_FORMAT " over memory limit (" TIFF_UINT64_FORMAT ")",
(uint64)TIFFStripSize(in), (uint64)maxMalloc);
return 0;
}
if( process_by_block && TIFFIsTiled( in ) ) if( process_by_block && TIFFIsTiled( in ) )
return( cvt_by_tile( in, out ) ); return( cvt_by_tile( in, out ) );
else if( process_by_block ) else if( process_by_block )
@ -539,7 +559,7 @@ tiffcvt(TIFF* in, TIFF* out)
} }
static const char* stuff[] = { static const char* stuff[] = {
"usage: tiff2rgba [-c comp] [-r rows] [-b] [-n] [-8] input... output", "usage: tiff2rgba [-c comp] [-r rows] [-b] [-n] [-8] [-M size] input... output",
"where comp is one of the following compression algorithms:", "where comp is one of the following compression algorithms:",
" jpeg\t\tJPEG encoding", " jpeg\t\tJPEG encoding",
" zip\t\tZip/Deflate encoding", " zip\t\tZip/Deflate encoding",
@ -551,6 +571,7 @@ static const char* stuff[] = {
" -b (progress by block rather than as a whole image)", " -b (progress by block rather than as a whole image)",
" -n don't emit alpha component.", " -n don't emit alpha component.",
" -8 write BigTIFF file instead of ClassicTIFF", " -8 write BigTIFF file instead of ClassicTIFF",
" -M set the memory allocation limit in MiB. 0 to disable limit",
NULL NULL
}; };