surface: verify surface palette in SDL_Save(BMP|PNG) before hitting the FS

(cherry picked from commit 28ea4a8e31)
This commit is contained in:
Anonymous Maarten
2026-02-03 09:32:37 -08:00
committed by Sam Lantinga
parent d9bc9dda7a
commit 775eac98ee
3 changed files with 154 additions and 79 deletions
+116 -78
View File
File diff suppressed because it is too large Load Diff
+9 -1
View File
@@ -395,7 +395,7 @@ bool SDL_SavePNG_IO(SDL_Surface *surface, SDL_IOStream *dst, bool closeio)
Uint8 *trns = NULL;
bool free_surface = false;
// Make sure we have somewhere to save
// Make sure we have something to save
CHECK_PARAM(!SDL_SurfaceValid(surface)) {
SDL_InvalidParamError("surface");
goto done;
@@ -478,6 +478,14 @@ done:
bool SDL_SavePNG(SDL_Surface *surface, const char *file)
{
#ifdef SDL_HAVE_STB
// Make sure we have something to save
CHECK_PARAM(!SDL_SurfaceValid(surface)) {
return SDL_InvalidParamError("surface");
}
if (SDL_ISPIXELFORMAT_INDEXED(surface->format) && !surface->palette) {
return SDL_SetError("Indexed surfaces must have a palette");
}
SDL_IOStream *stream = SDL_IOFromFile(file, "wb");
if (!stream) {
return false;
+29
View File
@@ -328,6 +328,7 @@ static int SDLCALL surface_testSaveLoad(void *arg)
int ret;
const char *sampleFilename = "testSaveLoad.tmp";
SDL_Surface *face;
SDL_Surface *indexed_surface;
SDL_Surface *rface;
SDL_Palette *palette;
SDL_Color colors[] = {
@@ -344,6 +345,18 @@ static int SDLCALL surface_testSaveLoad(void *arg)
return TEST_ABORTED;
}
indexed_surface = SDL_CreateSurface(32, 32, SDL_PIXELFORMAT_INDEX8);
SDLTest_AssertCheck(indexed_surface != NULL, "SDL_CreateSurface(SDL_PIXELFORMAT_INDEX8)");
/* Delete test file; ignore errors */
SDL_RemovePath(sampleFilename);
/* Saving an indexed surface without palette as BMP fails */
ret = SDL_SaveBMP(indexed_surface, sampleFilename);
SDLTest_AssertPass("Call to SDL_SaveBMP() using an indexed surface without palette");
SDLTest_AssertCheck(ret == false, "Verify result of SDL_SaveBMP(indexed_surface without palette), expected: false, got: %i", ret);
SDLTest_AssertCheck(!SDL_GetPathInfo(sampleFilename, NULL), "No file is created after trying to save a indexed surface without palette");
/* Delete test file; ignore errors */
SDL_RemovePath(sampleFilename);
@@ -367,6 +380,15 @@ static int SDLCALL surface_testSaveLoad(void *arg)
/* Delete test file; ignore errors */
SDL_RemovePath(sampleFilename);
/* Saving an indexed surface as PNG fails */
ret = SDL_SavePNG(indexed_surface, sampleFilename);
SDLTest_AssertPass("Call to SDL_SavePNG() using an indexed surface without palette");
SDLTest_AssertCheck(ret == false, "Verify result of SDL_SavePNG(indexed surface without palette), expected: false, got: %i", ret);
SDLTest_AssertCheck(ret == false, "Verify result of SDL_SavePNG(indexed surface without palette), expected: false, got: %i", ret);
/* Delete test file; ignore errors */
SDL_RemovePath(sampleFilename);
/* Save a PNG surface */
ret = SDL_SavePNG(face, sampleFilename);
SDLTest_AssertPass("Call to SDL_SavePNG()");
@@ -416,6 +438,9 @@ static int SDLCALL surface_testSaveLoad(void *arg)
if (stream == NULL) {
return TEST_ABORTED;
}
ret = SDL_SaveBMP_IO(indexed_surface, stream, false);
SDLTest_AssertCheck(ret == false, "Verify result from SDL_SaveBMP (indexed surface without palette), expected: false, got: %i", ret);
SDL_SeekIO(stream, 0, SDL_IO_SEEK_SET);
ret = SDL_SaveBMP_IO(face, stream, false);
SDLTest_AssertPass("Call to SDL_SaveBMP()");
SDLTest_AssertCheck(ret == true, "Verify result from SDL_SaveBMP, expected: true, got: %i", ret);
@@ -447,6 +472,9 @@ static int SDLCALL surface_testSaveLoad(void *arg)
if (stream == NULL) {
return TEST_ABORTED;
}
ret = SDL_SavePNG_IO(indexed_surface, stream, false);
SDLTest_AssertCheck(ret == false, "Verify result from SDL_SavePNG_IO (indexed surface without palette), expected: false, got: %i", ret);
SDL_SeekIO(stream, 0, SDL_IO_SEEK_SET);
ret = SDL_SavePNG_IO(face, stream, false);
SDLTest_AssertPass("Call to SDL_SavePNG()");
SDLTest_AssertCheck(ret == true, "Verify result from SDL_SavePNG, expected: true, got: %i", ret);
@@ -472,6 +500,7 @@ static int SDLCALL surface_testSaveLoad(void *arg)
SDL_CloseIO(stream);
stream = NULL;
SDL_DestroySurface(indexed_surface);
SDL_DestroySurface(face);
return TEST_COMPLETED;