| https://gitlab.com/libtiff/libtiff/-/merge_requests/408 | |
| https://gitlab.com/libtiff/libtiff/-/merge_requests/408.patch (edited to apply to PDFium, which does not have libtiff 352cb5a4fb11) | |
| From 586fd2889b9eefbaa671f6e173031d99400c2aaf Mon Sep 17 00:00:00 2001 | |
| From: Mark Mentovai <mark@chromium.org> | |
| 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/third_party/libtiff/tif_codec.c b/third_party/libtiff/tif_codec.c | |
| index f909b20c1325..d01259ca78c8 100644 | |
| --- a/third_party/libtiff/tif_codec.c | |
| +++ b/third_party/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, "%d",tif->tif_dir.td_compression ); | |
| + snprintf(compression_code, sizeof compression_code, "%d", | |
| + tif->tif_dir.td_compression); | |
| TIFFErrorExt(tif->tif_clientdata, tif->tif_name, | |
| "%s compression support is not configured", | |
| c ? c->name : compression_code ); | |
| diff --git a/third_party/libtiff/tif_getimage.c b/third_party/libtiff/tif_getimage.c | |
| index 2e88c9bdc4b4..5906d6d06d81 100644 | |
| --- a/third_party/libtiff/tif_getimage.c | |
| +++ b/third_party/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 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 %d-bit samples", | |
| + snprintf(emsg, EMSG_BUF_SIZE, "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, 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=%d, " | |
| "and %s=%d and Bits/Sample=%d", | |
| 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 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=%d", | |
| "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=%d", | |
| + snprintf(emsg, EMSG_BUF_SIZE, "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, EMSG_BUF_SIZE, | |
| "Sorry, can not handle image with %s=%d, %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 ) { | |
| - sprintf(emsg, | |
| + snprintf(emsg, EMSG_BUF_SIZE, | |
| "Sorry, can not handle image with %s=%d, %s=%d and %s=%d", | |
| "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=%d", | |
| + snprintf(emsg, EMSG_BUF_SIZE, "Sorry, can not handle image with %s=%d", | |
| 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* sampleinfo; | |
| uint16 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 %d-bit samples", | |
| + snprintf(emsg, EMSG_BUF_SIZE, "Sorry, can not handle images with %d-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 *) _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, 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=%d, " | |
| "and %s=%d and Bits/Sample=%d", | |
| 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 inkset; | |
| TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset); | |
| if (inkset != INKSET_CMYK) { | |
| - sprintf(emsg, "Sorry, can not handle separated image with %s=%d", | |
| + snprintf(emsg, EMSG_BUF_SIZE, "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, EMSG_BUF_SIZE, "Sorry, can not handle separated image with %s=%d", | |
| "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=%d", | |
| + snprintf(emsg, EMSG_BUF_SIZE, "Sorry, can not handle LogLuv images with %s=%d", | |
| "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=%d", | |
| + snprintf(emsg, EMSG_BUF_SIZE, "Sorry, can not handle image with %s=%d", | |
| 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 rwidth, uint32 rheight, uint32* raster, | |
| int orientation, int stop) | |
| { | |
| - char emsg[1024] = ""; | |
| + char emsg[EMSG_BUF_SIZE] = ""; | |
| TIFFRGBAImage img; | |
| int ok; | |
| @@ -2940,7 +2942,7 @@ int | |
| TIFFReadRGBAStripExt(TIFF* tif, uint32 row, uint32 * raster, int stop_on_error) | |
| { | |
| - char emsg[1024] = ""; | |
| + char emsg[EMSG_BUF_SIZE] = ""; | |
| TIFFRGBAImage img; | |
| int ok; | |
| uint32 rowsperstrip, rows_to_read; | |
| @@ -2998,7 +3000,7 @@ TIFFReadRGBATile(TIFF* tif, uint32 col, uint32 row, uint32 * raster) | |
| int | |
| TIFFReadRGBATileExt(TIFF* tif, uint32 col, uint32 row, uint32 * raster, int stop_on_error ) | |
| { | |
| - char emsg[1024] = ""; | |
| + char emsg[EMSG_BUF_SIZE] = ""; | |
| TIFFRGBAImage img; | |
| int ok; | |
| uint32 tile_xsize, tile_ysize; |