diff options
| author | bdm110 <BDM110@protonmail.com> | 2026-06-05 17:20:24 +0200 |
|---|---|---|
| committer | crueter <crueter@eden-emu.dev> | 2026-06-05 17:20:24 +0200 |
| commit | fb6330645a06a3e0d9e6fa42a4e6f875d9ee065e (patch) | |
| tree | 53bdbbc6de880d614774f94b125e4961dfff66fe /src/core/file_sys/control_metadata.cpp | |
| parent | 48219f348c8558ce3ecd3a8ac0f1b69185ae844b (diff) | |
[file_sys] Avoid crash on empty NACP language entries (#4062)
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>
Diffstat (limited to 'src/core/file_sys/control_metadata.cpp')
| -rw-r--r-- | src/core/file_sys/control_metadata.cpp | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/src/core/file_sys/control_metadata.cpp b/src/core/file_sys/control_metadata.cpp index f86d22d627..2e182f1749 100644 --- a/src/core/file_sys/control_metadata.cpp +++ b/src/core/file_sys/control_metadata.cpp @@ -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; + } + } + + if (!language_entries.empty()) { + return language_entries.front(); } - return language_entries.at(static_cast<u8>(Language::AmericanEnglish)); + static const LanguageEntry empty_entry{}; + return empty_entry; } std::vector<std::string> NACP::GetApplicationNames() const { |
