Replace sprintf calls with snprintf in third_party

This makes it possible to build PDFium 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.

This change affects libopenjpeg and libtiff. The patches here were
submitted upstream at https://github.com/uclouvain/openjpeg/pull/1450
and https://gitlab.com/libtiff/libtiff/-/merge_requests/408.

Bug: chromium:1381706
Change-Id: I92ff8f897fe63b3dee14301cd15c791e0d4fb8cf
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/100790
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/third_party/libopenjpeg/0045-openjp2-j2k-replace-sprintf-calls-with-snprintf.patch b/third_party/libopenjpeg/0045-openjp2-j2k-replace-sprintf-calls-with-snprintf.patch
new file mode 100644
index 0000000..01ef487
--- /dev/null
+++ b/third_party/libopenjpeg/0045-openjp2-j2k-replace-sprintf-calls-with-snprintf.patch
@@ -0,0 +1,82 @@
+https://github.com/uclouvain/openjpeg/pull/1450
+https://patch-diff.githubusercontent.com/raw/uclouvain/openjpeg/pull/1450.patch
+
+From 093ccb0ecdba7d5c4b5363e7dda33b1769fcc08a Mon Sep 17 00:00:00 2001
+From: Mark Mentovai <mark@chromium.org>
+Date: Mon, 7 Nov 2022 09:32:02 -0500
+Subject: [PATCH] openjp2/j2k: 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 j2k.c 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.
+
+j2k.c 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 src/lib/openjp2. Other uses of sprintf were
+found throughout openjpeg.
+---
+ src/lib/openjp2/j2k.c | 13 ++++++++-----
+ 1 file changed, 8 insertions(+), 5 deletions(-)
+
+diff --git a/src/lib/openjp2/j2k.c b/src/lib/openjp2/j2k.c
+index 923bd8916..354415df7 100644
+--- a/src/lib/openjp2/j2k.c
++++ b/src/lib/openjp2/j2k.c
+@@ -7954,21 +7954,24 @@ OPJ_BOOL opj_j2k_setup_encoder(opj_j2k_t *p_j2k,
+ 
+         /* UniPG>> */
+ #ifdef USE_JPWL
+-        cp->comment = (char*)opj_malloc(clen + strlen(version) + 11);
++        const size_t cp_comment_buf_size = clen + strlen(version) + 11;
++        cp->comment = (char*)opj_malloc(cp_comment_buf_size);
+         if (!cp->comment) {
+             opj_event_msg(p_manager, EVT_ERROR,
+                           "Not enough memory to allocate comment string\n");
+             return OPJ_FALSE;
+         }
+-        sprintf(cp->comment, "%s%s with JPWL", comment, version);
++        snprintf(cp->comment, cp_comment_buf_size, "%s%s with JPWL",
++                 comment, version);
+ #else
+-        cp->comment = (char*)opj_malloc(clen + strlen(version) + 1);
++        const size_t cp_comment_buf_size = clen + strlen(version) + 1;
++        cp->comment = (char*)opj_malloc(cp_comment_buf_size);
+         if (!cp->comment) {
+             opj_event_msg(p_manager, EVT_ERROR,
+                           "Not enough memory to allocate comment string\n");
+             return OPJ_FALSE;
+         }
+-        sprintf(cp->comment, "%s%s", comment, version);
++        snprintf(cp->comment, cp_comment_buf_size, "%s%s", comment, version);
+ #endif
+         /* <<UniPG */
+     }
+@@ -11973,7 +11976,7 @@ static OPJ_BOOL opj_j2k_move_data_from_codec_to_output_image(opj_j2k_t * p_j2k,
+             p_image->comps[compno].data = p_j2k->m_output_image->comps[compno].data;
+ #if 0
+             char fn[256];
+-            sprintf(fn, "/tmp/%d.raw", compno);
++            snprintf(fn, sizeof fn, "/tmp/%d.raw", compno);
+             FILE *debug = fopen(fn, "wb");
+             fwrite(p_image->comps[compno].data, sizeof(OPJ_INT32),
+                    p_image->comps[compno].w * p_image->comps[compno].h, debug);
diff --git a/third_party/libopenjpeg/README.pdfium b/third_party/libopenjpeg/README.pdfium
index 49b39be..9498b86 100644
--- a/third_party/libopenjpeg/README.pdfium
+++ b/third_party/libopenjpeg/README.pdfium
@@ -32,3 +32,4 @@
 0042-popcnt-windows-arm64.patch: Backport to fix Windows arm64 build.
 0043-mel_init.patch: Backport fix for assertion failure in mel_init().
 0044-opj_t1_allocate_buffers.patch: Backport fix for malloc size error in opj_t1_allocate_buffers().
+0045-openjp2-j2k-replace-sprintf-calls-with-snprintf.patch: Replace sprintf with snprintf for macOS 13 SDK compatibility, from https://github.com/uclouvain/openjpeg/pull/1450.
diff --git a/third_party/libopenjpeg/j2k.c b/third_party/libopenjpeg/j2k.c
index fce12e4..9b06e7e 100644
--- a/third_party/libopenjpeg/j2k.c
+++ b/third_party/libopenjpeg/j2k.c
@@ -7931,21 +7931,24 @@
 
         /* UniPG>> */
 #ifdef USE_JPWL
-        cp->comment = (char*)opj_malloc(clen + strlen(version) + 11);
+        const size_t cp_comment_buf_size = clen + strlen(version) + 11;
+        cp->comment = (char*)opj_malloc(cp_comment_buf_size);
         if (!cp->comment) {
             opj_event_msg(p_manager, EVT_ERROR,
                           "Not enough memory to allocate comment string\n");
             return OPJ_FALSE;
         }
-        sprintf(cp->comment, "%s%s with JPWL", comment, version);
+        snprintf(cp->comment, cp_comment_buf_size, "%s%s with JPWL",
+                 comment, version);
 #else
-        cp->comment = (char*)opj_malloc(clen + strlen(version) + 1);
+        const size_t cp_comment_buf_size = clen + strlen(version) + 1;
+        cp->comment = (char*)opj_malloc(cp_comment_buf_size);
         if (!cp->comment) {
             opj_event_msg(p_manager, EVT_ERROR,
                           "Not enough memory to allocate comment string\n");
             return OPJ_FALSE;
         }
-        sprintf(cp->comment, "%s%s", comment, version);
+        snprintf(cp->comment, cp_comment_buf_size, "%s%s", comment, version);
 #endif
         /* <<UniPG */
     }
