libtiff: Merge branch 'no_sprintf' into 'master'

From 72e90d07fb649f3c356257d4bcf4d9bf4bc618ef Mon Sep 17 00:00:00 2001
From: Mark Mentovai <[EMAIL REDACTED]>
Date: Mon, 7 Nov 2022 09:50:07 -0500
Subject: [PATCH] Replace sprintf calls with snprintf
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This makes it possible to build libtiff without warnings using the macOS
13 SDK. Calls to sprintf are replaced with snprintf, passing appropriate
buffer sizes.

It doesn’t appear that any of the changed uses of sprintf were actually
unsafe, so no behavior change is expected aside from SDK compatibility.

The macOS 13 SDK deprecates sprintf as it’s difficult to use safely. The
deprecation warning message is visible when building C++, but it is not
normally visible when building plain C code due to a quirk in how
sprintf is declared in the SDK. However, the deprecation message is
visible when building plain C under Address Sanitizer
(-fsanitize=address). This discrepancy was discovered at
https://crbug.com/1381706 and reported to Apple with a copy at
https://openradar.appspot.com/FB11761475.

The macOS 13 SDK is packaged in Xcode 14.1, released on 2022-11-01. This
also affects the iOS 16 SDK and other 2022-era Apple OS SDKs packaged in
Xcode 14.0, released on 2022-09-12.

libtiff is visible to the Chromium build via PDFium, and this change is
needed to allow Chromium to move forward to the macOS 13 SDK.

This change is limited to the libtiff directory. Other uses of sprintf
were found in contrib, test, and tools.
---
 libtiff/tif_codec.c    |  3 +-
 libtiff/tif_getimage.c | 68 ++++++++++++++++++++++--------------------
 2 files changed, 37 insertions(+), 34 deletions(-)

diff --git a/libtiff/tif_codec.c b/libtiff/tif_codec.c
index c1c19411..c3fa254a 100644
--- a/libtiff/tif_codec.c
+++ b/libtiff/tif_codec.c
@@ -114,7 +114,8 @@ _notConfigured(TIFF* tif)
 	const TIFFCodec* c = TIFFFindCODEC(tif->tif_dir.td_compression);
         char compression_code[20];
         
-        sprintf(compression_code, "%"PRIu16, tif->tif_dir.td_compression );
+        snprintf(compression_code, sizeof(compression_code), "%"PRIu16,
+                 tif->tif_dir.td_compression );
 	TIFFErrorExtR(tif, tif->tif_name,
                      "%s compression support is not configured", 
                      c ? c->name : compression_code );
diff --git a/libtiff/tif_getimage.c b/libtiff/tif_getimage.c
index c868e0a9..da33ad70 100644
--- a/libtiff/tif_getimage.c
+++ b/libtiff/tif_getimage.c
@@ -49,6 +49,8 @@ static const char photoTag[] = "PhotometricInterpretation";
 #define FLIP_VERTICALLY 0x01
 #define FLIP_HORIZONTALLY 0x02
 
+#define EMSG_BUF_SIZE 1024
+
 /*
  * Color conversion constants. We will define display types here.
  */
@@ -72,14 +74,14 @@ static const TIFFDisplay display_sRGB = {
  * why it is being rejected.
  */
 int
-TIFFRGBAImageOK(TIFF* tif, char emsg[1024])
+TIFFRGBAImageOK(TIFF* tif, char emsg[EMSG_BUF_SIZE])
 {
 	TIFFDirectory* td = &tif->tif_dir;
 	uint16_t photometric;
 	int colorchannels;
 
 	if (!tif->tif_decodestatus) {
-		sprintf(emsg, "Sorry, requested compression method is not configured");
+		snprintf(emsg, EMSG_BUF_SIZE, "Sorry, requested compression method is not configured");
 		return (0);
 	}
 	switch (td->td_bitspersample) {
@@ -90,12 +92,12 @@ TIFFRGBAImageOK(TIFF* tif, char emsg[1024])
 		case 16:
 			break;
 		default:
-			sprintf(emsg, "Sorry, can not handle images with %"PRIu16"-bit samples",
+			snprintf(emsg, EMSG_BUF_SIZE, "Sorry, can not handle images with %"PRIu16"-bit samples",
 			    td->td_bitspersample);
 			return (0);
 	}
         if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP) {
-                sprintf(emsg, "Sorry, can not handle images with IEEE floating-point samples");
+                snprintf(emsg, EMSG_BUF_SIZE, "Sorry, can not handle images with IEEE floating-point samples");
                 return (0);
         }
 	colorchannels = td->td_samplesperpixel - td->td_extrasamples;
@@ -108,7 +110,7 @@ TIFFRGBAImageOK(TIFF* tif, char emsg[1024])
 				photometric = PHOTOMETRIC_RGB;
 				break;
 			default:
-				sprintf(emsg, "Missing needed %s tag", photoTag);
+				snprintf(emsg, EMSG_BUF_SIZE, "Missing needed %s tag", photoTag);
 				return (0);
 		}
 	}
