| 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; |