sdl2-compat: Always allocate a new palette in SDL_ConvertSurface()

From 1ae7171fd084675a649359951028003e61c0af8f Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Sat, 1 Feb 2025 01:28:08 -0800
Subject: [PATCH] Always allocate a new palette in SDL_ConvertSurface()

The passed in palette might be on the stack, so isn't safe to assign to a new surface.

Fixes https://github.com/libsdl-org/sdl2-compat/issues/243
---
 src/sdl2_compat.c | 22 +++++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/src/sdl2_compat.c b/src/sdl2_compat.c
index 9939898..5864a85 100644
--- a/src/sdl2_compat.c
+++ b/src/sdl2_compat.c
@@ -2956,6 +2956,9 @@ SDL_GetWindowOpacity(SDL_Window *window, float *out_opacity)
 SDL_DECLSPEC SDL2_Surface * SDLCALL
 SDL_ConvertSurface(SDL2_Surface *surface, const SDL2_PixelFormat *format, Uint32 flags)
 {
+    SDL_Palette *palette = NULL;
+    SDL2_Surface *result;
+
     (void) flags; /* SDL3 removed the (unused) `flags` argument */
 
     if (!surface) {
@@ -2967,7 +2970,24 @@ SDL_ConvertSurface(SDL2_Surface *surface, const SDL2_PixelFormat *format, Uint32
         return NULL;
     }
 
-    return Surface3to2(SDL3_ConvertSurfaceAndColorspace(Surface2to3(surface), (SDL_PixelFormat)format->format, format->palette, SDL_COLORSPACE_SRGB, 0));
+    if (format->palette) {
+        // This conversion is going to assign the new surface this palette,
+        // but it might be on the stack, so always allocate a new one to be
+        // safe. Real SDL2 always allocated a new palette in this function.
+        const int ncolors = format->palette->ncolors;
+        palette = SDL3_CreatePalette(ncolors);
+        if (!palette) {
+            return NULL;
+        }
+        SDL3_SetPaletteColors(palette, format->palette->colors, 0, ncolors);
+    }
+
+    result = Surface3to2(SDL3_ConvertSurfaceAndColorspace(Surface2to3(surface), (SDL_PixelFormat)format->format, palette, SDL_COLORSPACE_SRGB, 0));
+
+    if (palette) {
+        SDL3_DestroyPalette(palette);
+    }
+    return result;
 }
 
 SDL_DECLSPEC SDL2_Surface * SDLCALL