From bc03ff3fa0fe1aa082af23c53b2ad47fd537729c Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 8 Feb 2026 17:29:54 +0000 Subject: [PATCH] Fix #15247: crash when handling invalid sprite in OpenGL cursor sprite system (#15248) --- src/spritecache.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/spritecache.cpp b/src/spritecache.cpp index 4fef4a26f7..f26695a419 100644 --- a/src/spritecache.cpp +++ b/src/spritecache.cpp @@ -802,10 +802,12 @@ void *UniquePtrSpriteAllocator::AllocatePtr(size_t size) * @param sprite ID of loaded sprite * @param requested requested sprite type * @param sc the currently known sprite cache for the requested sprite + * @param allocator Callback that provides the memory when loading sprites. + * @param encoder Sprite encoder to use. Set to nullptr to use the currently active blitter. * @return fallback sprite * @note this function will do UserError() in the case the fallback sprite isn't available */ -static void *HandleInvalidSpriteRequest(SpriteID sprite, SpriteType requested, SpriteCache *sc, SpriteAllocator *allocator) +static void *HandleInvalidSpriteRequest(SpriteID sprite, SpriteType requested, SpriteCache *sc, SpriteAllocator *allocator, SpriteEncoder *encoder) { static const std::string_view sprite_types[] = { "normal", // SpriteType::Normal @@ -817,7 +819,7 @@ static void *HandleInvalidSpriteRequest(SpriteID sprite, SpriteType requested, S SpriteType available = sc->type; if (requested == SpriteType::Font && available == SpriteType::Normal) { if (sc->ptr == nullptr) sc->type = SpriteType::Font; - return GetRawSprite(sprite, sc->type, allocator); + return GetRawSprite(sprite, sc->type, allocator, encoder); } uint8_t warning_level = sc->warned ? 6 : 0; @@ -829,10 +831,10 @@ static void *HandleInvalidSpriteRequest(SpriteID sprite, SpriteType requested, S if (sprite == SPR_IMG_QUERY) UserError("Uhm, would you be so kind not to load a NewGRF that makes the 'query' sprite a non-normal sprite?"); [[fallthrough]]; case SpriteType::Font: - return GetRawSprite(SPR_IMG_QUERY, SpriteType::Normal, allocator); + return GetRawSprite(SPR_IMG_QUERY, SpriteType::Normal, allocator, encoder); case SpriteType::Recolour: if (sprite == PALETTE_TO_DARK_BLUE) UserError("Uhm, would you be so kind not to load a NewGRF that makes the 'PALETTE_TO_DARK_BLUE' sprite a non-remap sprite?"); - return GetRawSprite(PALETTE_TO_DARK_BLUE, SpriteType::Recolour, allocator); + return GetRawSprite(PALETTE_TO_DARK_BLUE, SpriteType::Recolour, allocator, encoder); case SpriteType::MapGen: /* this shouldn't happen, overriding of SpriteType::MapGen sprites is checked in LoadNextSprite() * (the only case the check fails is when these sprites weren't even loaded...) */ @@ -864,7 +866,7 @@ void *GetRawSprite(SpriteID sprite, SpriteType type, SpriteAllocator *allocator, SpriteCache *sc = GetSpriteCache(sprite); - if (sc->type != type) return HandleInvalidSpriteRequest(sprite, type, sc, allocator); + if (sc->type != type) return HandleInvalidSpriteRequest(sprite, type, sc, allocator, encoder); if (allocator == nullptr && encoder == nullptr) { /* Load sprite into/from spritecache */