From 0be7869a71757f41d8446bed6f3ce91f17333d0e Mon Sep 17 00:00:00 2001 From: Robert Crossfield Date: Sun, 24 May 2026 12:13:43 +1000 Subject: [PATCH] Harden Amiga CF2 sprite palette and RAW bounds checks --- Source/Amiga/Graphics_Amiga2.cpp | 18 +++++++++++++++++- Source/Graphics.hpp | 8 +++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/Source/Amiga/Graphics_Amiga2.cpp b/Source/Amiga/Graphics_Amiga2.cpp index 3038c1e6..625848cc 100644 --- a/Source/Amiga/Graphics_Amiga2.cpp +++ b/Source/Amiga/Graphics_Amiga2.cpp @@ -38,6 +38,17 @@ void cGraphics_Amiga2::Map_Load_Resources() { mSpriteSheet_InGame2.mDimension.mHeight = 0x151; mSpriteSheet_InGame1.mDimension.mHeight = 0x150; + auto ValidateRawSize = [](sImage& pImage) { + const size_t RowStrideBytes = pImage.mDimension.mWidth >> 3; + const size_t RequiredBytes = RowStrideBytes * pImage.mDimension.mHeight * pImage.mPlanes; + + if (pImage.mData->size() < RequiredBytes) + pImage = sImage(); + }; + + ValidateRawSize(mSpriteSheet_InGame2); + ValidateRawSize(mSpriteSheet_InGame1); + SetActiveSpriteSheet(eGFX_IN_GAME); } @@ -142,6 +153,11 @@ sImage cGraphics_Amiga2::GetImage(const std::string& pFilename, const size_t pPa Decoded.mDimension.mWidth = 0x140; Decoded.mDimension.mHeight = 0x100; + const size_t RowStrideBytes = Decoded.mDimension.mWidth >> 3; + const size_t RequiredBytes = RowStrideBytes * Decoded.mDimension.mHeight * Decoded.mPlanes; + if (Decoded.mData->size() < RequiredBytes) + return sImage(); + Decoded.LoadPalette_Amiga((uint8*)Palette->data(), Palette->size() / 2, pPaletteIndex); return Decoded; @@ -221,4 +237,4 @@ void cGraphics_Amiga2::Recruit_Draw_Hill() { } Recruit_Draw_HomeAway(); -} \ No newline at end of file +} diff --git a/Source/Graphics.hpp b/Source/Graphics.hpp index 74204132..4fddc73c 100644 --- a/Source/Graphics.hpp +++ b/Source/Graphics.hpp @@ -93,8 +93,14 @@ struct sImage { void LoadPalette_Amiga( const uint8 *pFrom, const size_t pCount, const size_t pStartColorID = 0 ) { uint16 color; + const size_t PaletteLimit = sizeof(mPalette) / sizeof(mPalette[0]); - for (size_t ColorID = pStartColorID; ColorID < pStartColorID + pCount; ColorID++) { + if (pStartColorID >= PaletteLimit) + return; + + const size_t ColorsToRead = std::min(pCount, PaletteLimit - pStartColorID); + + for (size_t ColorID = pStartColorID; ColorID < pStartColorID + ColorsToRead; ColorID++) { // Get the next color codes color = readBEWord(pFrom);