diff options
author | Even Rouault <even.rouault@spatialys.com> | 2022-11-22 18:17:34 +0100 |
---|---|---|
committer | Even Rouault <even.rouault@spatialys.com> | 2022-11-22 18:17:34 +0100 |
commit | b88c3f9af25955a0df90a2f4fc2ac75fd4cce209 (patch) | |
tree | 60cc993fd9860cd4998350abcb1762ca9fcd4e29 | |
parent | d95b5b7628da6e0f446f7289059e1248de12dec9 (diff) | |
download | libtiff-git-b88c3f9af25955a0df90a2f4fc2ac75fd4cce209.tar.gz |
Add TIFFOpenOptionsSetMaxSingleMemAlloc()
to define a limit in bytes for a single memory allocation done by libtiff.
Also add internal functions used in replacement of the non Ext ones:
void* _TIFFmallocExt(TIFF* tif, tmsize_t s);
void* _TIFFcallocExt(TIFF* tif, tmsize_t nmemb, tmsize_t siz);
void* _TIFFreallocExt(TIFF* tif, void* p, tmsize_t s);
void _TIFFfreeExt(TIFF* tif, void* p);
-rw-r--r-- | libtiff/libtiff.def | 1 | ||||
-rw-r--r-- | libtiff/libtiff.map | 1 | ||||
-rw-r--r-- | libtiff/tif_open.c | 57 | ||||
-rw-r--r-- | libtiff/tiffio.h | 1 | ||||
-rw-r--r-- | libtiff/tiffiop.h | 7 |
5 files changed, 65 insertions, 2 deletions
diff --git a/libtiff/libtiff.def b/libtiff/libtiff.def index 975ad1fd..22cbb1aa 100644 --- a/libtiff/libtiff.def +++ b/libtiff/libtiff.def @@ -85,6 +85,7 @@ EXPORTS TIFFAccessTagMethods TIFFOpenWExt TIFFOpenOptionsAlloc TIFFOpenOptionsFree + TIFFOpenOptionsSetMaxSingleMemAlloc TIFFOpenOptionsSetErrorHandlerExtR TIFFOpenOptionsSetWarningHandlerExtR TIFFPrintDirectory diff --git a/libtiff/libtiff.map b/libtiff/libtiff.map index c811a751..05da6d7e 100644 --- a/libtiff/libtiff.map +++ b/libtiff/libtiff.map @@ -210,6 +210,7 @@ LIBTIFF_4.5 { TIFFWarningExtR; TIFFOpenOptionsAlloc; TIFFOpenOptionsFree; + TIFFOpenOptionsSetMaxSingleMemAlloc; TIFFOpenOptionsSetErrorHandlerExtR; TIFFOpenOptionsSetWarningHandlerExtR; } LIBTIFF_4.4; diff --git a/libtiff/tif_open.c b/libtiff/tif_open.c index 23e206d7..76158096 100644 --- a/libtiff/tif_open.c +++ b/libtiff/tif_open.c @@ -78,6 +78,15 @@ void TIFFOpenOptionsFree(TIFFOpenOptions* opts) _TIFFfree(opts); } +/** Define a limit in bytes for a single memory allocation done by libtiff. + * If max_single_mem_alloc is set to 0, no other limit that the underlying + * _TIFFmalloc() will be applied, which is the default. + */ +void TIFFOpenOptionsSetMaxSingleMemAlloc(TIFFOpenOptions* opts, tmsize_t max_single_mem_alloc) +{ + opts->max_single_mem_alloc = max_single_mem_alloc; +} + void TIFFOpenOptionsSetErrorHandlerExtR(TIFFOpenOptions* opts, TIFFErrorHandlerExtR handler, void* errorhandler_user_data) { opts->errorhandler = handler; @@ -90,6 +99,43 @@ void TIFFOpenOptionsSetWarningHandlerExtR(TIFFOpenOptions* opts, TIFFErrorHandle opts->warnhandler_user_data = warnhandler_user_data; } +/** malloc() version that takes into account memory-specific open options */ +void* _TIFFmallocExt(TIFF* tif, tmsize_t s) +{ + if (tif != NULL && tif->tif_max_single_mem_alloc > 0 && s > tif->tif_max_single_mem_alloc) + return NULL; + return _TIFFmalloc(s); +} + +/** calloc() version that takes into account memory-specific open options */ +void* _TIFFcallocExt(TIFF* tif, tmsize_t nmemb, tmsize_t siz) +{ + if( tif != NULL ) + { + if (nmemb <= 0 || siz <= 0 || nmemb > TIFF_TMSIZE_T_MAX / siz) + return NULL; + if (tif->tif_max_single_mem_alloc > 0 && nmemb * siz > tif->tif_max_single_mem_alloc) + return NULL; + } + return _TIFFcalloc(nmemb, siz); +} + +/** realloc() version that takes into account memory-specific open options */ +void* _TIFFreallocExt(TIFF* tif, void* p, tmsize_t s) +{ + if (tif != NULL && tif->tif_max_single_mem_alloc > 0 && s > tif->tif_max_single_mem_alloc) + return NULL; + return _TIFFrealloc(p, s); +} + +/** free() version that takes into account memory-specific open options */ +void _TIFFfreeExt(TIFF* tif, void* p) +{ + (void)tif; + _TIFFfree(p); +} + + TIFF* TIFFClientOpen( const char* name, const char* mode, @@ -160,7 +206,13 @@ TIFFClientOpenExt( m = _TIFFgetMode(opts, clientdata, mode, module); if (m == -1) goto bad2; - tif = (TIFF *)_TIFFmalloc((tmsize_t)(sizeof (TIFF) + strlen(name) + 1)); + tmsize_t size_to_alloc = (tmsize_t)(sizeof (TIFF) + strlen(name) + 1); + if (opts && opts->max_single_mem_alloc > 0 && + size_to_alloc > opts->max_single_mem_alloc) { + _TIFFErrorEarly(opts, clientdata, module, "%s: Out of memory (TIFF structure)", name); + goto bad2; + } + tif = (TIFF *)_TIFFmallocExt(NULL, size_to_alloc); if (tif == NULL) { _TIFFErrorEarly(opts, clientdata, module, "%s: Out of memory (TIFF structure)", name); goto bad2; @@ -187,12 +239,13 @@ TIFFClientOpenExt( tif->tif_errorhandler_user_data = opts->errorhandler_user_data; tif->tif_warnhandler = opts->warnhandler; tif->tif_warnhandler_user_data = opts->warnhandler_user_data; + tif->tif_max_single_mem_alloc = opts->max_single_mem_alloc; } if (!readproc || !writeproc || !seekproc || !closeproc || !sizeproc) { TIFFErrorExtR(tif, module, "One of the client procedures is NULL pointer."); - _TIFFfree(tif); + _TIFFfreeExt(NULL, tif); goto bad2; } diff --git a/libtiff/tiffio.h b/libtiff/tiffio.h index 7d12a88c..54a646d8 100644 --- a/libtiff/tiffio.h +++ b/libtiff/tiffio.h @@ -466,6 +466,7 @@ extern void TIFFErrorExtR(TIFF*, const char*, const char*, ...) TIFF_ATTRIBUTE(( typedef struct TIFFOpenOptions TIFFOpenOptions; extern TIFFOpenOptions* TIFFOpenOptionsAlloc(void); extern void TIFFOpenOptionsFree(TIFFOpenOptions*); +extern void TIFFOpenOptionsSetMaxSingleMemAlloc(TIFFOpenOptions* opts, tmsize_t max_single_mem_alloc); extern void TIFFOpenOptionsSetErrorHandlerExtR(TIFFOpenOptions* opts, TIFFErrorHandlerExtR handler, void* errorhandler_user_data); extern void TIFFOpenOptionsSetWarningHandlerExtR(TIFFOpenOptions* opts, TIFFErrorHandlerExtR handler, void* warnhandler_user_data); diff --git a/libtiff/tiffiop.h b/libtiff/tiffiop.h index d52fc45f..2399d1e1 100644 --- a/libtiff/tiffiop.h +++ b/libtiff/tiffiop.h @@ -202,6 +202,7 @@ struct tiff { void* tif_errorhandler_user_data; TIFFErrorHandlerExtR tif_warnhandler; void* tif_warnhandler_user_data; + tmsize_t tif_max_single_mem_alloc; /* in bytes. 0 for unlimited */ }; struct TIFFOpenOptions @@ -210,6 +211,7 @@ struct TIFFOpenOptions void* errorhandler_user_data; /* may be NULL */ TIFFErrorHandlerExtR warnhandler; /* may be NULL */ void* warnhandler_user_data; /* may be NULL */ + tmsize_t max_single_mem_alloc; /* in bytes. 0 for unlimited */ }; #define isPseudoTag(t) (t > 0xffff) /* is tag value normal or pseudo */ @@ -448,6 +450,11 @@ extern const TIFFCodec _TIFFBuiltinCODECS[]; extern void TIFFCIELab16ToXYZ(TIFFCIELabToRGB *, uint32_t l, int32_t a, int32_t b, float *, float *, float *); +extern void* _TIFFmallocExt(TIFF* tif, tmsize_t s); +extern void* _TIFFcallocExt(TIFF* tif, tmsize_t nmemb, tmsize_t siz); +extern void* _TIFFreallocExt(TIFF* tif, void* p, tmsize_t s); +extern void _TIFFfreeExt(TIFF* tif, void* p); + #if defined(__cplusplus) } #endif |