mirror of
https://github.com/HarbourMasters/Shipwright
synced 2026-08-12 12:18:32 -04:00
fix: seqLoadStatus OOB reads/writes for custom SAF sequences (#6917)
Custom SAF sequence IDs can exceed sequenceMapSize, causing out-of-bounds reads/writes on the seqLoadStatus byte array (sized exactly sequenceMapSize). This is the direct cause of intermittent battle music failure with BGM packs (issue #5706): on the second encounter, AudioLoad_SyncLoadSeq reads a garbage value from heap memory past seqLoadStatus[] and may find 1 (loading in progress), causing it to return NULL early — the sequence player is never initialized and no battle music plays. Symmetric fix to the fontLoadStatus guards in PR #6916: - AudioLoad_IsSeqLoadComplete: return true for OOB seqIds (custom SAF sequences are resource-manager-backed, not in the async-load status table) - AudioLoad_SetSeqLoadStatus: skip update for seqId >= sequenceMapSize - AudioLoad_SyncLoadSeq: skip the in-progress check for OOB seqIds Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -315,13 +315,19 @@ s32 AudioLoad_IsFontLoadComplete(s32 fontId) {
|
||||
s32 AudioLoad_IsSeqLoadComplete(s32 seqId) {
|
||||
if (seqId == 0xFF) {
|
||||
return true;
|
||||
} else if (gAudioContext.seqLoadStatus[seqId] >= 2) {
|
||||
return true;
|
||||
} else if (gAudioContext.seqLoadStatus[AudioLoad_GetRealTableIndex(SEQUENCE_TABLE, seqId)] >= 2) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
if ((size_t)seqId >= sequenceMapSize) {
|
||||
// Custom SAF sequence whose seqId exceeds the status table — not async-loading, treat as ready.
|
||||
return true;
|
||||
}
|
||||
if (gAudioContext.seqLoadStatus[seqId] >= 2) {
|
||||
return true;
|
||||
}
|
||||
s32 realId = (s32)AudioLoad_GetRealTableIndex(SEQUENCE_TABLE, seqId);
|
||||
if ((size_t)realId < sequenceMapSize && gAudioContext.seqLoadStatus[realId] >= 2) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
s32 AudioLoad_IsSampleLoadComplete(s32 sampleBankId) {
|
||||
@@ -343,7 +349,7 @@ void AudioLoad_SetFontLoadStatus(s32 fontId, s32 status) {
|
||||
}
|
||||
|
||||
void AudioLoad_SetSeqLoadStatus(s32 seqId, s32 status) {
|
||||
if ((seqId != 0xFF) && (gAudioContext.seqLoadStatus[seqId] != 5)) {
|
||||
if ((seqId != 0xFF) && ((size_t)seqId < sequenceMapSize) && (gAudioContext.seqLoadStatus[seqId] != 5)) {
|
||||
gAudioContext.seqLoadStatus[seqId] = status;
|
||||
}
|
||||
}
|
||||
@@ -637,7 +643,7 @@ u8* AudioLoad_SyncLoadSeq(s32 seqId) {
|
||||
s32 pad;
|
||||
s32 didAllocate;
|
||||
|
||||
if (gAudioContext.seqLoadStatus[AudioLoad_GetRealTableIndex(SEQUENCE_TABLE, seqId)] == 1) {
|
||||
if ((size_t)seqId < sequenceMapSize && gAudioContext.seqLoadStatus[seqId] == 1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user