Compare commits

..

2 commits

Author SHA1 Message Date
BoiledElectricity
470d43df6d
[hid_core] fix bounds-check aruid index in GetControllerFromNpadIdType (#4064)
Some checks are pending
tx-src / sources (push) Waiting to run
Check Strings / check-strings (push) Waiting to run
GetIndexFromAruid returns AruidIndexMax as the “not found” value, but both
GetControllerFromNpadIdType overloads were using that value to index
controller_data without checking it first.

when a game routes through DisconnectNpad before its applet resource is
registered, we can end up indexing past the end of controller_data. That seems
to be what was crashing some games on launch, especially on macOS and Android,
where the out-of-bounds read is less likely to just slide by unnoticed.

So yeah, AruidIndexMax is a sentinel, not a real controller_data index, so we
should not treat it like one.

  Fixes: https://github.com/eden-emulator/Issue-Reports/issues/438
  Fixes: https://github.com/eden-emulator/Issue-Reports/issues/439

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4064
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
2026-06-05 19:26:21 +02:00
bdm110
fb6330645a
[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>
2026-06-05 17:20:24 +02:00
2 changed files with 23 additions and 8 deletions

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 {

View file

@ -1144,7 +1144,11 @@ NPad::NpadControllerData& NPad::GetControllerFromNpadIdType(u64 aruid,
npad_id = Core::HID::NpadIdType::Player1;
}
const auto npad_index = NpadIdTypeToIndex(npad_id);
const auto aruid_index = applet_resource_holder.applet_resource->GetIndexFromAruid(aruid);
auto aruid_index = applet_resource_holder.applet_resource->GetIndexFromAruid(aruid);
if (aruid_index >= AruidIndexMax) {
LOG_ERROR(Service_HID, "Invalid aruid:{:016X}", aruid);
aruid_index = 0;
}
return controller_data[aruid_index][npad_index];
}
@ -1155,7 +1159,11 @@ const NPad::NpadControllerData& NPad::GetControllerFromNpadIdType(
npad_id = Core::HID::NpadIdType::Player1;
}
const auto npad_index = NpadIdTypeToIndex(npad_id);
const auto aruid_index = applet_resource_holder.applet_resource->GetIndexFromAruid(aruid);
auto aruid_index = applet_resource_holder.applet_resource->GetIndexFromAruid(aruid);
if (aruid_index >= AruidIndexMax) {
LOG_ERROR(Service_HID, "Invalid aruid:{:016X}", aruid);
aruid_index = 0;
}
return controller_data[aruid_index][npad_index];
}