Fix palette buffer overflow in wxGIFHandler::SaveFile()

The image palette can have more than the 256 entries a GIF supports, for
example when the image was loaded from an XPM that declares a larger
colour count. wxGIFHandler_GetPalette(), called when saving a GIF,
copied every entry into the caller's fixed wxRGB pal[256] buffer,
overflowing it.

Such an image can't be represented as a GIF, so reject the save with an
error message instead of overflowing the buffer or writing out a silently
truncated palette.

Closes #26532.
This commit is contained in:
dxbjavid
2026-05-31 15:45:18 +02:00
committed by Vadim Zeitlin
parent a3ad8e3360
commit e4a462d4bc
2 changed files with 34 additions and 0 deletions
+10
View File
@@ -556,6 +556,16 @@ bool wxGIFHandler_GetPalette(const wxImage& image,
const wxPalette& palette = image.GetPalette();
int palCount = palette.GetColoursCount();
// The caller's pal[] buffer only has room for the 256 entries a GIF can
// hold. A wxImage palette may be larger, e.g. when the image was loaded
// from an XPM declaring more than 256 colours, and such an image can't be
// represented as a GIF, so fail the save here rather than overflow pal[].
if (palCount > 256)
{
wxLogError(_("Image palette has too many colours to save as GIF."));
return false;
}
for (int i = 0; i < palCount; ++i)
{
if (!palette.GetRGB(i, &pal[i].red, &pal[i].green, &pal[i].blue))
+24
View File
@@ -1304,6 +1304,30 @@ TEST_CASE_METHOD(ImageHandlersInit, "wxImage::SaveAnimatedGIF", "[image]")
#endif // #if wxUSE_PALETTE
}
TEST_CASE_METHOD(ImageHandlersInit, "wxImage::SaveGIFBigPalette", "[image][gif][error]")
{
#if wxUSE_PALETTE
// An image palette can have more than the 256 entries a GIF supports, for
// instance when the image was loaded from an XPM declaring a larger colour
// count. Saving such an image as GIF must not overflow the fixed 256-entry
// palette buffer used by the encoder; instead the save should fail cleanly.
const int numColours = 300;
unsigned char r[numColours], g[numColours], b[numColours];
for (int i = 0; i < numColours; ++i)
{
r[i] = g[i] = b[i] = static_cast<unsigned char>(i);
}
wxImage image(1, 1);
image.SetRGB(0, 0, 0, 0, 0);
image.SetPalette(wxPalette(numColours, r, g, b));
wxMemoryOutputStream memOut;
wxLogNull noLog;
CHECK( !image.SaveFile(memOut, wxBITMAP_TYPE_GIF) );
#endif // wxUSE_PALETTE
}
static void TestGIFComment(const wxString& comment)
{
wxImage image("horse.gif");