Improve error handling for parsing banners. Fixes #18

This commit is contained in:
Gericom
2026-03-29 11:47:08 +02:00
parent 7c06abf224
commit 3f780fdd69
2 changed files with 40 additions and 39 deletions

View File

@@ -2,52 +2,60 @@
#include <string.h>
#include <nds/arm9/cache.h>
#include "fat/File.h"
#include "romBrowser/ICoverRepository.h"
#include "NdsInternalFileInfo.h"
NdsInternalFileInfo::NdsInternalFileInfo(const FastFileRef& fastFileRef)
{
const auto file = std::make_unique<File>();
_hasBanner = false;
memset(_gameCode, 0, sizeof(_gameCode));
file->Open(fastFileRef, FA_READ);
if (file->Seek(0xC) != FR_OK)
return;
u32 bytesRead;
if (file->Read(_gameCode, 4, bytesRead) != FR_OK)
return;
if (file->Seek(0x68) != FR_OK)
return;
u32 bannerOffset;
if (file->Read(&bannerOffset, 4, bytesRead) != FR_OK)
return;
if (bannerOffset == 0)
return;
if (file->Seek(bannerOffset) != FR_OK)
return;
if (file->Read(&_banner, 0xA00, bytesRead) != FR_OK)
return;
if (_banner.header.version >= NDS_BANNER_VERSION_103)
if (file->Seek(0xC) != FR_OK ||
!file->ReadExact(_gameCode, 4) ||
file->Seek(0x68) != FR_OK ||
!file->ReadExact(&bannerOffset, 4) ||
bannerOffset == 0 ||
bannerOffset >= file->GetSize() ||
file->Seek(bannerOffset) != FR_OK ||
!file->ReadExact(&_banner, 0x840))
{
if (file->Read(((u8*)&_banner) + 0xA00, 0x19C0, bytesRead) != FR_OK)
return;
}
if (_banner.header.version >= NDS_BANNER_VERSION_2 &&
!file->ReadExact(((u8*)&_banner) + 0x840, 0x100))
{
return;
}
if (_banner.header.version >= NDS_BANNER_VERSION_3 &&
!file->ReadExact(((u8*)&_banner) + 0x940, 0x100))
{
return;
}
if (_banner.header.version >= NDS_BANNER_VERSION_103 &&
!file->ReadExact(((u8*)&_banner) + 0xA40, 0x1980))
{
return;
}
_hasBanner = true;
DC_FlushRange(&_banner, sizeof(_banner));
}
const char16_t* NdsInternalFileInfo::GetGameTitle() const
{
if (!_hasBanner)
return nullptr;
return _banner.title[NDS_BANNER_TITLE_LANGUAGE_ENGLISH];
return _hasBanner
? _banner.title[NDS_BANNER_TITLE_LANGUAGE_ENGLISH]
: nullptr;
}
std::unique_ptr<FileIcon> NdsInternalFileInfo::CreateGameIcon() const
{
return _hasBanner
? std::make_unique<NdsFileIcon>(&_banner)
: nullptr;
}

View File

@@ -12,18 +12,11 @@ public:
constexpr const char* GetGameCode() const override { return _gameCode; }
const char16_t* GetGameTitle() const override;
std::unique_ptr<FileIcon> CreateGameIcon() const override
{
if (!_hasBanner)
return nullptr;
return std::make_unique<NdsFileIcon>(&_banner);
}
std::unique_ptr<FileIcon> CreateGameIcon() const override;
const nds_banner_t& GetBanner() const { return _banner; }
private:
nds_banner_t _banner alignas(32);
bool _hasBanner;
bool _hasBanner = false;
char _gameCode[5];
};