From 840e4316c6575b1ebe90efc1b90577dd22db16fa 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 | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/spritecache.cpp b/src/spritecache.cpp index 39b40b72d8..562756d31f 100644 --- a/src/spritecache.cpp +++ b/src/spritecache.cpp @@ -803,10 +803,11 @@ void *UniquePtrSpriteAllocator::AllocatePtr(size_t size) * @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 @@ -818,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; @@ -830,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...) */ @@ -865,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 */