$OpenBSD: patch-libtiff_tif_getimage_c,v 1.14 2021/03/16 15:34:23 landry Exp $

This one is slightly problematic.  If an application allocates less
room for its error buffer than the recommended 1024, the error message
buffer will still overflow.

Index: libtiff/tif_getimage.c
--- libtiff/tif_getimage.c.orig
+++ libtiff/tif_getimage.c
@@ -79,7 +79,7 @@ TIFFRGBAImageOK(TIFF* tif, char emsg[1024])
 	int colorchannels;
 
 	if (!tif->tif_decodestatus) {
-		sprintf(emsg, "Sorry, requested compression method is not configured");
+		snprintf(emsg, 1024, "Sorry, requested compression method is not configured");
 		return (0);
 	}
 	switch (td->td_bitspersample) {
@@ -90,12 +90,12 @@ TIFFRGBAImageOK(TIFF* tif, char emsg[1024])
 		case 16:
 			break;
 		default:
-			sprintf(emsg, "Sorry, can not handle images with %d-bit samples",
+			snprintf(emsg, 1024, "Sorry, can not handle images with %d-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, 1024, "Sorry, can not handle images with IEEE floating-point samples");
                 return (0);
         }
 	colorchannels = td->td_samplesperpixel - td->td_extrasamples;
@@ -108,7 +108,7 @@ TIFFRGBAImageOK(TIFF* tif, char emsg[1024])
 				photometric = PHOTOMETRIC_RGB;
 				break;
 			default:
-				sprintf(emsg, "Missing needed %s tag", photoTag);
+				snprintf(emsg, 1024, "Missing needed %s tag", photoTag);
 				return (0);
 		}
 	}
@@ -119,7 +119,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, 1024,
 				    "Sorry, can not handle contiguous data with %s=%d, "
 				    "and %s=%d and Bits/Sample=%d",
 				    photoTag, photometric,
@@ -143,7 +143,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, 1024, "Sorry, can not handle RGB image with %s=%d",
 				    "Color channels", colorchannels);
 				return (0);
 			}
@@ -153,13 +153,13 @@ TIFFRGBAImageOK(TIFF* tif, char emsg[1024])
 				uint16 inkset;
 				TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset);
 				if (inkset != INKSET_CMYK) {
-					sprintf(emsg,
+					snprintf(emsg, 1024,
 					    "Sorry, can not handle separated image with %s=%d",
 					    "InkSet", inkset);
 					return 0;
 				}
 				if (td->td_samplesperpixel < 4) {
-					sprintf(emsg,
+					snprintf(emsg, 1024,
 					    "Sorry, can not handle separated image with %s=%d",
 					    "Samples/pixel", td->td_samplesperpixel);
 					return 0;
@@ -168,7 +168,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, 1024, "Sorry, LogL data must have %s=%d",
 				    "Compression", COMPRESSION_SGILOG);
 				return (0);
 			}
@@ -176,17 +176,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, 1024, "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=%d",
+				snprintf(emsg, 1024, "Sorry, can not handle LogLuv images with %s=%d",
 				    "Planarconfiguration", td->td_planarconfig);
 				return (0);
 			}
 			if ( td->td_samplesperpixel != 3 || colorchannels != 3 ) {
-                                sprintf(emsg,
+                                snprintf(emsg, 1024,
                                         "Sorry, can not handle image with %s=%d, %s=%d",
                                         "Samples/pixel", td->td_samplesperpixel,
                                         "colorchannels", colorchannels);
@@ -195,7 +195,7 @@ TIFFRGBAImageOK(TIFF* tif, char emsg[1024])
 			break;
 		case PHOTOMETRIC_CIELAB:
                         if ( td->td_samplesperpixel != 3 || colorchannels != 3 || td->td_bitspersample != 8 ) {
-                                sprintf(emsg,
+                                snprintf(emsg, 1024,
                                         "Sorry, can not handle image with %s=%d, %s=%d and %s=%d",
                                         "Samples/pixel", td->td_samplesperpixel,
                                         "colorchannels", colorchannels,
@@ -204,7 +204,7 @@ TIFFRGBAImageOK(TIFF* tif, char emsg[1024])
                         }
 			break;
                 default:
-			sprintf(emsg, "Sorry, can not handle image with %s=%d",
+			snprintf(emsg, 1024, "Sorry, can not handle image with %s=%d",
 			    photoTag, photometric);
 			return (0);
 	}
@@ -302,7 +302,7 @@ TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int 
 		case 16:
 			break;
 		default:
-			sprintf(emsg, "Sorry, can not handle images with %d-bit samples",
+			snprintf(emsg, 1024, "Sorry, can not handle images with %d-bit samples",
 			    img->bitspersample);
 			goto fail_return;
 	}
@@ -352,7 +352,7 @@ TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int 
 				img->photometric = PHOTOMETRIC_RGB;
 				break;
 			default:
-				sprintf(emsg, "Missing needed %s tag", photoTag);
+				snprintf(emsg, 1024, "Missing needed %s tag", photoTag);
                                 goto fail_return;
 		}
 	}
@@ -360,7 +360,7 @@ TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int 
 		case PHOTOMETRIC_PALETTE:
 			if (!TIFFGetField(tif, TIFFTAG_COLORMAP,
 			    &red_orig, &green_orig, &blue_orig)) {
-				sprintf(emsg, "Missing required \"Colormap\" tag");
+				snprintf(emsg, 1024, "Missing required \"Colormap\" tag");
                                 goto fail_return;
 			}
 
@@ -370,7 +370,7 @@ TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int 
 			img->greencmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color);
 			img->bluecmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color);
 			if( !img->redcmap || !img->greencmap || !img->bluecmap ) {
-				sprintf(emsg, "Out of memory for colormap copy");
+				snprintf(emsg, 1024, "Out of memory for colormap copy");
                                 goto fail_return;
 			}
 
