- Added MUS header scan to mus2midi.

- Fixed buffer overflow when reading a MUS song from a compressed file.

SVN r2274 (trunk)
This commit is contained in:
Randy Heit 2010-04-07 02:02:53 +00:00
parent 114412d5a2
commit 2772786a7e
5 changed files with 30 additions and 18 deletions

View file

@ -53,7 +53,7 @@ static const BYTE StaticMIDIhead[] =
0, 255, 81, 3, 0x07, 0xa1, 0x20 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] = static const BYTE CtrlTranslate[15] =
{ {
@ -110,23 +110,30 @@ static size_t WriteVarLen (TArray<BYTE> &file, int time)
return ofs; return ofs;
} }
bool ProduceMIDI (const BYTE *musBuf, TArray<BYTE> &outFile) bool ProduceMIDI (const BYTE *musBuf, int len, TArray<BYTE> &outFile)
{ {
BYTE midStatus, midArgs, mid1, mid2; BYTE midStatus, midArgs, mid1, mid2;
size_t mus_p, maxmus_p; size_t mus_p, maxmus_p;
BYTE event; BYTE event;
int deltaTime; int deltaTime;
const MUSHeader *musHead = (const MUSHeader *)musBuf; const MUSHeader *musHead;
BYTE status; BYTE status;
BYTE chanUsed[16]; BYTE chanUsed[16];
BYTE lastVel[16]; BYTE lastVel[16];
long trackLen; long trackLen;
bool no_op; bool no_op;
// Do some validation of the MUS file // Find the header
if (MUSMagic != musHead->Magic) int offset = MUSHeaderSearch(musBuf, len);
if (offset < 0 || offset + (int)sizeof(MUSHeader) >= len)
return false; return false;
musBuf += offset;
len -= offset;
musHead = (const MUSHeader *)musBuf;
// Do some validation of the MUS file
if (LittleShort(musHead->NumChans) > 15) if (LittleShort(musHead->NumChans) > 15)
return false; return false;
@ -136,8 +143,12 @@ bool ProduceMIDI (const BYTE *musBuf, TArray<BYTE> &outFile)
memcpy(&outFile[0], StaticMIDIhead, sizeof(StaticMIDIhead)); memcpy(&outFile[0], StaticMIDIhead, sizeof(StaticMIDIhead));
musBuf += LittleShort(musHead->SongStart); musBuf += LittleShort(musHead->SongStart);
maxmus_p = LittleShort(musHead->SongLen);
mus_p = 0; 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 (lastVel, 100, 16);
memset (chanUsed, 0, 16); memset (chanUsed, 0, 16);
@ -287,10 +298,10 @@ bool ProduceMIDI (const BYTE *musBuf, TArray<BYTE> &outFile)
return true; return true;
} }
bool ProduceMIDI(const BYTE *musBuf, FILE *outFile) bool ProduceMIDI(const BYTE *musBuf, int len, FILE *outFile)
{ {
TArray<BYTE> work; TArray<BYTE> work;
if (ProduceMIDI(musBuf, work)) if (ProduceMIDI(musBuf, len, work))
{ {
return fwrite(&work[0], 1, work.Size(), outFile) == work.Size(); return fwrite(&work[0], 1, work.Size(), outFile) == work.Size();
} }

View file

@ -75,7 +75,7 @@ typedef struct
// WORD UsedInstruments[NumInstruments]; // WORD UsedInstruments[NumInstruments];
} MUSHeader; } MUSHeader;
bool ProduceMIDI (const BYTE *musBuf, TArray<BYTE> &outFile); bool ProduceMIDI (const BYTE *musBuf, int len, TArray<BYTE> &outFile);
bool ProduceMIDI (const BYTE *musBuf, FILE *outFile); bool ProduceMIDI (const BYTE *musBuf, int len, FILE *outFile);
#endif //__MUS2MIDI_H__ #endif //__MUS2MIDI_H__

View file

@ -441,7 +441,7 @@ MusInfo *I_RegisterSong (const char *filename, BYTE *musiccache, int offset, int
if (file == NULL) if (file == NULL)
{ {
midi_made = ProduceMIDI((BYTE *)musiccache, midi); midi_made = ProduceMIDI((BYTE *)musiccache, len, midi);
} }
else 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); size_t did_read = fread(mus, 1, len, file);
if (did_read == (size_t)len) if (did_read == (size_t)len)
{ {
midi_made = ProduceMIDI(mus, midi); midi_made = ProduceMIDI(mus, len, midi);
} }
fseek(file, -(long)did_read, SEEK_CUR); fseek(file, -(long)did_read, SEEK_CUR);
delete[] mus; delete[] mus;

View file

@ -227,7 +227,7 @@ TimiditySong::TimiditySong (FILE *file, BYTE *musiccache, int len)
} }
else else
{ {
success = ProduceMIDI (buf, f); success = ProduceMIDI (buf, len, f);
} }
fclose (f); fclose (f);
if (file != NULL) if (file != NULL)

View file

@ -106,9 +106,9 @@ MUSSong2::MUSSong2 (FILE *file, BYTE *musiccache, int len, EMIDIDevice type)
if (file == NULL) 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; return;
} }
@ -136,8 +136,8 @@ MUSSong2::MUSSong2 (FILE *file, BYTE *musiccache, int len, EMIDIDevice type)
} }
else else
{ {
memcpy(MusHeader, front + start, 32 - start); memcpy(MusHeader, front + start, sizeof(front) - start);
if (fread((BYTE *)MusHeader + 32 - start, 1, len - (32 - start), file) != (size_t)(len - (32 - start))) if (fread((BYTE *)MusHeader + sizeof(front) - start, 1, len - (sizeof(front) - start), file) != (size_t)(len - (32 - start)))
{ {
return; return;
} }
@ -148,6 +148,7 @@ MUSSong2::MUSSong2 (FILE *file, BYTE *musiccache, int len, EMIDIDevice type)
{ {
return; return;
} }
MusBuffer = (BYTE *)MusHeader + LittleShort(MusHeader->SongStart); MusBuffer = (BYTE *)MusHeader + LittleShort(MusHeader->SongStart);
MaxMusP = MIN<int>(LittleShort(MusHeader->SongLen), len - LittleShort(MusHeader->SongStart)); MaxMusP = MIN<int>(LittleShort(MusHeader->SongLen), len - LittleShort(MusHeader->SongStart));
Division = 140; Division = 140;