Merge branch 'out-of-memory' into 'master'
tiffcp/tiff2pdf/tiff2ps: enforce maximum malloc size Closes #153, #84, #116 et #115 See merge request libtiff/libtiff!130
This commit is contained in:
commit
6c63f17749
@ -212,6 +212,9 @@ Set document information subject, overrides image image description default.
|
||||
.BI \-k " keywords"
|
||||
Set document information keywords.
|
||||
.TP
|
||||
.BI \-m " size"
|
||||
Set memory allocation limit (in MiB). Default is 256MiB. Set to 0 to disable the limit.
|
||||
.TP
|
||||
.B \-h
|
||||
List usage reminder to stderr and exit.
|
||||
.SH EXAMPLES
|
||||
|
@ -160,6 +160,10 @@ options.
|
||||
Specify the left margin for the output (in inches). This does not affect
|
||||
the width of the printed image.
|
||||
.TP
|
||||
.BI \-M " size"
|
||||
Set maximum memory allocation size (in MiB). The default is 256MiB.
|
||||
Set to 0 to disable the limit.
|
||||
.TP
|
||||
.B \-m
|
||||
Where possible render using the
|
||||
.I imagemask
|
||||
|
@ -247,6 +247,10 @@ Note that
|
||||
.B \-,=
|
||||
with whitespace immediately following will disable
|
||||
the special meaning of the `,' entirely. See examples.
|
||||
.TP
|
||||
.BI \-m " size"
|
||||
Set maximum memory allocation size (in MiB). The default is 256MiB.
|
||||
Set to 0 to disable the limit.
|
||||
.SH EXAMPLES
|
||||
The following concatenates two files and writes the result using
|
||||
.SM LZW
|
||||
|
@ -70,6 +70,8 @@ extern int getopt(int argc, char * const argv[], const char *optstring);
|
||||
|
||||
#define TIFF_DIR_MAX 65534
|
||||
|
||||
#define DEFAULT_MAX_MALLOC (256 * 1024 * 1024)
|
||||
|
||||
/* This type is of PDF color spaces. */
|
||||
typedef enum {
|
||||
T2P_CS_BILEVEL = 0x01, /* Bilevel, black and white */
|
||||
@ -176,6 +178,7 @@ typedef struct {
|
||||
uint16 tiff_orientation;
|
||||
toff_t tiff_dataoffset;
|
||||
tsize_t tiff_datasize;
|
||||
tsize_t tiff_maxdatasize;
|
||||
uint16 tiff_resunit;
|
||||
uint16 pdf_centimeters;
|
||||
uint16 pdf_overrideres;
|
||||
@ -622,8 +625,11 @@ int main(int argc, char** argv){
|
||||
|
||||
while (argv &&
|
||||
(c = getopt(argc, argv,
|
||||
"o:q:u:x:y:w:l:r:p:e:c:a:t:s:k:jzndifbhF")) != -1){
|
||||
"m:o:q:u:x:y:w:l:r:p:e:c:a:t:s:k:jzndifbhF")) != -1){
|
||||
switch (c) {
|
||||
case 'm':
|
||||
t2p->tiff_maxdatasize = (tsize_t)strtoul(optarg, NULL, 0) << 20;
|
||||
break;
|
||||
case 'o':
|
||||
outfilename = optarg;
|
||||
break;
|
||||
@ -869,6 +875,7 @@ void tiff2pdf_usage(){
|
||||
" -s: sets document subject, overrides image image description default",
|
||||
" -k: sets document keywords",
|
||||
" -b: set PDF \"Interpolate\" user preference",
|
||||
" -m: set memory allocation limit (in MiB). set to 0 to disable limit",
|
||||
" -h: usage",
|
||||
NULL
|
||||
};
|
||||
@ -964,6 +971,7 @@ T2P* t2p_init()
|
||||
t2p->pdf_defaultpagewidth=612.0;
|
||||
t2p->pdf_defaultpagelength=792.0;
|
||||
t2p->pdf_xrefcount=3; /* Catalog, Info, Pages */
|
||||
t2p->tiff_maxdatasize = DEFAULT_MAX_MALLOC;
|
||||
|
||||
return(t2p);
|
||||
}
|
||||
@ -5626,6 +5634,13 @@ tsize_t t2p_write_pdf(T2P* t2p, TIFF* input, TIFF* output){
|
||||
written += t2p_write_pdf_stream_start(output);
|
||||
streamlen=written;
|
||||
t2p_read_tiff_size(t2p, input);
|
||||
if (t2p->tiff_maxdatasize && (t2p->tiff_datasize > t2p->tiff_maxdatasize)) {
|
||||
TIFFError(TIFF2PDF_MODULE,
|
||||
"Allocation of " TIFF_UINT64_FORMAT " bytes is forbidden. Limit is " TIFF_UINT64_FORMAT ". Use -m option to change limit",
|
||||
(uint64)t2p->tiff_datasize, (uint64)t2p->tiff_maxdatasize);
|
||||
t2p->t2p_error = T2P_ERR_ERROR;
|
||||
return (0);
|
||||
}
|
||||
written += t2p_readwrite_pdf_image(t2p, input, output);
|
||||
t2p_write_advance_directory(t2p, output);
|
||||
if(t2p->t2p_error!=T2P_ERR_OK){return(0);}
|
||||
|
@ -174,6 +174,12 @@
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#define DEFAULT_MAX_MALLOC (256 * 1024 * 1024)
|
||||
|
||||
/* malloc size limit (in bytes)
|
||||
* disabled when set to 0 */
|
||||
static tmsize_t maxMalloc = DEFAULT_MAX_MALLOC;
|
||||
|
||||
int ascii85 = FALSE; /* use ASCII85 encoding */
|
||||
int interpolate = TRUE; /* interpolate level2 image */
|
||||
int level2 = FALSE; /* generate PostScript level 2 */
|
||||
@ -234,6 +240,20 @@ tsize_t Ascii85EncodeBlock( uint8 * ascii85_p, unsigned f_eod, const uint8 * raw
|
||||
|
||||
static void usage(int);
|
||||
|
||||
/**
|
||||
* This custom malloc function enforce a maximum allocation size
|
||||
*/
|
||||
static void* limitMalloc(tmsize_t s)
|
||||
{
|
||||
if (maxMalloc && (s > maxMalloc)) {
|
||||
fprintf(stderr, "MemoryLimitError: allocation of " TIFF_UINT64_FORMAT " bytes is forbidden. Limit is " TIFF_UINT64_FORMAT ".\n",
|
||||
(uint64)s, (uint64)maxMalloc);
|
||||
fprintf(stderr, " use -M option to change limit.\n");
|
||||
return NULL;
|
||||
}
|
||||
return _TIFFmalloc(s);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
@ -252,8 +272,11 @@ main(int argc, char* argv[])
|
||||
|
||||
pageOrientation[0] = '\0';
|
||||
|
||||
while ((c = getopt(argc, argv, "b:d:h:H:W:L:i:w:l:o:O:P:C:r:t:acemxyzps1238DT")) != -1)
|
||||
while ((c = getopt(argc, argv, "b:d:h:H:W:L:M:i:w:l:o:O:P:C:r:t:acemxyzps1238DT")) != -1)
|
||||
switch (c) {
|
||||
case 'M':
|
||||
maxMalloc = (tmsize_t)strtoul(optarg, NULL, 0) << 20;
|
||||
break;
|
||||
case 'b':
|
||||
bottommargin = atof(optarg);
|
||||
break;
|
||||
@ -2187,7 +2210,7 @@ PS_Lvl2page(FILE* fd, TIFF* tif, uint32 w, uint32 h)
|
||||
else
|
||||
chunk_size = TIFFStripSize(tif);
|
||||
}
|
||||
buf_data = (unsigned char *)_TIFFmalloc(chunk_size);
|
||||
buf_data = (unsigned char *)limitMalloc(chunk_size);
|
||||
if (!buf_data) {
|
||||
TIFFError(filename, "Can't alloc %lu bytes for %s.",
|
||||
(unsigned long) chunk_size, tiled_image ? "tiles" : "strips");
|
||||
@ -2205,7 +2228,7 @@ PS_Lvl2page(FILE* fd, TIFF* tif, uint32 w, uint32 h)
|
||||
* 5*chunk_size/4.
|
||||
*/
|
||||
|
||||
ascii85_p = _TIFFmalloc( (chunk_size+(chunk_size/2)) + 8 );
|
||||
ascii85_p = limitMalloc( (chunk_size+(chunk_size/2)) + 8 );
|
||||
|
||||
if ( !ascii85_p ) {
|
||||
_TIFFfree( buf_data );
|
||||
@ -2449,7 +2472,7 @@ PSDataColorContig(FILE* fd, TIFF* tif, uint32 w, uint32 h, int nc)
|
||||
TIFFError(filename, "Inconsistent value of es: %d (samplesperpixel=%u, nc=%d)", es, samplesperpixel, nc);
|
||||
return;
|
||||
}
|
||||
tf_buf = (unsigned char *) _TIFFmalloc(tf_bytesperrow);
|
||||
tf_buf = (unsigned char *) limitMalloc(tf_bytesperrow);
|
||||
if (tf_buf == NULL) {
|
||||
TIFFError(filename, "No space for scanline buffer");
|
||||
return;
|
||||
@ -2517,7 +2540,7 @@ PSDataColorSeparate(FILE* fd, TIFF* tif, uint32 w, uint32 h, int nc)
|
||||
unsigned char *cp, c;
|
||||
|
||||
(void) w;
|
||||
tf_buf = (unsigned char *) _TIFFmalloc(tf_bytesperrow);
|
||||
tf_buf = (unsigned char *) limitMalloc(tf_bytesperrow);
|
||||
if (tf_buf == NULL) {
|
||||
TIFFError(filename, "No space for scanline buffer");
|
||||
return;
|
||||
@ -2563,7 +2586,7 @@ PSDataPalette(FILE* fd, TIFF* tif, uint32 w, uint32 h)
|
||||
return;
|
||||
}
|
||||
nc = 3 * (8 / bitspersample);
|
||||
tf_buf = (unsigned char *) _TIFFmalloc(tf_bytesperrow);
|
||||
tf_buf = (unsigned char *) limitMalloc(tf_bytesperrow);
|
||||
if (tf_buf == NULL) {
|
||||
TIFFError(filename, "No space for scanline buffer");
|
||||
return;
|
||||
@ -2628,7 +2651,7 @@ PSDataBW(FILE* fd, TIFF* tif, uint32 w, uint32 h)
|
||||
#endif
|
||||
|
||||
(void) w; (void) h;
|
||||
tf_buf = (unsigned char *) _TIFFmalloc(stripsize);
|
||||
tf_buf = (unsigned char *) limitMalloc(stripsize);
|
||||
if (tf_buf == NULL) {
|
||||
TIFFError(filename, "No space for scanline buffer");
|
||||
return;
|
||||
@ -2648,7 +2671,7 @@ PSDataBW(FILE* fd, TIFF* tif, uint32 w, uint32 h)
|
||||
* 5*stripsize/4.
|
||||
*/
|
||||
|
||||
ascii85_p = _TIFFmalloc( (stripsize+(stripsize/2)) + 8 );
|
||||
ascii85_p = limitMalloc( (stripsize+(stripsize/2)) + 8 );
|
||||
|
||||
if ( !ascii85_p ) {
|
||||
_TIFFfree( tf_buf );
|
||||
@ -2775,7 +2798,7 @@ PSRawDataBW(FILE* fd, TIFF* tif, uint32 w, uint32 h)
|
||||
bufsize = (uint32) bc[s];
|
||||
}
|
||||
|
||||
tf_buf = (unsigned char*) _TIFFmalloc(bufsize);
|
||||
tf_buf = (unsigned char*) limitMalloc(bufsize);
|
||||
if (tf_buf == NULL) {
|
||||
TIFFError(filename, "No space for strip buffer");
|
||||
return;
|
||||
@ -2792,7 +2815,7 @@ PSRawDataBW(FILE* fd, TIFF* tif, uint32 w, uint32 h)
|
||||
* 5*bufsize/4.
|
||||
*/
|
||||
|
||||
ascii85_p = _TIFFmalloc( (bufsize+(bufsize/2)) + 8 );
|
||||
ascii85_p = limitMalloc( (bufsize+(bufsize/2)) + 8 );
|
||||
|
||||
if ( !ascii85_p ) {
|
||||
_TIFFfree( tf_buf );
|
||||
@ -3079,6 +3102,7 @@ char* stuff[] = {
|
||||
" -i # enable/disable (Nz/0) pixel interpolation (default: enable)",
|
||||
" -l # set the left margin to # inches",
|
||||
" -m use \"imagemask\" operator instead of \"image\"",
|
||||
" -M size set the memory allocation limit in MiB. 0 to disable limit",
|
||||
" -o # convert directory at file offset # bytes",
|
||||
" -O file write PostScript to file instead of standard output",
|
||||
" -p generate regular (non-encapsulated) PostScript",
|
||||
|
@ -65,6 +65,12 @@ extern int getopt(int argc, char * const argv[], const char *optstring);
|
||||
#define TRUE 1
|
||||
#define FALSE 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 outtiled = -1;
|
||||
static uint32 tilewidth;
|
||||
static uint32 tilelength;
|
||||
@ -94,6 +100,20 @@ static TIFF* bias = NULL;
|
||||
static int pageNum = 0;
|
||||
static int pageInSeq = 0;
|
||||
|
||||
/**
|
||||
* This custom malloc function enforce a maximum allocation size
|
||||
*/
|
||||
static void* limitMalloc(tmsize_t s)
|
||||
{
|
||||
if (maxMalloc && (s > maxMalloc)) {
|
||||
fprintf(stderr, "MemoryLimitError: allocation of " TIFF_UINT64_FORMAT " bytes is forbidden. Limit is " TIFF_UINT64_FORMAT ".\n",
|
||||
(uint64)s, (uint64)maxMalloc);
|
||||
fprintf(stderr, " use -m option to change limit.\n");
|
||||
return NULL;
|
||||
}
|
||||
return _TIFFmalloc(s);
|
||||
}
|
||||
|
||||
static int nextSrcImage (TIFF *tif, char **imageSpec)
|
||||
/*
|
||||
seek to the next image specified in *imageSpec
|
||||
@ -173,8 +193,11 @@ main(int argc, char* argv[])
|
||||
|
||||
*mp++ = 'w';
|
||||
*mp = '\0';
|
||||
while ((c = getopt(argc, argv, ",:b:c:f:l:o:p:r:w:aistBLMC8x")) != -1)
|
||||
while ((c = getopt(argc, argv, "m:,:b:c:f:l:o:p:r:w:aistBLMC8x")) != -1)
|
||||
switch (c) {
|
||||
case 'm':
|
||||
maxMalloc = (tmsize_t)strtoul(optarg, NULL, 0) << 20;
|
||||
break;
|
||||
case ',':
|
||||
if (optarg[0] != '=') usage();
|
||||
comma = optarg[1];
|
||||
@ -423,6 +446,7 @@ char* stuff[] = {
|
||||
" -i ignore read errors",
|
||||
" -b file[,#] bias (dark) monochrome image to be subtracted from all others",
|
||||
" -,=% use % rather than , to separate image #'s (per Note below)",
|
||||
" -m size set maximum memory allocation size (MiB). 0 to disable limit.",
|
||||
"",
|
||||
" -r # make each strip have no more than # rows",
|
||||
" -w # set output tile width (pixels)",
|
||||
@ -859,7 +883,7 @@ DECLAREcpFunc(cpContig2ContigByRow)
|
||||
tdata_t buf;
|
||||
uint32 row;
|
||||
|
||||
buf = _TIFFmalloc(scanlinesize);
|
||||
buf = limitMalloc(scanlinesize);
|
||||
if (!buf)
|
||||
return 0;
|
||||
_TIFFmemset(buf, 0, scanlinesize);
|
||||
@ -933,8 +957,8 @@ DECLAREcpFunc(cpBiasedContig2Contig)
|
||||
subtractLine = lineSubtractFn (sampleBits);
|
||||
if (subtractLine) {
|
||||
uint32 row;
|
||||
buf = _TIFFmalloc(bufSize);
|
||||
biasBuf = _TIFFmalloc(bufSize);
|
||||
buf = limitMalloc(bufSize);
|
||||
biasBuf = limitMalloc(bufSize);
|
||||
for (row = 0; row < imagelength; row++) {
|
||||
if (TIFFReadScanline(in, buf, row, 0) < 0
|
||||
&& !ignore) {
|
||||
@ -996,7 +1020,7 @@ bad:
|
||||
DECLAREcpFunc(cpDecodedStrips)
|
||||
{
|
||||
tsize_t stripsize = TIFFStripSize(in);
|
||||
tdata_t buf = _TIFFmalloc(stripsize);
|
||||
tdata_t buf = limitMalloc(stripsize);
|
||||
|
||||
(void) imagewidth; (void) spp;
|
||||
if (buf) {
|
||||
@ -1046,7 +1070,7 @@ DECLAREcpFunc(cpSeparate2SeparateByRow)
|
||||
tsample_t s;
|
||||
|
||||
(void) imagewidth;
|
||||
buf = _TIFFmalloc(scanlinesize);
|
||||
buf = limitMalloc(scanlinesize);
|
||||
if (!buf)
|
||||
return 0;
|
||||
_TIFFmemset(buf, 0, scanlinesize);
|
||||
@ -1097,8 +1121,8 @@ DECLAREcpFunc(cpContig2SeparateByRow)
|
||||
return 0;
|
||||
}
|
||||
|
||||
inbuf = _TIFFmalloc(scanlinesizein);
|
||||
outbuf = _TIFFmalloc(scanlinesizeout);
|
||||
inbuf = limitMalloc(scanlinesizein);
|
||||
outbuf = limitMalloc(scanlinesizeout);
|
||||
if (!inbuf || !outbuf)
|
||||
goto bad;
|
||||
_TIFFmemset(inbuf, 0, scanlinesizein);
|
||||
@ -1160,8 +1184,8 @@ DECLAREcpFunc(cpSeparate2ContigByRow)
|
||||
return 0;
|
||||
}
|
||||
|
||||
inbuf = _TIFFmalloc(scanlinesizein);
|
||||
outbuf = _TIFFmalloc(scanlinesizeout);
|
||||
inbuf = limitMalloc(scanlinesizein);
|
||||
outbuf = limitMalloc(scanlinesizeout);
|
||||
if (!inbuf || !outbuf)
|
||||
goto bad;
|
||||
_TIFFmemset(inbuf, 0, scanlinesizein);
|
||||
@ -1267,7 +1291,7 @@ cpImage(TIFF* in, TIFF* out, readFunc fin, writeFunc fout,
|
||||
if (scanlinesize
|
||||
&& imagelength
|
||||
&& bytes / (tsize_t)imagelength == scanlinesize) {
|
||||
buf = _TIFFmalloc(bytes);
|
||||
buf = limitMalloc(bytes);
|
||||
if (buf) {
|
||||
if ((*fin)(in, (uint8*)buf, imagelength,
|
||||
imagewidth, spp)) {
|
||||
@ -1315,7 +1339,7 @@ DECLAREreadFunc(readSeparateStripsIntoBuffer)
|
||||
if (!scanlinesize)
|
||||
return 0;
|
||||
|
||||
scanline = _TIFFmalloc(scanlinesize);
|
||||
scanline = limitMalloc(scanlinesize);
|
||||
if (!scanline)
|
||||
return 0;
|
||||
_TIFFmemset(scanline, 0, scanlinesize);
|
||||
@ -1364,7 +1388,7 @@ DECLAREreadFunc(readContigTilesIntoBuffer)
|
||||
uint32 row;
|
||||
|
||||
(void) spp;
|
||||
tilebuf = _TIFFmalloc(tilesize);
|
||||
tilebuf = limitMalloc(tilesize);
|
||||
if (tilebuf == 0)
|
||||
return 0;
|
||||
_TIFFmemset(tilebuf, 0, tilesize);
|
||||
@ -1424,7 +1448,7 @@ DECLAREreadFunc(readSeparateTilesIntoBuffer)
|
||||
return 0;
|
||||
}
|
||||
iskew = imagew - tilew*spp;
|
||||
tilebuf = _TIFFmalloc(tilesize);
|
||||
tilebuf = limitMalloc(tilesize);
|
||||
if (tilebuf == 0)
|
||||
return 0;
|
||||
_TIFFmemset(tilebuf, 0, tilesize);
|
||||
@ -1525,7 +1549,7 @@ DECLAREwriteFunc(writeBufferToSeparateStrips)
|
||||
tstrip_t strip = 0;
|
||||
tsample_t s;
|
||||
|
||||
obuf = _TIFFmalloc(stripsize);
|
||||
obuf = limitMalloc(stripsize);
|
||||
if (obuf == NULL)
|
||||
return (0);
|
||||
_TIFFmemset(obuf, 0, stripsize);
|
||||
@ -1567,7 +1591,7 @@ DECLAREwriteFunc(writeBufferToContigTiles)
|
||||
|
||||
(void) spp;
|
||||
|
||||
obuf = _TIFFmalloc(TIFFTileSize(out));
|
||||
obuf = limitMalloc(TIFFTileSize(out));
|
||||
if (obuf == NULL)
|
||||
return 0;
|
||||
_TIFFmemset(obuf, 0, tilesize);
|
||||
@ -1620,7 +1644,7 @@ DECLAREwriteFunc(writeBufferToSeparateTiles)
|
||||
uint32 row;
|
||||
uint16 bps = 0, bytes_per_sample;
|
||||
|
||||
obuf = _TIFFmalloc(TIFFTileSize(out));
|
||||
obuf = limitMalloc(TIFFTileSize(out));
|
||||
if (obuf == NULL)
|
||||
return 0;
|
||||
_TIFFmemset(obuf, 0, tilesize);
|
||||
|
Loading…
Reference in New Issue
Block a user