summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGriffinR <griffin.g.richards@gmail.com>2021-07-03 17:25:05 -0400
committerGitHub <noreply@github.com>2021-07-03 17:25:05 -0400
commit585d92f298e1edd8f756f8362de45c9fadc6fcab (patch)
tree2e3b17d37c4782f575329fc0fbe1f7bd406e6bad /src
parent558097f42326f19044a6351004468a46d6ee0b38 (diff)
parentff94d49a45ef605cfaed1268aa5a230958e25cd9 (diff)
Merge pull request #445 from Kurausukun/ubfix
Port UBFIX Macro and Some Usages from Emerald
Diffstat (limited to 'src')
-rw-r--r--src/agb_flash.c8
-rw-r--r--src/battle_ai_script_commands.c5
-rw-r--r--src/battle_anim_mons.c2
-rw-r--r--src/battle_script_commands.c4
-rw-r--r--src/easy_chat.c5
-rw-r--r--src/event_object_movement.c8
-rw-r--r--src/field_effect.c6
-rw-r--r--src/fieldmap.c28
-rw-r--r--src/pokemon_storage_system_7.c7
-rw-r--r--src/sprite.c2
-rw-r--r--src/union_room.c4
11 files changed, 65 insertions, 14 deletions
diff --git a/src/agb_flash.c b/src/agb_flash.c
index bdbfcb294..0b454a41a 100644
--- a/src/agb_flash.c
+++ b/src/agb_flash.c
@@ -127,7 +127,9 @@ void SetReadFlash1(u16 *dest)
}
}
-void ReadFlash_Core(u8 *src, u8 *dest, u32 size)
+
+// Using volatile here to make sure the flash memory will ONLY be read as bytes, to prevent any compiler optimizations.
+void ReadFlash_Core(vu8 *src, u8 *dest, u32 size)
{
while (size-- != 0)
{
@@ -142,7 +144,7 @@ void ReadFlash(u16 sectorNum, u32 offset, void *dest, u32 size)
vu16 readFlash_Core_Buffer[0x40];
vu16 *funcSrc;
vu16 *funcDest;
- void (*readFlash_Core)(u8 *, u8 *, u32);
+ void (*readFlash_Core)(vu8 *, u8 *, u32);
REG_WAITCNT = (REG_WAITCNT & ~WAITCNT_SRAM_MASK) | WAITCNT_SRAM_8;
@@ -164,7 +166,7 @@ void ReadFlash(u16 sectorNum, u32 offset, void *dest, u32 size)
i--;
}
- readFlash_Core = (void (*)(u8 *, u8 *, u32))((s32)readFlash_Core_Buffer + 1);
+ readFlash_Core = (void (*)(vu8 *, u8 *, u32))((s32)readFlash_Core_Buffer + 1);
src = FLASH_BASE + (sectorNum << gFlash->sector.shift) + offset;
diff --git a/src/battle_ai_script_commands.c b/src/battle_ai_script_commands.c
index 952c1487f..a500d591b 100644
--- a/src/battle_ai_script_commands.c
+++ b/src/battle_ai_script_commands.c
@@ -1362,7 +1362,12 @@ static void Cmd_if_status_not_in_party(void)
// everytime the status is found, the AI's logic jumps further and further past its intended destination. this results in a broken AI macro and is probably why it is unused.
if (species != SPECIES_NONE && species != SPECIES_EGG && hp != 0 && status == statusToCompareTo)
+ {
sAIScriptPtr += 10; // doesnt return?
+ #ifdef UBFIX
+ return;
+ #endif
+ }
}
sAIScriptPtr = T1_READ_PTR(sAIScriptPtr + 6);
}
diff --git a/src/battle_anim_mons.c b/src/battle_anim_mons.c
index c47a29976..a62694834 100644
--- a/src/battle_anim_mons.c
+++ b/src/battle_anim_mons.c
@@ -1706,7 +1706,7 @@ void SetBattlerSpriteYOffsetFromOtherYScale(u8 spriteId, u8 otherSpriteId)
{
s32 var = 64 - GetBattlerYDeltaFromSpriteId(otherSpriteId) * 2;
u16 matrix = gSprites[spriteId].oam.matrixNum;
- s32 var2 = (var << 8) / gOamMatrices[matrix].d;
+ s32 var2 = SAFE_DIV((var << 8), gOamMatrices[matrix].d);
if (var2 > 128)
var2 = 128;
diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c
index ee9251017..c6ab568ff 100644
--- a/src/battle_script_commands.c
+++ b/src/battle_script_commands.c
@@ -3108,7 +3108,7 @@ static void atk23_getexp(void)
calculatedExp = gBaseStats[gBattleMons[gBattlerFainted].species].expYield * gBattleMons[gBattlerFainted].level / 7;
if (viaExpShare) // at least one mon is getting exp via exp share
{
- *exp = calculatedExp / 2 / viaSentIn;
+ *exp = SAFE_DIV(calculatedExp / 2, viaSentIn);
if (*exp == 0)
*exp = 1;
gExpShareExp = calculatedExp / 2 / viaExpShare;
@@ -3117,7 +3117,7 @@ static void atk23_getexp(void)
}
else
{
- *exp = calculatedExp / viaSentIn;
+ *exp = SAFE_DIV(calculatedExp, viaSentIn);
if (*exp == 0)
*exp = 1;
gExpShareExp = 0;
diff --git a/src/easy_chat.c b/src/easy_chat.c
index 4360dc72e..55bc104db 100644
--- a/src/easy_chat.c
+++ b/src/easy_chat.c
@@ -459,12 +459,17 @@ void InitEasyChatPhrases(void)
gSaveBlock1Ptr->mail[i].words[j] = EC_WORD_UNDEFINED;
}
+#ifndef UBFIX
// BUG: This is supposed to clear 64 bits, but this loop is clearing 64 bytes.
// However, this bug has no resulting effect on gameplay because only the
// Mauville old man data is corrupted, which is initialized directly after
// this function is called when starting a new game.
for (i = 0; i < 64; i++)
gSaveBlock1Ptr->additionalPhrases[i] = 0;
+#else
+ for (i = 0; i < NELEMS(gSaveBlock1Ptr->additionalPhrases); i++)
+ gSaveBlock1Ptr->additionalPhrases[i] = 0;
+#endif
}
void EC_ResetMEventProfileMaybe(void)
diff --git a/src/event_object_movement.c b/src/event_object_movement.c
index a671ada34..14914bf92 100644
--- a/src/event_object_movement.c
+++ b/src/event_object_movement.c
@@ -2561,7 +2561,13 @@ const u8 *GetObjectEventScriptPointerByObjectEventId(u8 objectEventId)
static u16 GetObjectEventFlagIdByLocalIdAndMap(u8 localId, u8 mapNum, u8 mapGroup)
{
- return GetObjectEventTemplateByLocalIdAndMap(localId, mapNum, mapGroup)->flagId;
+ struct ObjectEventTemplate *obj = GetObjectEventTemplateByLocalIdAndMap(localId, mapNum, mapGroup);
+#ifdef UBFIX
+ // BUG: The function may return NULL, and attempting to read from NULL may freeze the game using modern compilers.
+ if (obj == NULL)
+ return 0;
+#endif // UBFIX
+ return obj->flagId;
}
static u16 GetObjectEventFlagIdByObjectEventId(u8 objectEventId)
diff --git a/src/field_effect.c b/src/field_effect.c
index 4cab3cff8..206b695b0 100644
--- a/src/field_effect.c
+++ b/src/field_effect.c
@@ -3666,8 +3666,10 @@ static void Task_MoveDeoxysRock_Step(u8 taskId)
case 0:
data[4] = sprite->pos1.x << 4;
data[5] = sprite->pos1.y << 4;
- data[6] = ((data[2] << 4) - data[4]) / data[8];
- data[7] = ((data[3] << 4) - data[5]) / data[8];
+
+ // UB: Possible divide by zero
+ data[6] = SAFE_DIV(((data[2] << 4) - data[4]), data[8]);
+ data[7] = SAFE_DIV(((data[3] << 4) - data[5]), data[8]);
data[0]++;
// fallthrough
case 1:
diff --git a/src/fieldmap.c b/src/fieldmap.c
index 7ece8b622..400fc4cff 100644
--- a/src/fieldmap.c
+++ b/src/fieldmap.c
@@ -528,10 +528,14 @@ static bool32 SavedMapViewIsEmpty(void)
u16 i;
u32 marker = 0;
+#ifndef UBFIX
// BUG: This loop extends past the bounds of the mapView array. Its size is only 0x100.
for (i = 0; i < 0x200; i++)
marker |= gSaveBlock2Ptr->mapView[i];
-
+#else
+ for (i = 0; i < NELEMS(gSaveBlock2Ptr->mapView); i++)
+ marker |= gSaveBlock2Ptr->mapView[i];
+#endif
if (marker == 0)
return TRUE;
else
@@ -746,14 +750,32 @@ struct MapConnection *sub_8059600(u8 direction, s32 x, s32 y)
{
s32 count;
struct MapConnection *connection;
+ const struct MapConnections *connections = gMapHeader.connections;
s32 i;
- count = gMapHeader.connections->count;
- connection = gMapHeader.connections->connections;
+ // UB: Multiple possible null dereferences
+#ifdef UBFIX
+ if (connections != NULL)
+ {
+ count = connections->count;
+ connection = connections->connections;
+ if (connection != NULL)
+ {
+ for (i = 0; i < count; i++, connection++)
+ {
+ if (connection->direction == direction && sub_8059658(direction, x, y, connection) == TRUE)
+ return connection;
+ }
+ }
+ }
+#else
+ count = connections->count;
+ connection = connections->connections;
for (i = 0; i < count; i++, connection++)
{
if (connection->direction == direction && sub_8059658(direction, x, y, connection) == TRUE)
return connection;
}
+#endif
return NULL;
}
diff --git a/src/pokemon_storage_system_7.c b/src/pokemon_storage_system_7.c
index 3d0472230..a9b538cae 100644
--- a/src/pokemon_storage_system_7.c
+++ b/src/pokemon_storage_system_7.c
@@ -473,8 +473,13 @@ static void sub_80957C8(void)
for (j = sMoveMonsPtr->minRow; j < rowCount; j++)
{
struct BoxPokemon *boxMon = GetBoxedMonPtr(boxId, boxPosition);
-
+ // UB: possible null dereference
+#ifdef UBFIX
+ if (boxMon != NULL)
+ sMoveMonsPtr->boxMons[monArrayId] = *boxMon;
+#else
sMoveMonsPtr->boxMons[monArrayId] = *boxMon;
+#endif
monArrayId++;
boxPosition++;
}
diff --git a/src/sprite.c b/src/sprite.c
index af03aaf11..972fd932d 100644
--- a/src/sprite.c
+++ b/src/sprite.c
@@ -1333,7 +1333,7 @@ void ApplyAffineAnimFrameRelativeAndUpdateMatrix(u8 matrixNum, struct AffineAnim
s16 ConvertScaleParam(s16 scale)
{
s32 val = 0x10000;
- return val / scale;
+ return SAFE_DIV(val, scale);
}
void GetAffineAnimFrame(u8 matrixNum, struct Sprite *sprite, struct AffineAnimFrameCmd *frameCmd)
diff --git a/src/union_room.c b/src/union_room.c
index 5fc8730e5..9b0a9263d 100644
--- a/src/union_room.c
+++ b/src/union_room.c
@@ -1628,7 +1628,11 @@ static bool32 IsPartnerActivityAcceptable(u32 activity, u32 group)
if (group == 0xFF)
return TRUE;
+ #ifndef UBFIX
if (group <= NELEMS(sAcceptedActivityIds)) // UB: <= may access data outside the array
+ #else
+ if (group < NELEMS(sAcceptedActivityIds))
+ #endif
{
const u8 *bytes = sAcceptedActivityIds[group];