From 6f435661e7840de5366c2d6539d5691f9889f5c7 Mon Sep 17 00:00:00 2001 From: Misa Date: Fri, 29 Dec 2023 11:34:16 -0800 Subject: [PATCH] Add inbounds pixel assertion to DrawPixel/ReadPixel I was running the game through Valgrind and I noticed a memory error where the game was attempting to read a pixel that was just outside the image. Since this is an error that doesn't immediately result in a segfault, I figured that it would be prudent to put in an assertion to make it loud and clear that a memory error is, in fact, happening here. Similarly, drawing to a pixel just outside the surface wouldn't result in a crash, so I copy-pasted the check there too (with changes). --- desktop_version/src/GraphicsUtil.cpp | 30 +++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/desktop_version/src/GraphicsUtil.cpp b/desktop_version/src/GraphicsUtil.cpp index fc990609..303e12f5 100644 --- a/desktop_version/src/GraphicsUtil.cpp +++ b/desktop_version/src/GraphicsUtil.cpp @@ -81,6 +81,20 @@ SDL_Surface* GetSubSurface( SDL_Surface* metaSurface, int x, int y, int width, i void DrawPixel(SDL_Surface* surface, const int x, const int y, const SDL_Color color) { + const SDL_Point point = {x, y}; + const SDL_Rect rect = {0, 0, surface->w, surface->h}; + const bool inbounds = SDL_PointInRect(&point, &rect); + if (!inbounds) + { + WHINE_ONCE_ARGS(( + "Pixel draw is not inbounds: " + "Attempted to draw to %i,%i in %ix%i surface", + x, y, surface->w, surface->h + )); + SDL_assert(0 && "Pixel draw is not inbounds!"); + return; + } + const SDL_PixelFormat* fmt = surface->format; const int bpp = fmt->BytesPerPixel; Uint32* pixel = (Uint32*) ((Uint8*) surface->pixels + y * surface->pitch + x * bpp); @@ -100,10 +114,24 @@ void DrawPixel(SDL_Surface* surface, const int x, const int y, const SDL_Color c SDL_Color ReadPixel(const SDL_Surface* surface, const int x, const int y) { + SDL_Color color = {0, 0, 0, 0}; + const SDL_Point point = {x, y}; + const SDL_Rect rect = {0, 0, surface->w, surface->h}; + const bool inbounds = SDL_PointInRect(&point, &rect); + if (!inbounds) + { + WHINE_ONCE_ARGS(( + "Pixel read is not inbounds: " + "Attempted to read %i,%i in %ix%i surface", + x, y, surface->w, surface->h + )); + SDL_assert(0 && "Pixel read is not inbounds!"); + return color; + } + const SDL_PixelFormat* fmt = surface->format; const int bpp = surface->format->BytesPerPixel; const Uint32* pixel = (Uint32*) ((Uint8*) surface->pixels + y * surface->pitch + x * bpp); - SDL_Color color = {0, 0, 0, 0}; switch (bpp) {