[file_sys] Avoid crash on empty NACP language entries (#4062)
Some checks are pending
tx-src / sources (push) Waiting to run
Check Strings / check-strings (push) Waiting to run

This fixes an Android game library scan crash when reading XCI title metadata with empty or incomplete NACP language entries.

Previously, NACP::GetLanguageEntry() could fall back to:

language_entries.at(static_cast<u8>(Language::AmericanEnglish))

When language_entries was empty, this threw std::out_of_range and aborted the Android scan thread.

The new fallback preserves the existing lookup order:
1. preferred language entry with non-empty application name
2. any entry with non-empty application name
3. first available entry
4. static empty LanguageEntry if no entries exist

Tested locally with a Mainline RelWithDebInfo APK on Odin3 Android 15 using a large external TF-card ROM directory. The previous build crashed during fresh ROM scan; the patched build completes scanning normally.

Related my issue:
https://github.com/eden-emulator/Issue-Reports/issues/500

Co-authored-by: bdm110 <bdm110@prontmail.com>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4062
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: crueter <crueter@eden-emu.dev>
This commit is contained in:
bdm110 2026-06-05 17:20:24 +02:00 committed by crueter
parent 48219f348c
commit fb6330645a
No known key found for this signature in database
GPG key ID: 425ACD2D4830EBC6

View file

@ -128,25 +128,32 @@ const LanguageEntry& NACP::GetLanguageEntry() const {
case Settings::Language::Russian: return Language::Russian;
case Settings::Language::Spanish: return Language::Spanish;
case Settings::Language::SpanishLatin: return Language::LatinAmericanSpanish;
case Settings::Language::Taiwanese: return Language::SimplifiedChinese;
case Settings::Language::Taiwanese: return Language::TraditionalChinese;
case Settings::Language::Thai: return Language::Thai;
case Settings::Language::Polish: return Language::Polish;
default: return Language::AmericanEnglish;
}
}();
u32 index = u32(language);
const auto index = static_cast<size_t>(language);
if (index < language_entries.size() && !language_entries[index].GetApplicationName().empty()) {
if (index < language_entries.size() &&
!language_entries[index].GetApplicationName().empty()) {
return language_entries[index];
}
for (const auto& entry : language_entries) {
if (!entry.GetApplicationName().empty())
return entry;
if (!entry.GetApplicationName().empty()) {
return entry;
}
}
return language_entries.at(static_cast<u8>(Language::AmericanEnglish));
if (!language_entries.empty()) {
return language_entries.front();
}
static const LanguageEntry empty_entry{};
return empty_entry;
}
std::vector<std::string> NACP::GetApplicationNames() const {