@@ -119,7 +121,7 @@ TIFFRGBAImageOK(TIFF* tif, char emsg[1024])
 			if (td->td_planarconfig == PLANARCONFIG_CONTIG
 			    && td->td_samplesperpixel != 1
 			    && td->td_bitspersample < 8 ) {
-				sprintf(emsg,
+				snprintf(emsg, EMSG_BUF_SIZE,
 				    "Sorry, can not handle contiguous data with %s=%"PRIu16", "
 				    "and %s=%"PRIu16" and Bits/Sample=%"PRIu16"",
 				    photoTag, photometric,
@@ -143,7 +145,7 @@ TIFFRGBAImageOK(TIFF* tif, char emsg[1024])
 			break;
 		case PHOTOMETRIC_RGB:
 			if (colorchannels < 3) {
-				sprintf(emsg, "Sorry, can not handle RGB image with %s=%d",
+				snprintf(emsg, EMSG_BUF_SIZE, "Sorry, can not handle RGB image with %s=%d",
 				    "Color channels", colorchannels);
 				return (0);
 			}
@@ -153,13 +155,13 @@ TIFFRGBAImageOK(TIFF* tif, char emsg[1024])
 				uint16_t inkset;
 				TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset);
 				if (inkset != INKSET_CMYK) {
-					sprintf(emsg,
+					snprintf(emsg, EMSG_BUF_SIZE,
 					    "Sorry, can not handle separated image with %s=%d",
 					    "InkSet", inkset);
 					return 0;
 				}
 				if (td->td_samplesperpixel < 4) {
-					sprintf(emsg,
+					snprintf(emsg, EMSG_BUF_SIZE,
 					    "Sorry, can not handle separated image with %s=%"PRIu16,
 					    "Samples/pixel", td->td_samplesperpixel);
 					return 0;
@@ -168,7 +170,7 @@ TIFFRGBAImageOK(TIFF* tif, char emsg[1024])
 			}
 		case PHOTOMETRIC_LOGL:
 			if (td->td_compression != COMPRESSION_SGILOG) {
-				sprintf(emsg, "Sorry, LogL data must have %s=%d",
+				snprintf(emsg, EMSG_BUF_SIZE, "Sorry, LogL data must have %s=%d",
 				    "Compression", COMPRESSION_SGILOG);
 				return (0);
 			}
@@ -176,17 +178,17 @@ TIFFRGBAImageOK(TIFF* tif, char emsg[1024])
 		case PHOTOMETRIC_LOGLUV:
 			if (td->td_compression != COMPRESSION_SGILOG &&
 			    td->td_compression != COMPRESSION_SGILOG24) {
-				sprintf(emsg, "Sorry, LogLuv data must have %s=%d or %d",
+				snprintf(emsg, EMSG_BUF_SIZE, "Sorry, LogLuv data must have %s=%d or %d",
 				    "Compression", COMPRESSION_SGILOG, COMPRESSION_SGILOG24);
 				return (0);
 			}
 			if (td->td_planarconfig != PLANARCONFIG_CONTIG) {
-				sprintf(emsg, "Sorry, can not handle LogLuv images with %s=%"PRIu16,
+				snprintf(emsg, EMSG_BUF_SIZE, "Sorry, can not handle LogLuv images with %s=%"PRIu16,
 				    "Planarconfiguration", td->td_planarconfig);
 				return (0);
 			}
 			if ( td->td_samplesperpixel != 3 || colorchannels != 3 ) {
-                                sprintf(emsg,
+                                snprintf(emsg, EMSG_BUF_SIZE,
                                         "Sorry, can not handle image with %s=%"PRIu16", %s=%d",
                                         "Samples/pixel", td->td_samplesperpixel,
                                         "colorchannels", colorchannels);
@@ -195,7 +197,7 @@ TIFFRGBAImageOK(TIFF* tif, char emsg[1024])
 			break;
 		case PHOTOMETRIC_CIELAB:
                         if ( td->td_samplesperpixel != 3 || colorchannels != 3 || (td->td_bitspersample != 8 && td->td_bitspersample != 16) ) {
-                                sprintf(emsg,
+                                snprintf(emsg, EMSG_BUF_SIZE,
                                         "Sorry, can not handle image with %s=%"PRIu16", %s=%d and %s=%"PRIu16,
                                         "Samples/pixel", td->td_samplesperpixel,
                                         "colorchannels", colorchannels,
@@ -204,7 +206,7 @@ TIFFRGBAImageOK(TIFF* tif, char emsg[1024])
                         }
 			break;
                 default:
-			sprintf(emsg, "Sorry, can not handle image with %s=%"PRIu16,
+			snprintf(emsg, EMSG_BUF_SIZE, "Sorry, can not handle image with %s=%"PRIu16,
 			    photoTag, photometric);
 			return (0);
 	}
@@ -263,7 +265,7 @@ isCCITTCompression(TIFF* tif)
 }
 
 int
-TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stop, char emsg[1024])
+TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stop, char emsg[EMSG_BUF_SIZE])
 {
 	uint16_t* sampleinfo;
 	uint16_t extrasamples;
@@ -302,7 +304,7 @@ TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stop, char emsg[1024])
 		case 16:
 			break;
 		default:
-			sprintf(emsg, "Sorry, can not handle images with %"PRIu16"-bit samples",
+			snprintf(emsg, EMSG_BUF_SIZE, "Sorry, can not handle images with %"PRIu16"-bit samples",
 			    img->bitspersample);
 			goto fail_return;
 	}
@@ -352,7 +354,7 @@ TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stop, char emsg[1024])
 				img->photometric = PHOTOMETRIC_RGB;
 				break;
 			default:
-				sprintf(emsg, "Missing needed %s tag", photoTag);
+				snprintf(emsg, EMSG_BUF_SIZE, "Missing needed %s tag", photoTag);
                                 goto fail_return;
 		}
 	}
@@ -360,7 +362,7 @@ TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stop, char emsg[1024])
 		case PHOTOMETRIC_PALETTE:
 			if (!TIFFGetField(tif, TIFFTAG_COLORMAP,
 			    &red_orig, &green_orig, &blue_orig)) {
-				sprintf(emsg, "Missing required \"Colormap\" tag");
+				snprintf(emsg, EMSG_BUF_SIZE, "Missing required \"Colormap\" tag");
                                 goto fail_return;
 			}
 
@@ -370,7 +372,7 @@ TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stop, char emsg[1024])
 			img->greencmap = (uint16_t *) _TIFFmalloc(sizeof(uint16_t) * n_color);
 			img->bluecmap = (uint16_t *) _TIFFmalloc(sizeof(uint16_t) * n_color);
 			if( !img->redcmap || !img->greencmap || !img->bluecmap ) {
-				sprintf(emsg, "Out of memory for colormap copy");
+				snprintf(emsg, EMSG_BUF_SIZE, "Out of memory for colormap copy");
                                 goto fail_return;
 			}
 
@@ -384,7 +386,7 @@ TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stop, char emsg[1024])
 			if (planarconfig == PLANARCONFIG_CONTIG
 			    && img->samplesperpixel != 1
 			    && img->bitspersample < 8 ) {
-				sprintf(emsg,
+				snprintf(emsg, EMSG_BUF_SIZE,
 				    "Sorry, can not handle contiguous data with %s=%"PRIu16", "
 				    "and %s=%"PRIu16" and Bits/Sample=%"PRIu16,
 				    photoTag, img->photometric,
@@ -421,7 +423,7 @@ TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stop, char emsg[1024])
 			break;
 		case PHOTOMETRIC_RGB:
 			if (colorchannels < 3) {
-				sprintf(emsg, "Sorry, can not handle RGB image with %s=%d",
+				snprintf(emsg, EMSG_BUF_SIZE, "Sorry, can not handle RGB image with %s=%d",
 				    "Color channels", colorchannels);
                                 goto fail_return;
 			}
@@ -431,12 +433,12 @@ TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stop, char emsg[1024])
 				uint16_t inkset;
 				TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset);
 				if (inkset != INKSET_CMYK) {
-					sprintf(emsg, "Sorry, can not handle separated image with %s=%"PRIu16,
+					snprintf(emsg, EMSG_BUF_SIZE, "Sorry, can not handle separated image with %s=%"PRIu16,
 					    "InkSet", inkset);
                                         goto fail_return;
 				}
 				if (img->samplesperpixel < 4) {
-					sprintf(emsg, "Sorry, can not handle separated image with %s=%"PRIu16,
+					snprintf(emsg, EMSG_BUF_SIZE, "Sorry, can not handle separated image with %s=%"PRIu16,
 					    "Samples/pixel", img->samplesperpixel);
                                         goto fail_return;
 				}
@@ -444,7 +446,7 @@ TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stop, char emsg[1024])
 			break;
 		case PHOTOMETRIC_LOGL:
 			if (compress != COMPRESSION_SGILOG) {
-				sprintf(emsg, "Sorry, LogL data must have %s=%d",
+				snprintf(emsg, EMSG_BUF_SIZE, "Sorry, LogL data must have %s=%d",
 				    "Compression", COMPRESSION_SGILOG);
                                 goto fail_return;
 			}
@@ -454,12 +456,12 @@ TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stop, char emsg[1024])
 			break;
 		case PHOTOMETRIC_LOGLUV:
 			if (compress != COMPRESSION_SGILOG && compress != COMPRESSION_SGILOG24) {
-				sprintf(emsg, "Sorry, LogLuv data must have %s=%d or %d",
+				snprintf(emsg, EMSG_BUF_SIZE, "Sorry, LogLuv data must have %s=%d or %d",
 				    "Compression", COMPRESSION_SGILOG, COMPRESSION_SGILOG24);
                                 goto fail_return;
 			}
 			if (planarconfig != PLANARCONFIG_CONTIG) {
-				sprintf(emsg, "Sorry, can not handle LogLuv images with %s=%"PRIu16,
+				snprintf(emsg, EMSG_BUF_SIZE, "Sorry, can not handle LogLuv images with %s=%"PRIu16,
 				    "Planarconfiguration", planarconfig);
 				return (0);
 			}
@@ -470,7 +472,7 @@ TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stop, char emsg[1024])
 		case PHOTOMETRIC_CIELAB:
 			break;
 		default:
-			sprintf(emsg, "Sorry, can not handle image with %s=%"PRIu16,
+			snprintf(emsg, EMSG_BUF_SIZE, "Sorry, can not handle image with %s=%"PRIu16,
 			    photoTag, img->photometric);
                         goto fail_return;
 	}
@@ -481,12 +483,12 @@ TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stop, char emsg[1024])
 	    !(planarconfig == PLANARCONFIG_SEPARATE && img->samplesperpixel > 1);
 	if (img->isContig) {
 		if (!PickContigCase(img)) {
-			sprintf(emsg, "Sorry, can not handle image");
+			snprintf(emsg, EMSG_BUF_SIZE, "Sorry, can not handle image");
 			goto fail_return;
 		}
 	} else {
 		if (!PickSeparateCase(img)) {
-			sprintf(emsg, "Sorry, can not handle image");
+			snprintf(emsg, EMSG_BUF_SIZE, "Sorry, can not handle image");
 			goto fail_return;
 		}
 	}
@@ -521,7 +523,7 @@ TIFFReadRGBAImageOriented(TIFF* tif,
                           uint32_t rwidth, uint32_t rheight, uint32_t* raster,
                           int orientation, int stop)
 {
-    char emsg[1024] = "";
+    char emsg[EMSG_BUF_SIZE] = "";
     TIFFRGBAImage img;
     int ok;
 
@@ -2879,7 +2881,7 @@ int
 TIFFReadRGBAStripExt(TIFF* tif, uint32_t row, uint32_t * raster, int stop_on_error)
 
 {
-    char 	emsg[1024] = "";
+    char 	emsg[EMSG_BUF_SIZE] = "";
     TIFFRGBAImage img;
     int 	ok;
     uint32_t	rowsperstrip, rows_to_read;
@@ -2937,7 +2939,7 @@ TIFFReadRGBATile(TIFF* tif, uint32_t col, uint32_t row, uint32_t * raster)
 int
 TIFFReadRGBATileExt(TIFF* tif, uint32_t col, uint32_t row, uint32_t * raster, int stop_on_error )
 {
-    char 	emsg[1024] = "";
+    char 	emsg[EMSG_BUF_SIZE] = "";
     TIFFRGBAImage img;
     int 	ok;
     uint32_t	tile_xsize, tile_ysize;