From abb9bec571ebb511486bd756049cfa3327168f5b Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 31 Dec 2024 01:45:03 -0800 Subject: [PATCH] GB Core: Fix cloning savedata when backing file is outdated (fixes #3388) --- CHANGES | 1 + src/gb/core.c | 35 ++++++++++++++++++++++++----------- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/CHANGES b/CHANGES index b5b2f4fe1..595943d3d 100644 --- a/CHANGES +++ b/CHANGES @@ -19,6 +19,7 @@ Other fixes: - Core: Fix inconsistencies with setting game-specific overrides (fixes mgba.io/i/2963) - Debugger: Fix writing to specific segment in command-line debugger - FFmpeg: Fix failing to record videos with CRF video (fixes mgba.io/i/3368) + - GB Core: Fix cloning savedata when backing file is outdated (fixes mgba.io/i/3388) - GB Serialize: Prevent loading invalid states where LY >= 144 in modes other than 1 - GBA: Fix getting game info for multiboot ROMs - GBA Core: Fix booting into BIOS when skip BIOS is enabled diff --git a/src/gb/core.c b/src/gb/core.c index b97e1ee25..f71b570e0 100644 --- a/src/gb/core.c +++ b/src/gb/core.c @@ -1167,19 +1167,32 @@ static struct mCheatDevice* _GBCoreCheatDevice(struct mCore* core) { static size_t _GBCoreSavedataClone(struct mCore* core, void** sram) { struct GB* gb = core->board; - struct VFile* vf = gb->sramVf; - if (vf) { - *sram = malloc(vf->size(vf)); - vf->seek(vf, 0, SEEK_SET); - return vf->read(vf, *sram, vf->size(vf)); + size_t sramSize = gb->sramSize; + size_t vfSize = 0; + size_t size = sramSize; + uint8_t* view = NULL; + + if (gb->sramVf) { + vfSize = gb->sramVf->size(gb->sramVf); + if (vfSize > size) { + size = vfSize; + } } - if (gb->sramSize) { - *sram = malloc(gb->sramSize); - memcpy(*sram, gb->memory.sram, gb->sramSize); - return gb->sramSize; + if (!size) { + *sram = NULL; + return 0; } - *sram = NULL; - return 0; + + view = malloc(size); + if (sramSize) { + memcpy(view, gb->memory.sram, gb->sramSize); + } + if (vfSize > sramSize) { + gb->sramVf->seek(gb->sramVf, sramSize, SEEK_SET); + gb->sramVf->read(gb->sramVf, &view[sramSize], vfSize - sramSize); + } + *sram = view; + return size; } static bool _GBCoreSavedataRestore(struct mCore* core, const void* sram, size_t size, bool writeback) {