@@ -11957,7 +11960,7 @@
             p_image->comps[compno].data = p_j2k->m_output_image->comps[compno].data;
 #if 0
             char fn[256];
-            sprintf(fn, "/tmp/%d.raw", compno);
+            snprintf(fn, sizeof fn, "/tmp/%d.raw", compno);
             FILE *debug = fopen(fn, "wb");
             fwrite(p_image->comps[compno].data, sizeof(OPJ_INT32),
                    p_image->comps[compno].w * p_image->comps[compno].h, debug);
diff --git a/third_party/libtiff/0036-Replace-sprintf-calls-with-snprintf.patch b/third_party/libtiff/0036-Replace-sprintf-calls-with-snprintf.patch
new file mode 100644
index 0000000..ae69dff
--- /dev/null
+++ b/third_party/libtiff/0036-Replace-sprintf-calls-with-snprintf.patch
@@ -0,0 +1,344 @@
+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;
diff --git a/third_party/libtiff/README.pdfium b/third_party/libtiff/README.pdfium
index 8a6bd5b..fe3f746 100644
--- a/third_party/libtiff/README.pdfium
+++ b/third_party/libtiff/README.pdfium
@@ -19,3 +19,4 @@
 0033-avail-out-overflow.patch: signed comparison in PixarLogDecode().
 0034-memcpy-nullptr.patch: Check size before calling memcpy().
 0035-memcpy-nullptr-zero-size.patch: Check for nullptr and zero size before calling memcpy().
+0036-Replace-sprintf-calls-with-snprintf.patch: Replace sprintf with snprintf for macOS 13 SDK compatibility, from https://gitlab.com/libtiff/libtiff/-/merge_requests/408, edited to apply to PDFium, which does not have libtiff 352cb5a4fb11.
diff --git a/third_party/libtiff/tif_codec.c b/third_party/libtiff/tif_codec.c
index f909b20..d01259c 100644
--- a/third_party/libtiff/tif_codec.c
+++ b/third_party/libtiff/tif_codec.c
@@ -114,7 +114,8 @@
 	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 2e88c9b..5906d6d 100644
--- a/third_party/libtiff/tif_getimage.c
+++ b/third_party/libtiff/tif_getimage.c
@@ -49,6 +49,8 @@
 #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 @@
  * 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 @@
 		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 @@
 				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 @@
 			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 @@
 			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 @@
 				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 @@
 			}
 		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 @@
 		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 @@
 			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 @@
                         }
 			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 @@
 }
 
 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 @@
 		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 @@
 				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 @@
 		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 @@
 			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 @@
 			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 @@
 			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 @@
 				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 @@
 			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 @@
 			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 @@
 		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 @@
 	    !(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 @@
 			  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 @@
 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 @@
 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;