summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2022-11-22 18:17:34 +0100
committerEven Rouault <even.rouault@spatialys.com>2022-11-22 18:17:34 +0100
commitb88c3f9af25955a0df90a2f4fc2ac75fd4cce209 (patch)
tree60cc993fd9860cd4998350abcb1762ca9fcd4e29
parentd95b5b7628da6e0f446f7289059e1248de12dec9 (diff)
downloadlibtiff-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.def1
-rw-r--r--libtiff/libtiff.map1
-rw-r--r--libtiff/tif_open.c57
-rw-r--r--libtiff/tiffio.h1
-rw-r--r--libtiff/tiffiop.h7
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