Browse Source

Make sure the blit mapping is cleared when undoing RLE encoding

This fixes a crash if a surface is RLE encoded, then locked and unlocked.

We also mark the surface as no longer needing to be locked after undoing RLE encoding
Sam Lantinga 4 months ago
parent
commit
704ac98d3f
2 changed files with 8 additions and 2 deletions
  1. 3 0
      src/video/SDL_RLEaccel.c
  2. 5 2
      src/video/SDL_surface.c

+ 3 - 0
src/video/SDL_RLEaccel.c

@@ -89,6 +89,7 @@
 
 #include "SDL_sysvideo.h"
 #include "SDL_surface_c.h"
+#include "SDL_pixels_c.h"
 #include "SDL_RLEaccel_c.h"
 
 #define PIXEL_COPY(to, from, len, bpp) \
@@ -1385,6 +1386,8 @@ void SDL_UnRLESurface(SDL_Surface *surface)
         SDL_free(surface->map.data);
         surface->map.data = NULL;
 
+        SDL_InvalidateMap(&surface->map);
+
         SDL_UpdateSurfaceLockFlag(surface);
     }
 }

+ 5 - 2
src/video/SDL_surface.c

@@ -50,7 +50,9 @@ bool SDL_SurfaceValid(SDL_Surface *surface)
 
 void SDL_UpdateSurfaceLockFlag(SDL_Surface *surface)
 {
-    if (surface->internal_flags & SDL_INTERNAL_SURFACE_RLEACCEL) {
+    // We need to mark the surface as needing unlock while locked
+    if ((surface->flags & SDL_SURFACE_LOCKED) ||
+        (surface->internal_flags & SDL_INTERNAL_SURFACE_RLEACCEL)) {
         surface->flags |= SDL_SURFACE_LOCK_NEEDED;
     } else {
         surface->flags &= ~SDL_SURFACE_LOCK_NEEDED;
@@ -1726,7 +1728,6 @@ bool SDL_LockSurface(SDL_Surface *surface)
         // Perform the lock
         if (surface->internal_flags & SDL_INTERNAL_SURFACE_RLEACCEL) {
             SDL_UnRLESurface(surface);
-            surface->flags |= SDL_SURFACE_LOCK_NEEDED;
         }
 #endif
     }
@@ -1734,6 +1735,7 @@ bool SDL_LockSurface(SDL_Surface *surface)
     // Increment the surface lock count, for recursive locks
     ++surface->locked;
     surface->flags |= SDL_SURFACE_LOCKED;
+    SDL_UpdateSurfaceLockFlag(surface);
 
     // Ready to go..
     return true;
@@ -1754,6 +1756,7 @@ void SDL_UnlockSurface(SDL_Surface *surface)
     }
 
     surface->flags &= ~SDL_SURFACE_LOCKED;
+    SDL_UpdateSurfaceLockFlag(surface);
 }
 
 static bool SDL_FlipSurfaceHorizontal(SDL_Surface *surface)