@@ -384,7 +384,7 @@ TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int 
 			if (planarconfig == PLANARCONFIG_CONTIG
 			    && img->samplesperpixel != 1
 			    && img->bitspersample < 8 ) {
-				sprintf(emsg,
+				snprintf(emsg, 1024,
 				    "Sorry, can not handle contiguous data with %s=%d, "
 				    "and %s=%d and Bits/Sample=%d",
 				    photoTag, img->photometric,
@@ -421,7 +421,7 @@ TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int 
 			break;
 		case PHOTOMETRIC_RGB:
 			if (colorchannels < 3) {
-				sprintf(emsg, "Sorry, can not handle RGB image with %s=%d",
+				snprintf(emsg, 1024, "Sorry, can not handle RGB image with %s=%d",
 				    "Color channels", colorchannels);
                                 goto fail_return;
 			}
@@ -431,12 +431,12 @@ TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int 
 				uint16 inkset;
 				TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset);
 				if (inkset != INKSET_CMYK) {
-					sprintf(emsg, "Sorry, can not handle separated image with %s=%d",
+					snprintf(emsg, 1024, "Sorry, can not handle separated image with %s=%d",
 					    "InkSet", inkset);
                                         goto fail_return;
 				}
 				if (img->samplesperpixel < 4) {
-					sprintf(emsg, "Sorry, can not handle separated image with %s=%d",
+					snprintf(emsg, 1024, "Sorry, can not handle separated image with %s=%d",
 					    "Samples/pixel", img->samplesperpixel);
                                         goto fail_return;
 				}
@@ -444,7 +444,7 @@ TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int 
 			break;
 		case PHOTOMETRIC_LOGL:
 			if (compress != COMPRESSION_SGILOG) {
-				sprintf(emsg, "Sorry, LogL data must have %s=%d",
+				snprintf(emsg, 1024, "Sorry, LogL data must have %s=%d",
 				    "Compression", COMPRESSION_SGILOG);
                                 goto fail_return;
 			}
@@ -454,12 +454,12 @@ TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int 
 			break;
 		case PHOTOMETRIC_LOGLUV:
 			if (compress != COMPRESSION_SGILOG && compress != COMPRESSION_SGILOG24) {
-				sprintf(emsg, "Sorry, LogLuv data must have %s=%d or %d",
+				snprintf(emsg, 1024, "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=%d",
+				snprintf(emsg, 1024, "Sorry, can not handle LogLuv images with %s=%d",
 				    "Planarconfiguration", planarconfig);
 				return (0);
 			}
@@ -470,7 +470,7 @@ TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int 
 		case PHOTOMETRIC_CIELAB:
 			break;
 		default:
-			sprintf(emsg, "Sorry, can not handle image with %s=%d",
+			snprintf(emsg, 1024, "Sorry, can not handle image with %s=%d",
 			    photoTag, img->photometric);
                         goto fail_return;
 	}
@@ -481,12 +481,12 @@ TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int 
 	    !(planarconfig == PLANARCONFIG_SEPARATE && img->samplesperpixel > 1);
 	if (img->isContig) {
 		if (!PickContigCase(img)) {
-			sprintf(emsg, "Sorry, can not handle image");
+			snprintf(emsg, 1024, "Sorry, can not handle image");
 			goto fail_return;
 		}
 	} else {
 		if (!PickSeparateCase(img)) {
-			sprintf(emsg, "Sorry, can not handle image");
+			snprintf(emsg, 1024, "Sorry, can not handle image");
 			goto fail_return;
 		}
 	}
