From 6f8503263a397ec2a93495c4f6502de39b9e5eb2 Mon Sep 17 00:00:00 2001 From: Larry Gritz Date: Thu, 2 Jul 2026 23:33:09 -0400 Subject: [PATCH] fix(gif): avoid int32 overflow in palette-split pixel-count math GifSplitPalette() computed `numPixels * (splitElt - firstElt)` as a 32-bit int before dividing. For any image over roughly 16.9M pixels (e.g. 4117x4117), that intermediate multiplication overflows INT_MAX and is undefined behavior; in practice it produced a bogus negative/garbage split count that could drive later indexing into `image` out of its bounds. Do the multiply in 64 bits and narrow back afterward -- the quotient is always <= numPixels, so the narrowing itself is safe. Assisted-by: Claude Code / Sonnet 5 Signed-off-by: Larry Gritz --- src/gif.imageio/gif.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/gif.imageio/gif.h b/src/gif.imageio/gif.h index afbe3d8050..69c99b5826 100644 --- a/src/gif.imageio/gif.h +++ b/src/gif.imageio/gif.h @@ -340,7 +340,11 @@ void GifSplitPalette(uint8_t* image, int numPixels, int firstElt, int lastElt, i if(bRange > gRange) splitCom = 2; if(rRange > bRange && rRange > gRange) splitCom = 0; - int subPixelsA = numPixels * (splitElt - firstElt) / (lastElt - firstElt); + // numPixels*(splitElt-firstElt) can overflow int32 for images beyond + // about 16.9M pixels (e.g. 4117x4117); do the multiply in 64 bits. The + // final quotient is always <= numPixels, so it safely narrows back. + int subPixelsA = (int)((int64_t)numPixels * (splitElt - firstElt) + / (lastElt - firstElt)); int subPixelsB = numPixels-subPixelsA; GifPartitionByMedian(image, 0, numPixels, splitCom, subPixelsA);