Skip to content

✨Mark bugs that involve genuine undefined behavior as UBFix#2328

Open
AZero13 wants to merge 1 commit into
pret:masterfrom
AZero13:out-of-bounds
Open

✨Mark bugs that involve genuine undefined behavior as UBFix#2328
AZero13 wants to merge 1 commit into
pret:masterfrom
AZero13:out-of-bounds

Conversation

@AZero13

@AZero13 AZero13 commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

The objEvent->localId != OBJ_EVENT_ID_CAMERA counts because this results in a null dereference, which is fine for vanilla I guess, but still wrong.

@mrgriffin mrgriffin left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure why there's a distinction between BUGFIX and UBFIX, but assuming it's for a good reason* I've pointed out some cases where I'm not sure what the UB is.

* ig it's for people that want to compile a ROM which works almost exactly the same as vanilla, but without invoking any UB? If that's the case, then the src/battle_gfx_sfx_util.c/src/trainer_pokemon_sprites.c ones wouldn't qualify. Maybe it's "people want to compile a ROM that's altered but can't invoke any UB without them violating a reasonable precondition", "reasonable" because "you can't have non-transparent pixels in the first tile's top row" is obviously not reasonable.

Comment thread src/battle_ai_script_commands.c Outdated
s32 i;
s32 j;
#ifndef BUGFIX
#ifndef UBFIX

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why's this one UB?

Comment thread src/event_object_movement.c Outdated
{gObjectEventPal_RubySapphireBrendan, OBJ_EVENT_PAL_TAG_RS_BRENDAN},
{gObjectEventPal_RubySapphireMay, OBJ_EVENT_PAL_TAG_RS_MAY},
#ifdef BUGFIX
#ifdef UBFIX

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

idk if this is really a fix for UB. Yes, it's UB if you ask for a tag that isn't in this list, but that's a precondition of the code; if "can invoke UB when you violate a precondition" is the bar for what's UB or not then every function that dereferences a pointer without a NULL check should grow UBFIX that checks for NULL and that's obviously silly.

Comment thread src/event_object_movement.c Outdated
u32 flags;

#ifdef BUGFIX
#ifdef UBFIX

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't looked into it, but why's it UB for the camera to trigger ground effects?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if the check objEvent->localId != OBJ_EVENT_ID_CAMERA is missing, the game will attempt to run the ground effects logic on the camera sprite

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

During the OAM update/rendering loop, the engine checks sprite->subspriteTableNum and attempts to read from sprite->subspriteTables[4].

Because subspriteTables is NULL, this compiles to an offset reference of NULL + 4 * sizeof(void *), trying to read from memory address 0x00000010.

@mrgriffin mrgriffin Jun 21, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

afaict the only call to AddSubspritesToOamBuffer is on the else of if (!sprite->subspriteTables || sprite->subspriteMode == SUBSPRITES_OFF)? (i.e. only entered if subspriteTables != NULL && sprite->subspriteMode != SUBSPRITES_OFF)

@ketsuban

Copy link
Copy Markdown
Contributor

I'm not sure why there's a distinction between BUGFIX and UBFIX

I thought the goal was to make something like the PC port easier to do by providing a compile-time flag to enable null-pointer checks Gamefreak didn't do because dereferencing a null pointer just reads the last instruction read from the firmware, and that happens not to crash the game in those instances in the vanilla game.

@AZero13

AZero13 commented Jun 21, 2026

Copy link
Copy Markdown
Contributor Author

Addressed!

@AZero13
AZero13 requested a review from mrgriffin June 21, 2026 13:20
@AZero13
AZero13 force-pushed the out-of-bounds branch 2 times, most recently from 55611e5 to 20a1d8e Compare June 21, 2026 13:21
@AZero13 AZero13 changed the title Mark bugs that involve genuine undefined behavior as UBFix ✨Mark bugs that involve genuine undefined behavior as UBFix Jul 8, 2026
@AZero13

AZero13 commented Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants