Fix a few cases of UB incl. OoB

Behaviour should be mostly the same but there are some OoB accesses in the menu code where I've had to assume things.

Tests for each OoB case:

- Accessing of layer -1: Select a game file in the "Choose Your Reality" screen.
- Accessing of menu for the 5th player: Die in a mission.
This commit is contained in:
GreaseMonkey committed 2023-08-29 10:23:14 +12:00
1 parent d2574c4b49
commit 889ae950fe
4 files changed
+36 -2

No files matched your search

+9
View File
@@ -1,4 +1,5 @@
#include <ultra64.h>
#include <string.h>
#include "constants.h"
#include "game/atan2f.h"
#include "game/camera.h"
@@ -600,6 +601,9 @@ bool camIsPosInFovAndVisibleRoom(RoomNum *rooms, struct coord *pos, f32 arg2)
RoomNum room;
bool hasdata = false;
struct drawslot *thisthing;
#ifdef AVOID_UB
static struct drawslot dslot;
#endif
struct screenbox box;
for (i = 0, room = rooms[i]; room != -1; i++, room = rooms[i]) {
@@ -637,5 +641,10 @@ bool camIsPosInFovAndVisibleRoom(RoomNum *rooms, struct coord *pos, f32 arg2)
return false;
}
#ifdef AVOID_UB
memcpy(&dslot.box, &box, sizeof(box));
return camIsPosInScreenBox(pos, arg2, &dslot);
#else
return camIsPosInScreenBox(pos, arg2, (struct drawslot *) &(((u8 *) &box)[-((uintptr_t) &(((struct drawslot *)0)->box))]));
#endif
}
+4
View File
@@ -329,7 +329,11 @@ void gfxReplaceGbiCommands(Gfx *startgdl, Gfx *endgdl, s32 type)
void gfxReplaceGbiCommandsRecursively(struct roomblock *block, s32 type)
{
#ifndef AVOID_UB
// Sometimes block is NULL when this is called.
// If UBSan is being used, this will crash in this instance.
if (block->type == ROOMBLOCKTYPE_PARENT);
#endif
while (true) {
if (!block) {
+21
View File
@@ -3413,8 +3413,14 @@ void menuClose(void)
void func0f0f8120(void)
{
#ifdef AVOID_UB
u32 mpindex = g_MpPlayerNum % MAX_PLAYERS;
struct menudialog *prev = g_Menus[mpindex].curdialog;
s32 i;
#else
struct menudialog *prev = g_Menus[g_MpPlayerNum].curdialog;
s32 i;
#endif
if (g_MenuData.unk66e > 0) {
for (i = g_MenuData.unk66e; i >= 0; i--) {
@@ -3422,11 +3428,22 @@ void func0f0f8120(void)
}
}
#ifdef AVOID_UB
mpindex = g_MpPlayerNum;
if (mpindex >= MAX_PLAYERS)
mpindex -= MAX_PLAYERS;
if (g_Menus[mpindex].curdialog == prev) {
while (g_Menus[mpindex].depth > 0) {
menuPopDialog();
}
}
#else
if (g_Menus[g_MpPlayerNum].curdialog == prev) {
while (g_Menus[g_MpPlayerNum].depth > 0) {
menuPopDialog();
}
}
#endif
}
void func0f0f820c(struct menudialogdef *dialogdef, s32 root)
@@ -4340,7 +4357,11 @@ void dialogTick(struct menudialog *dialog, struct menuinputs *inputs, u32 tickfl
}
// Apply default navigational behaviour if requested
#ifdef AVOID_UB
if (usedefaultbehaviour && (tickflags & MENUTICKFLAG_DIALOGISCURRENT) && !dialog->dimmed && g_Menus[g_MpPlayerNum].depth >= 1) {
#else
if (usedefaultbehaviour && (tickflags & MENUTICKFLAG_DIALOGISCURRENT) && !dialog->dimmed) {
#endif
struct menulayer *layer = &g_Menus[g_MpPlayerNum].layers[g_Menus[g_MpPlayerNum].depth - 1];
if (layer->numsiblings <= 1) {
+2 -2
View File
@@ -2736,8 +2736,8 @@ bool mp3dec000427d8(struct asistream *stream, u32 gr)
f32 *sp0c = stream->unk4664[0][0].unk00;
s32 i = 0;
if (stream->window_switching[gr][0] && stream->window_switching[gr][2] == 2) {
if (stream->window_switching[gr][4]) {
if (stream->window_switching[gr][0] && stream->block_type[gr][0] == 2) {
if (stream->mixed_block_flag[gr][0]) {
while (i++ < 36) {
*(sp10++) = *(sp0c++);
}