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);
}