libtiff: tiffinfo, tiffcp, tiffcrop, tiffsplit, tiff2rgba, tiff2ps: use TIFFOpenOptionsSetMaxSingleMemAlloc()

From 0ad56c292a1a4d3c7d2f777ea4684b5912443ff3 Mon Sep 17 00:00:00 2001
From: Even Rouault <[EMAIL REDACTED]>
Date: Tue, 22 Nov 2022 18:07:25 +0100
Subject: [PATCH] tiffinfo, tiffcp, tiffcrop, tiffsplit, tiff2rgba, tiff2ps:
 use TIFFOpenOptionsSetMaxSingleMemAlloc()

---
 tools/tiff2ps.c   |  8 +++++++-
 tools/tiff2rgba.c | 15 ++++++++++++---
 tools/tiffcp.c    | 18 +++++++++++++++---
 tools/tiffcrop.c  | 17 +++++++++++++++--
 tools/tiffinfo.c  |  9 ++++++++-
 tools/tiffsplit.c | 14 ++++++++++++--
 6 files changed, 69 insertions(+), 12 deletions(-)

diff --git a/tools/tiff2ps.c b/tools/tiff2ps.c
index 4355a84b..0d1656b9 100644
--- a/tools/tiff2ps.c
+++ b/tools/tiff2ps.c
@@ -485,7 +485,13 @@ main(int argc, char* argv[])
 	  PSavoiddeadzone = FALSE;
 
 	for (; argc - optind > 0; optind++) {
-		TIFF* tif = TIFFOpen(filename = argv[optind], "r");
+		TIFFOpenOptions* opts = TIFFOpenOptionsAlloc();
+		if (opts == NULL) {
+		    return EXIT_FAILURE;
+		}
+		TIFFOpenOptionsSetMaxSingleMemAlloc(opts, maxMalloc);
+		TIFF* tif = TIFFOpenExt(filename = argv[optind], "r", opts);
+		TIFFOpenOptionsFree(opts);
 		if (tif != NULL) {
 			if (dirnum != -1
                             && !TIFFSetDirectory(tif, (tdir_t)dirnum))
diff --git a/tools/tiff2rgba.c b/tools/tiff2rgba.c
index 8af9a333..011544a4 100644
--- a/tools/tiff2rgba.c
+++ b/tools/tiff2rgba.c
@@ -129,24 +129,33 @@ main(int argc, char* argv[])
 	if (argc - optind < 2)
 		usage(EXIT_FAILURE);
 
-	out = TIFFOpen(argv[argc-1], bigtiff_output?"w8":"w");
-	if (out == NULL)
+	TIFFOpenOptions* opts = TIFFOpenOptionsAlloc();
+	if (opts == NULL) {
+	    return EXIT_FAILURE;
+	}
+	TIFFOpenOptionsSetMaxSingleMemAlloc(opts, maxMalloc);
+	out = TIFFOpenExt(argv[argc-1], bigtiff_output?"w8":"w", opts);
+	if (out == NULL) {
+		TIFFOpenOptionsFree(opts);
 		return (EXIT_FAILURE);
+	}
 
 	for (; optind < argc-1; optind++) {
-		in = TIFFOpen(argv[optind], "r");
+		in = TIFFOpenExt(argv[optind], "r", opts);
 		if (in != NULL) {
 			do {
 				if (!tiffcvt(in, out) ||
 				    !TIFFWriteDirectory(out)) {
 					(void) TIFFClose(out);
 					(void) TIFFClose(in);
+					TIFFOpenOptionsFree(opts);
 					return (1);
 				}
 			} while (TIFFReadDirectory(in));
 			(void) TIFFClose(in);
 		}
 	}
+	TIFFOpenOptionsFree(opts);
 	(void) TIFFClose(out);
 	return (EXIT_SUCCESS);
 }
diff --git a/tools/tiffcp.c b/tools/tiffcp.c
index 07ed0ebc..4b9f1e77 100644
--- a/tools/tiffcp.c
+++ b/tools/tiffcp.c
@@ -159,9 +159,14 @@ static TIFF* openSrcImage (char **imageSpec)
 	TIFF *tif;
 	char *fn = *imageSpec;
 	*imageSpec = strchr (fn, comma);
+	TIFFOpenOptions* opts = TIFFOpenOptionsAlloc();
+	if (opts == NULL) {
+	    return NULL;
+	}
+    TIFFOpenOptionsSetMaxSingleMemAlloc(opts, maxMalloc);
 	if (*imageSpec) {  /* there is at least one image number specifier */
 		**imageSpec = '\0';
-		tif = TIFFOpen (fn, mode);
+		tif = TIFFOpenExt (fn, mode, opts);
 		/* but, ignore any single trailing comma */
 		if (!(*imageSpec)[1]) {*imageSpec = NULL; return tif;}
 		if (tif) {
@@ -172,7 +177,8 @@ static TIFF* openSrcImage (char **imageSpec)
 			}
 		}
 	}else
-		tif = TIFFOpen (fn, mode);
+		tif = TIFFOpenExt (fn, mode, opts);
+	TIFFOpenOptionsFree(opts);
 	return tif;
 }
 
@@ -317,7 +323,13 @@ main(int argc, char* argv[])
 		}
 	if (argc - optind < 2)
 		usage(EXIT_FAILURE);
