[BUGFIX] for abilities affecting wild encounter tables

fixes a potential buffer overread in TryGetAbilityInfluencedWildMonIndex.
The bug can occur if an electric type mon is in the first slots of a fishing
encounter table and the player carries a mon with the `ABILITY_STATIC` ability.
This never happens in the vanilla codebase.
This commit is contained in:
sbird 2023-09-15 19:11:25 +02:00
parent de3493ff0e
commit 4ed4b69019

View File

@ -52,7 +52,11 @@ static void FeebasSeedRng(u16 seed);
static bool8 IsWildLevelAllowedByRepel(u8 level);
static void ApplyFluteEncounterRateMod(u32 *encRate);
static void ApplyCleanseTagEncounterRateMod(u32 *encRate);
#ifdef BUGFIX
static bool8 TryGetAbilityInfluencedWildMonIndex(const struct WildPokemon *wildMon, u8 type, u8 ability, u8 *monIndex, u32 size);
#else
static bool8 TryGetAbilityInfluencedWildMonIndex(const struct WildPokemon *wildMon, u8 type, u8 ability, u8 *monIndex);
#endif
static bool8 IsAbilityAllowingEncounter(u8 level);
EWRAM_DATA static u8 sWildEncountersDisabled = 0;
@ -409,6 +413,11 @@ static void CreateWildMon(u16 species, u8 level)
CreateMonWithNature(&gEnemyParty[0], species, level, USE_RANDOM_IVS, PickWildMonNature());
}
#ifdef BUGFIX
#define TRY_GET_ABILITY_INFLUENCED_WILD_MON_INDEX(wildPokemon, type, ability, ptr, count) TryGetAbilityInfluencedWildMonIndex(wildPokemon, type, ability, ptr, count)
#else
#define TRY_GET_ABILITY_INFLUENCED_WILD_MON_INDEX(wildPokemon, type, ability, ptr, count) TryGetAbilityInfluencedWildMonIndex(wildPokemon, type, ability, ptr)
#endif
static bool8 TryGenerateWildMon(const struct WildPokemonInfo *wildMonInfo, u8 area, u8 flags)
{
@ -418,15 +427,15 @@ static bool8 TryGenerateWildMon(const struct WildPokemonInfo *wildMonInfo, u8 ar
switch (area)
{
case WILD_AREA_LAND:
if (TryGetAbilityInfluencedWildMonIndex(wildMonInfo->wildPokemon, TYPE_STEEL, ABILITY_MAGNET_PULL, &wildMonIndex))
if (TRY_GET_ABILITY_INFLUENCED_WILD_MON_INDEX(wildMonInfo->wildPokemon, TYPE_STEEL, ABILITY_MAGNET_PULL, &wildMonIndex, LAND_WILD_COUNT))
break;
if (TryGetAbilityInfluencedWildMonIndex(wildMonInfo->wildPokemon, TYPE_ELECTRIC, ABILITY_STATIC, &wildMonIndex))
if (TRY_GET_ABILITY_INFLUENCED_WILD_MON_INDEX(wildMonInfo->wildPokemon, TYPE_ELECTRIC, ABILITY_STATIC, &wildMonIndex, LAND_WILD_COUNT))
break;
wildMonIndex = ChooseWildMonIndex_Land();
break;
case WILD_AREA_WATER:
if (TryGetAbilityInfluencedWildMonIndex(wildMonInfo->wildPokemon, TYPE_ELECTRIC, ABILITY_STATIC, &wildMonIndex))
if (TRY_GET_ABILITY_INFLUENCED_WILD_MON_INDEX(wildMonInfo->wildPokemon, TYPE_ELECTRIC, ABILITY_STATIC, &wildMonIndex, WATER_WILD_COUNT))
break;
wildMonIndex = ChooseWildMonIndex_WaterRock();
@ -923,8 +932,11 @@ static bool8 TryGetRandomWildMonIndexByType(const struct WildPokemon *wildMon, u
*monIndex = validIndexes[Random() % validMonCount];
return TRUE;
}
#ifdef BUGFIX
static bool8 TryGetAbilityInfluencedWildMonIndex(const struct WildPokemon *wildMon, u8 type, u8 ability, u8 *monIndex, u32 size)
#else
static bool8 TryGetAbilityInfluencedWildMonIndex(const struct WildPokemon *wildMon, u8 type, u8 ability, u8 *monIndex)
#endif
{
if (GetMonData(&gPlayerParty[0], MON_DATA_SANITY_IS_EGG))
return FALSE;
@ -933,7 +945,11 @@ static bool8 TryGetAbilityInfluencedWildMonIndex(const struct WildPokemon *wildM
else if (Random() % 2 != 0)
return FALSE;
#ifdef BUGFIX
return TryGetRandomWildMonIndexByType(wildMon, type, size, monIndex);
#else
return TryGetRandomWildMonIndexByType(wildMon, type, LAND_WILD_COUNT, monIndex);
#endif
}
static void ApplyFluteEncounterRateMod(u32 *encRate)