SDL: Don't overwrite the SDL_IOFromFile() error in SDL_LoadBMP()

From b766c824bd9c7bc966ddc293beedd5a33b8c6cf2 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Sun, 13 Oct 2024 09:36:25 -0700
Subject: [PATCH] Don't overwrite the SDL_IOFromFile() error in SDL_LoadBMP()

Fixes https://github.com/libsdl-org/SDL/issues/11188
---
 src/video/SDL_bmp.c | 107 +++++++++++++++++++++++---------------------
 1 file changed, 56 insertions(+), 51 deletions(-)

diff --git a/src/video/SDL_bmp.c b/src/video/SDL_bmp.c
index 053f22c111774..3d292eb5a64a3 100644
--- a/src/video/SDL_bmp.c
+++ b/src/video/SDL_bmp.c
@@ -589,7 +589,11 @@ SDL_Surface *SDL_LoadBMP_IO(SDL_IOStream *src, bool closeio)
 
 SDL_Surface *SDL_LoadBMP(const char *file)
 {
-    return SDL_LoadBMP_IO(SDL_IOFromFile(file, "rb"), 1);
+    SDL_IOStream *stream = SDL_IOFromFile(file, "rb");
+    if (!stream) {
+        return NULL;
+    }
+    return SDL_LoadBMP_IO(stream, 1);
 }
 
 bool SDL_SaveBMP_IO(SDL_Surface *surface, SDL_IOStream *dst, bool closeio)
@@ -597,7 +601,7 @@ bool SDL_SaveBMP_IO(SDL_Surface *surface, SDL_IOStream *dst, bool closeio)
     bool was_error = true;
     Sint64 fp_offset, new_offset;
     int i, pad;
-    SDL_Surface *intermediate_surface;
+    SDL_Surface *intermediate_surface = NULL;
     Uint8 *bits;
     bool save32bit = false;
     bool saveLegacyBMP = false;
@@ -634,63 +638,60 @@ bool SDL_SaveBMP_IO(SDL_Surface *surface, SDL_IOStream *dst, bool closeio)
     Uint32 bV4GammaBlue = 0;
 
     // Make sure we have somewhere to save
-    intermediate_surface = NULL;
-    if (dst) {
-        if (!SDL_SurfaceValid(surface)) {
-            SDL_InvalidParamError("surface");
-            goto done;
-        }
+    if (!SDL_SurfaceValid(surface)) {
+        SDL_InvalidParamError("surface");
+        goto done;
+    }
+    if (!dst) {
+        SDL_InvalidParamError("dst");
+        goto done;
+    }
 
 #ifdef SAVE_32BIT_BMP
-        // We can save alpha information in a 32-bit BMP
-        if (SDL_BITSPERPIXEL(surface->format) >= 8 &&
-            (SDL_ISPIXELFORMAT_ALPHA(surface->format) ||
-             surface->map.info.flags & SDL_COPY_COLORKEY)) {
-            save32bit = true;
-        }
+    // We can save alpha information in a 32-bit BMP
+    if (SDL_BITSPERPIXEL(surface->format) >= 8 &&
+        (SDL_ISPIXELFORMAT_ALPHA(surface->format) ||
+         surface->map.info.flags & SDL_COPY_COLORKEY)) {
+        save32bit = true;
+    }
 #endif // SAVE_32BIT_BMP
 
-        if (surface->palette && !save32bit) {
-            if (SDL_BITSPERPIXEL(surface->format) == 8) {
-                intermediate_surface = surface;
-            } else {
-                SDL_SetError("%u bpp BMP files not supported",
-                             SDL_BITSPERPIXEL(surface->format));
-                goto done;
-            }
-        } else if ((SDL_BITSPERPIXEL(surface->format) == 24) && !save32bit &&
+    if (surface->palette && !save32bit) {
+        if (SDL_BITSPERPIXEL(surface->format) == 8) {
+            intermediate_surface = surface;
+        } else {
+            SDL_SetError("%u bpp BMP files not supported",
+                         SDL_BITSPERPIXEL(surface->format));
+            goto done;
+        }
+    } else if ((SDL_BITSPERPIXEL(surface->format) == 24) && !save32bit &&
 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
-                   (surface->fmt->Rmask == 0x00FF0000) &&
-                   (surface->fmt->Gmask == 0x0000FF00) &&
-                   (surface->fmt->Bmask == 0x000000FF)
+               (surface->fmt->Rmask == 0x00FF0000) &&
+               (surface->fmt->Gmask == 0x0000FF00) &&
+               (surface->fmt->Bmask == 0x000000FF)
 #else
-                   (surface->fmt->Rmask == 0x000000FF) &&
-                   (surface->fmt->Gmask == 0x0000FF00) &&
-                   (surface->fmt->Bmask == 0x00FF0000)
+               (surface->fmt->Rmask == 0x000000FF) &&
+               (surface->fmt->Gmask == 0x0000FF00) &&
+               (surface->fmt->Bmask == 0x00FF0000)
 #endif
-        ) {
-            intermediate_surface = surface;
-        } else {
-            SDL_PixelFormat pixel_format;
+    ) {
+        intermediate_surface = surface;
+    } else {
+        SDL_PixelFormat pixel_format;
 
-            /* If the surface has a colorkey or alpha channel we'll save a
-               32-bit BMP with alpha channel, otherwise save a 24-bit BMP. */
-            if (save32bit) {
-                pixel_format = SDL_PIXELFORMAT_BGRA32;
-            } else {
-                pixel_format = SDL_PIXELFORMAT_BGR24;
-            }
-            intermediate_surface = SDL_ConvertSurface(surface, pixel_format);
-            if (!intermediate_surface) {
-                SDL_SetError("Couldn't convert image to %d bpp",
-                             (int)SDL_BITSPERPIXEL(pixel_format));
-                goto done;
-            }
+        /* If the surface has a colorkey or alpha channel we'll save a
+           32-bit BMP with alpha channel, otherwise save a 24-bit BMP. */
+        if (save32bit) {
+            pixel_format = SDL_PIXELFORMAT_BGRA32;
+        } else {
+            pixel_format = SDL_PIXELFORMAT_BGR24;
+        }
+        intermediate_surface = SDL_ConvertSurface(surface, pixel_format);
+        if (!intermediate_surface) {
+            SDL_SetError("Couldn't convert image to %d bpp",
+                         (int)SDL_BITSPERPIXEL(pixel_format));
+            goto done;
         }
-    } else {
-        /* Set no error here because it may overwrite a more useful message from
-           SDL_IOFromFile() if SDL_SaveBMP_IO() is called from SDL_SaveBMP(). */
-        goto done;
     }
 
     if (save32bit) {
@@ -873,5 +874,9 @@ bool SDL_SaveBMP_IO(SDL_Surface *surface, SDL_IOStream *dst, bool closeio)
 
 bool SDL_SaveBMP(SDL_Surface *surface, const char *file)
 {
-    return SDL_SaveBMP_IO(surface, SDL_IOFromFile(file, "wb"), true);
+    SDL_IOStream *stream = SDL_IOFromFile(file, "wb");
+    if (!stream) {
+        return false;
+    }
+    return SDL_SaveBMP_IO(surface, stream, true);
 }