From cfa0d04bbbc4e8792089f77e6cddc263c1bd9751 Mon Sep 17 00:00:00 2001 From: Misa Date: Sun, 14 Nov 2021 14:02:51 -0800 Subject: [PATCH] `LoadImage`: Check LodePNG return value and print errors Dvoid from Discord just reported a crash when trying to load a custom tiles2.png that was encoded weirdly. The problem is that we don't check the return value from LodePNG, so LodePNG gives us a null pointer, and then SDL_CreateRGBSurfaceFrom doesn't check this null pointer, which then propagates until we crash in SDL_ConvertSurfaceFormat (or rather, one of its sub-functions), and we would probably crash somewhere else anyway if it continued. After properly checking LodePNG's return value, along with printing the error, it turns out that Dvoid's custom tiles2.png had an "invalid CRC". I don't know what this means but it sounds worrying. `feh` can read the file correctly but it also reports a "CRC error". --- desktop_version/src/GraphicsResources.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/desktop_version/src/GraphicsResources.cpp b/desktop_version/src/GraphicsResources.cpp index 0b07cd3e..37f609c8 100644 --- a/desktop_version/src/GraphicsResources.cpp +++ b/desktop_version/src/GraphicsResources.cpp @@ -22,6 +22,7 @@ extern "C" const unsigned char* in, size_t insize ); + extern const char* lodepng_error_text(unsigned code); } static SDL_Surface* LoadImage(const char *filename, bool noBlend = true, bool noAlpha = false) @@ -33,6 +34,7 @@ static SDL_Surface* LoadImage(const char *filename, bool noBlend = true, bool no unsigned char *data; unsigned int width, height; + unsigned int error; unsigned char *fileIn; size_t length; @@ -44,14 +46,20 @@ static SDL_Surface* LoadImage(const char *filename, bool noBlend = true, bool no } if (noAlpha) { - lodepng_decode24(&data, &width, &height, fileIn, length); + error = lodepng_decode24(&data, &width, &height, fileIn, length); } else { - lodepng_decode32(&data, &width, &height, fileIn, length); + error = lodepng_decode32(&data, &width, &height, fileIn, length); } FILESYSTEM_freeMemory(&fileIn); + if (error != 0) + { + fprintf(stderr, "Could not load %s: %s\n", filename, lodepng_error_text(error)); + return NULL; + } + loadedImage = SDL_CreateRGBSurfaceFrom( data, width,