-	out = TIFFOpen(argv[argc-1], mode);
+	TIFFOpenOptions* opts = TIFFOpenOptionsAlloc();
+	if (opts == NULL) {
+	    return EXIT_FAILURE;
+	}
+	TIFFOpenOptionsSetMaxSingleMemAlloc(opts, maxMalloc);
+	out = TIFFOpenExt(argv[argc-1], mode, opts);
+	TIFFOpenOptionsFree(opts);
 	if (out == NULL)
 		return (EXIT_FAILURE);
 	if ((argc - optind) == 2)
diff --git a/tools/tiffcrop.c b/tools/tiffcrop.c
index da28a750..2421aa3d 100644
--- a/tools/tiffcrop.c
+++ b/tools/tiffcrop.c
@@ -2277,7 +2277,13 @@ update_output_file (TIFF **tiffout, char *mode, int autoindex,
       }
     exportname[sizeof(exportname) - 1] = '\0';
 
-    *tiffout = TIFFOpen(exportname, mode);
+    TIFFOpenOptions* opts = TIFFOpenOptionsAlloc();
+    if (opts == NULL) {
+        return 1;
+    }
+    TIFFOpenOptionsSetMaxSingleMemAlloc(opts, maxMalloc);
+    *tiffout = TIFFOpenExt(exportname, mode, opts);
+    TIFFOpenOptionsFree(opts);
     if (*tiffout == NULL)
       {
       TIFFError("update_output_file", "Unable to open output file %s", exportname);
@@ -2359,7 +2365,14 @@ main(int argc, char* argv[])
   /* Read multiple input files and write to output file(s) */
   while (optind < argc - 1)
     {
-    in = TIFFOpen (argv[optind], "r");
+
+    TIFFOpenOptions* opts = TIFFOpenOptionsAlloc();
+    if (opts == NULL) {
+        return -3;
+    }
+    TIFFOpenOptionsSetMaxSingleMemAlloc(opts, maxMalloc);
+    in = TIFFOpenExt(argv[optind], "r", opts);
+    TIFFOpenOptionsFree(opts);
     if (in == NULL)
       return (-3);
 
diff --git a/tools/tiffinfo.c b/tools/tiffinfo.c
index c3d79eb7..ac7559f9 100644
--- a/tools/tiffinfo.c
+++ b/tools/tiffinfo.c
@@ -152,7 +152,14 @@ main(int argc, char* argv[])
 	for (; optind < argc; optind++) {
 		if (multiplefiles)
 			printf("File %s:\n", argv[optind]);
-		tif = TIFFOpen(argv[optind], chopstrips ? "rC" : "rc");
+		TIFFOpenOptions* opts = TIFFOpenOptionsAlloc();
+		if (opts == NULL) {
+		    status = EXIT_FAILURE;
+		    break;
+		}
+		TIFFOpenOptionsSetMaxSingleMemAlloc(opts, maxMalloc);
+		tif = TIFFOpenExt(argv[optind], chopstrips ? "rC" : "rc", opts);
+		TIFFOpenOptionsFree(opts);
 		if (tif != NULL) {
 			if (dirnum != -1) {
 				if (TIFFSetDirectory(tif, (tdir_t) dirnum))
diff --git a/tools/tiffsplit.c b/tools/tiffsplit.c
index 7c05391d..08c93eec 100644
--- a/tools/tiffsplit.c
+++ b/tools/tiffsplit.c
@@ -126,9 +126,15 @@ main(int argc, char* argv[])
 		fname[sizeof(fname) - 1] = '\0';
 	}
 
-	in = TIFFOpen(argv[optind], "r");
+	TIFFOpenOptions* opts = TIFFOpenOptionsAlloc();
+	if (opts == NULL) {
+	    return EXIT_FAILURE;
+	}
+	TIFFOpenOptionsSetMaxSingleMemAlloc(opts, maxMalloc);
+	in = TIFFOpenExt(argv[optind], "r", opts);
 	if (in == NULL) {
 		fprintf(stderr, "tiffsplit: Error: Could not open %s \n", argv[optind]);
+        TIFFOpenOptionsFree(opts);
 		usage(EXIT_FAILURE);
 	}
 
@@ -143,23 +149,26 @@ main(int argc, char* argv[])
 		if (!path) {
 			fprintf(stderr, "tiffsplit: Error: Can't allocate %"TIFF_SSIZE_FORMAT" bytes for path-variable.\n", path_len);
 			TIFFClose(in);
+			TIFFOpenOptionsFree(opts);
 			return (EXIT_FAILURE);
 		}
 		strncpy(path, fname, path_len);
 		path[path_len - 1] = '\0';
 		strncat(path, TIFF_SUFFIX, path_len - strlen(path) - 1);
-		out = TIFFOpen(path, TIFFIsBigEndian(in) ? "wb" : "wl");
+		out = TIFFOpenExt(path, TIFFIsBigEndian(in) ? "wb" : "wl", opts);
 
 		if (out == NULL) {
 			TIFFClose(in);
 			fprintf(stderr, "tiffsplit: Error: Could not open output file %s \n", path);
 			_TIFFfree(path);
+			TIFFOpenOptionsFree(opts);
 			return (EXIT_FAILURE);
 		}
 		_TIFFfree(path);
 		if (!tiffcp(in, out)) {
 			TIFFClose(in);
 			TIFFClose(out);
+			TIFFOpenOptionsFree(opts);
 			fprintf(stderr, "tiffsplit: Error: Could not copy data from input to output.\n");
 			return (EXIT_FAILURE);
 
@@ -167,6 +176,7 @@ main(int argc, char* argv[])
 		TIFFClose(out);
 	} while (TIFFReadDirectory(in));
 
+	TIFFOpenOptionsFree(opts);
 	(void)TIFFClose(in);
 
 	return (EXIT_SUCCESS);