Fixes UB in Cmd_averagestats (#5191)

* Fixes UB in Cmd_averagestats

* fix test and align default case
This commit is contained in:
Alex 2024-08-17 18:19:22 +02:00 committed by GitHub
parent 3a0c5c9c6c
commit 8607a7fb33
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 60 additions and 7 deletions

View file

@ -15669,17 +15669,26 @@ static void Cmd_swapstatstages(void)
gBattlescriptCurrInstr = cmd->nextInstr;
}
static u16 *GetBattlerStat(struct BattlePokemon *battler, u32 stat)
{
switch (stat)
{
case STAT_ATK: return &battler->attack;
case STAT_DEF: return &battler->defense;
case STAT_SPATK: return &battler->spAttack;
case STAT_SPDEF: return &battler->spDefense;
default: return NULL;
}
}
static void Cmd_averagestats(void)
{
CMD_ARGS(u8 stat);
u8 stat = cmd->stat;
u16 atkStat = *(u16 *)((&gBattleMons[gBattlerAttacker].attack) + (stat - 1));
u16 defStat = *(u16 *)((&gBattleMons[gBattlerTarget].attack) + (stat - 1));
u16 average = (atkStat + defStat) / 2;
*(u16 *)((&gBattleMons[gBattlerAttacker].attack) + (stat - 1)) = average;
*(u16 *)((&gBattleMons[gBattlerTarget].attack) + (stat - 1)) = average;
u16 *stat1 = GetBattlerStat(&gBattleMons[gBattlerAttacker], cmd->stat);
u16 *stat2 = GetBattlerStat(&gBattleMons[gBattlerTarget], cmd->stat);
u16 avg = (*stat1 + *stat2) / 2;
*stat1 = *stat2 = avg;
gBattlescriptCurrInstr = cmd->nextInstr;
}

View file

@ -0,0 +1,22 @@
#include "global.h"
#include "test/battle.h"
ASSUMPTIONS
{
ASSUME(gMovesInfo[MOVE_GUARD_SPLIT].effect == EFFECT_GUARD_SPLIT);
}
SINGLE_BATTLE_TEST("Guard Split averages users and targets Def and Sp. Def stats")
{
GIVEN {
PLAYER(SPECIES_BULBASAUR);
OPPONENT(SPECIES_IVYSAUR);
} WHEN {
TURN { MOVE(player, MOVE_GUARD_SPLIT); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_GUARD_SPLIT, player);
} THEN {
EXPECT_EQ(player->defense, opponent->defense);
EXPECT_EQ(player->spDefense, opponent->spDefense);
}
}

View file

@ -0,0 +1,22 @@
#include "global.h"
#include "test/battle.h"
ASSUMPTIONS
{
ASSUME(gMovesInfo[MOVE_POWER_SPLIT].effect == EFFECT_POWER_SPLIT);
}
SINGLE_BATTLE_TEST("Power Split averages user and targets Atk and Sp. Atk stats")
{
GIVEN {
PLAYER(SPECIES_BULBASAUR);
OPPONENT(SPECIES_IVYSAUR);
} WHEN {
TURN { MOVE(player, MOVE_POWER_SPLIT); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_POWER_SPLIT, player);
} THEN {
EXPECT_EQ(player->attack, opponent->attack);
EXPECT_EQ(player->spAttack, opponent->spAttack);
}
}