From 2772786a7ef92e26f2d3f81e22e405ff805b3937 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 7 Apr 2010 02:02:53 +0000 Subject: [PATCH] - Added MUS header scan to mus2midi. - Fixed buffer overflow when reading a MUS song from a compressed file. SVN r2274 (trunk) --- src/mus2midi.cpp | 29 ++++++++++++++++++++--------- src/mus2midi.h | 4 ++-- src/sound/i_music.cpp | 4 ++-- src/sound/music_midi_timidity.cpp | 2 +- src/sound/music_mus_midiout.cpp | 9 +++++---- 5 files changed, 30 insertions(+), 18 deletions(-) diff --git a/src/mus2midi.cpp b/src/mus2midi.cpp index beef4ffa42..63e59e755a 100644 --- a/src/mus2midi.cpp +++ b/src/mus2midi.cpp @@ -53,7 +53,7 @@ static const BYTE StaticMIDIhead[] = 0, 255, 81, 3, 0x07, 0xa1, 0x20 }; -static const DWORD MUSMagic = MAKE_ID('M','U','S',0x1a); +extern int MUSHeaderSearch(const BYTE *head, int len); static const BYTE CtrlTranslate[15] = { @@ -110,23 +110,30 @@ static size_t WriteVarLen (TArray &file, int time) return ofs; } -bool ProduceMIDI (const BYTE *musBuf, TArray &outFile) +bool ProduceMIDI (const BYTE *musBuf, int len, TArray &outFile) { BYTE midStatus, midArgs, mid1, mid2; size_t mus_p, maxmus_p; BYTE event; int deltaTime; - const MUSHeader *musHead = (const MUSHeader *)musBuf; + const MUSHeader *musHead; BYTE status; BYTE chanUsed[16]; BYTE lastVel[16]; long trackLen; bool no_op; - // Do some validation of the MUS file - if (MUSMagic != musHead->Magic) + // Find the header + int offset = MUSHeaderSearch(musBuf, len); + + if (offset < 0 || offset + (int)sizeof(MUSHeader) >= len) return false; - + + musBuf += offset; + len -= offset; + musHead = (const MUSHeader *)musBuf; + + // Do some validation of the MUS file if (LittleShort(musHead->NumChans) > 15) return false; @@ -136,8 +143,12 @@ bool ProduceMIDI (const BYTE *musBuf, TArray &outFile) memcpy(&outFile[0], StaticMIDIhead, sizeof(StaticMIDIhead)); musBuf += LittleShort(musHead->SongStart); - maxmus_p = LittleShort(musHead->SongLen); mus_p = 0; + maxmus_p = LittleShort(musHead->SongLen); + if ((size_t)len - LittleShort(musHead->SongStart) < maxmus_p) + { + maxmus_p = len - LittleShort(musHead->SongStart); + } memset (lastVel, 100, 16); memset (chanUsed, 0, 16); @@ -287,10 +298,10 @@ bool ProduceMIDI (const BYTE *musBuf, TArray &outFile) return true; } -bool ProduceMIDI(const BYTE *musBuf, FILE *outFile) +bool ProduceMIDI(const BYTE *musBuf, int len, FILE *outFile) { TArray work; - if (ProduceMIDI(musBuf, work)) + if (ProduceMIDI(musBuf, len, work)) { return fwrite(&work[0], 1, work.Size(), outFile) == work.Size(); } diff --git a/src/mus2midi.h b/src/mus2midi.h index 6780bdf47c..6dc75dc039 100644 --- a/src/mus2midi.h +++ b/src/mus2midi.h @@ -75,7 +75,7 @@ typedef struct // WORD UsedInstruments[NumInstruments]; } MUSHeader; -bool ProduceMIDI (const BYTE *musBuf, TArray &outFile); -bool ProduceMIDI (const BYTE *musBuf, FILE *outFile); +bool ProduceMIDI (const BYTE *musBuf, int len, TArray &outFile); +bool ProduceMIDI (const BYTE *musBuf, int len, FILE *outFile); #endif //__MUS2MIDI_H__ diff --git a/src/sound/i_music.cpp b/src/sound/i_music.cpp index 6e996bbad6..e25d4b5d62 100644 --- a/src/sound/i_music.cpp +++ b/src/sound/i_music.cpp @@ -441,7 +441,7 @@ MusInfo *I_RegisterSong (const char *filename, BYTE *musiccache, int offset, int if (file == NULL) { - midi_made = ProduceMIDI((BYTE *)musiccache, midi); + midi_made = ProduceMIDI((BYTE *)musiccache, len, midi); } else { @@ -449,7 +449,7 @@ MusInfo *I_RegisterSong (const char *filename, BYTE *musiccache, int offset, int size_t did_read = fread(mus, 1, len, file); if (did_read == (size_t)len) { - midi_made = ProduceMIDI(mus, midi); + midi_made = ProduceMIDI(mus, len, midi); } fseek(file, -(long)did_read, SEEK_CUR); delete[] mus; diff --git a/src/sound/music_midi_timidity.cpp b/src/sound/music_midi_timidity.cpp index 15e69c8a63..ea725d0da0 100644 --- a/src/sound/music_midi_timidity.cpp +++ b/src/sound/music_midi_timidity.cpp @@ -227,7 +227,7 @@ TimiditySong::TimiditySong (FILE *file, BYTE *musiccache, int len) } else { - success = ProduceMIDI (buf, f); + success = ProduceMIDI (buf, len, f); } fclose (f); if (file != NULL) diff --git a/src/sound/music_mus_midiout.cpp b/src/sound/music_mus_midiout.cpp index ef6cba16d0..68558bdadb 100644 --- a/src/sound/music_mus_midiout.cpp +++ b/src/sound/music_mus_midiout.cpp @@ -106,9 +106,9 @@ MUSSong2::MUSSong2 (FILE *file, BYTE *musiccache, int len, EMIDIDevice type) if (file == NULL) { - memcpy(front, musiccache, len); + memcpy(front, musiccache, sizeof(front)); } - else if (fread(front, 1, 32, file) != 32) + else if (fread(front, 1, sizeof(front), file) != sizeof(front)) { return; } @@ -136,8 +136,8 @@ MUSSong2::MUSSong2 (FILE *file, BYTE *musiccache, int len, EMIDIDevice type) } else { - memcpy(MusHeader, front + start, 32 - start); - if (fread((BYTE *)MusHeader + 32 - start, 1, len - (32 - start), file) != (size_t)(len - (32 - start))) + memcpy(MusHeader, front + start, sizeof(front) - start); + if (fread((BYTE *)MusHeader + sizeof(front) - start, 1, len - (sizeof(front) - start), file) != (size_t)(len - (32 - start))) { return; } @@ -148,6 +148,7 @@ MUSSong2::MUSSong2 (FILE *file, BYTE *musiccache, int len, EMIDIDevice type) { return; } + MusBuffer = (BYTE *)MusHeader + LittleShort(MusHeader->SongStart); MaxMusP = MIN(LittleShort(MusHeader->SongLen), len - LittleShort(MusHeader->SongStart)); Division = 140;