sdl2-compat: texture: Fix leak in SDL_LockTextureToSurface()

From dd768394fbd61dba3b79144de2f11b1dd2244b43 Mon Sep 17 00:00:00 2001
From: Cameron Gutman <[EMAIL REDACTED]>
Date: Mon, 7 Apr 2025 23:32:09 -0500
Subject: [PATCH] texture: Fix leak in SDL_LockTextureToSurface()

---
 src/sdl2_compat.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/src/sdl2_compat.c b/src/sdl2_compat.c
index 55f5203..2f057f0 100644
--- a/src/sdl2_compat.c
+++ b/src/sdl2_compat.c
@@ -9987,7 +9987,8 @@ SDL_GetSurfaceBlendMode(SDL2_Surface *surface, SDL_BlendMode *blendMode)
     return SDL3_GetSurfaceBlendMode(Surface2to3(surface), blendMode) ? 0 : -1;
 }
 
-static void SDLCALL CleanupWindowSurface(void *userdata, void *value)
+/* Cleanup callback for SDL2 surfaces that are retained by an SDL3 object */
+static void SDLCALL CleanupRetainedSurface2(void *userdata, void *value)
 {
     SDL2_Surface *surface = (SDL2_Surface *)value;
     surface->flags &= ~SDL_DONTFREE;
@@ -10022,7 +10023,7 @@ SDL_GetWindowSurface(SDL_Window *window)
                 if (surface2) {
                     surface2->flags |= SDL_DONTFREE;
 
-                    SDL3_SetPointerPropertyWithCleanup(SDL3_GetWindowProperties(window), PROP_SURFACE2, surface2, CleanupWindowSurface, NULL);
+                    SDL3_SetPointerPropertyWithCleanup(SDL3_GetWindowProperties(window), PROP_SURFACE2, surface2, CleanupRetainedSurface2, NULL);
                 }
             }
         }
@@ -10037,7 +10038,15 @@ SDL_LockTextureToSurface(SDL_Texture *texture, const SDL_Rect *rect, SDL2_Surfac
     if (!SDL3_LockTextureToSurface(texture, rect, &surface3)) {
         return -1;
     }
-    *surface = Surface3to2(surface3);
+    *surface = CreateSurface2from3(surface3);
+    if (!*surface) {
+        SDL_UnlockTexture(texture);
+        return -1;
+    }
+
+    /* This surface is freed by SDL_UnlockTexture() or SDL_DestroyTexture(), not by SDL_FreeSurface() */
+    (*surface)->flags |= SDL_DONTFREE;
+    SDL3_SetPointerPropertyWithCleanup(SDL3_GetSurfaceProperties(surface3), PROP_SURFACE2, *surface, CleanupRetainedSurface2, NULL);
     return 0;
 }