dependencies/SDL_sound/libmodplug/load_xm.c in gosu-1.3.0 vs dependencies/SDL_sound/libmodplug/load_xm.c in gosu-1.4.0
- old
+ new
@@ -8,11 +8,11 @@
#include "libmodplug.h"
////////////////////////////////////////////////////////
// FastTracker II XM file support
-#ifdef MSC_VER
+#ifdef _MSC_VER
#pragma warning(disable:4244)
#endif
#pragma pack(1)
typedef struct tagXMFILEHEADER
@@ -27,21 +27,19 @@
WORD speed;
WORD tempo;
BYTE order[256];
} XMFILEHEADER;
-
typedef struct tagXMINSTRUMENTHEADER
{
DWORD size;
CHAR name[22];
BYTE type;
BYTE samples;
BYTE samplesh;
} XMINSTRUMENTHEADER;
-
typedef struct tagXMSAMPLEHEADER
{
DWORD shsize;
BYTE snum[96];
WORD venv[24];
@@ -68,11 +66,10 @@
BYTE res;
char name[22];
} XMSAMPLESTRUCT;
#pragma pack()
-
BOOL CSoundFile_ReadXM(CSoundFile *_this, const BYTE *lpStream, DWORD dwMemLength)
//--------------------------------------------------------------
{
XMSAMPLEHEADER xmsh;
XMSAMPLESTRUCT xmss;
@@ -86,18 +83,20 @@
UINT unused_samples;
XMFILEHEADER xmhead;
_this->m_nChannels = 0;
if ((!lpStream) || (dwMemLength < 0x200)) return FALSE;
- if (SDL_strncasecmp((LPCSTR)lpStream, "Extended Module", 15)) return FALSE;
+ if (SDL_strncmp((LPCSTR)lpStream, "Extended Module:", 16)) return FALSE;
SDL_memcpy(&xmhead, lpStream+60, sizeof (xmhead));
dwHdrSize = bswapLE32(xmhead.size);
norders = bswapLE16(xmhead.norder);
- if ((!norders) || (norders > MAX_ORDERS)) return FALSE;
restartpos = bswapLE16(xmhead.restartpos);
channels = bswapLE16(xmhead.channels);
+
+ if ((!dwHdrSize) || dwHdrSize > dwMemLength - 60) return FALSE;
+ if ((!norders) || (norders > MAX_ORDERS)) return FALSE;
if ((!channels) || (channels > 64)) return FALSE;
_this->m_nType = MOD_TYPE_XM;
_this->m_nMinPeriod = 27;
_this->m_nMaxPeriod = 54784;
_this->m_nChannels = channels;
@@ -160,10 +159,11 @@
{
if (dwMemPos + 4 >= dwMemLength) break;
dwMemPos++;
dwSize = bswapLE32(*((DWORD *)(lpStream+dwMemPos)));
}
+ if (dwMemPos + 9 > dwMemLength) return TRUE;
rows = bswapLE16(*((WORD *)(lpStream+dwMemPos+5)));
if ((!rows) || (rows > 256)) rows = 64;
packsize = bswapLE16(*((WORD *)(lpStream+dwMemPos+7)));
if (dwMemPos + dwSize + 4 > dwMemLength) return TRUE;
dwMemPos += dwSize;
@@ -186,17 +186,18 @@
{
BYTE b = src[j++];
UINT vol = 0;
if (b & 0x80)
{
- if (b & 1) p->note = src[j++];
- if (b & 2) p->instr = src[j++];
- if (b & 4) vol = src[j++];
- if (b & 8) p->command = src[j++];
- if (b & 16) p->param = src[j++];
+ if ((b & 1) && j < packsize) p->note = src[j++];
+ if ((b & 2) && j < packsize) p->instr = src[j++];
+ if ((b & 4) && j < packsize) vol = src[j++];
+ if ((b & 8) && j < packsize) p->command = src[j++];
+ if ((b & 16) && j < packsize) p->param = src[j++];
} else
{
+ if (j + 5 > packsize) break;
p->note = b;
p->instr = src[j++];
vol = src[j++];
p->command = src[j++];
p->param = src[j++];
@@ -274,31 +275,32 @@
XMINSTRUMENTHEADER *pih;
BYTE flags[32];
DWORD samplesize[32];
UINT samplemap[32];
WORD nsamples;
+ DWORD pihlen;
if (dwMemPos + sizeof(XMINSTRUMENTHEADER) >= dwMemLength) return TRUE;
pih = (XMINSTRUMENTHEADER *)(lpStream+dwMemPos);
- if (dwMemPos + bswapLE32(pih->size) > dwMemLength) return TRUE;
- if ((_this->Headers[iIns] = (INSTRUMENTHEADER *) SDL_malloc(sizeof (INSTRUMENTHEADER))) == NULL) continue;
- SDL_memset(_this->Headers[iIns], 0, sizeof(INSTRUMENTHEADER));
+ pihlen = bswapLE32(pih->size);
+ if (pihlen >= dwMemLength || dwMemPos > dwMemLength - pihlen) return TRUE;
+ if ((_this->Headers[iIns] = (INSTRUMENTHEADER *) SDL_calloc(1, sizeof(INSTRUMENTHEADER))) == NULL) continue;
if ((nsamples = pih->samples) > 0)
{
- if (dwMemPos + sizeof(XMSAMPLEHEADER) > dwMemLength) return TRUE;
+ if (dwMemPos + sizeof(XMINSTRUMENTHEADER) + sizeof(XMSAMPLEHEADER) > dwMemLength) return TRUE;
SDL_memcpy(&xmsh, lpStream+dwMemPos+sizeof(XMINSTRUMENTHEADER), sizeof(XMSAMPLEHEADER));
xmsh.shsize = bswapLE32(xmsh.shsize);
for (int i = 0; i < 24; ++i) {
xmsh.venv[i] = bswapLE16(xmsh.venv[i]);
xmsh.penv[i] = bswapLE16(xmsh.penv[i]);
}
xmsh.volfade = bswapLE16(xmsh.volfade);
xmsh.res = bswapLE16(xmsh.res);
- dwMemPos += bswapLE32(pih->size);
+ dwMemPos += pihlen;
} else
{
- if (bswapLE32(pih->size)) dwMemPos += bswapLE32(pih->size);
+ if (pihlen) dwMemPos += pihlen;
else dwMemPos += sizeof(XMINSTRUMENTHEADER);
continue;
}
SDL_memset(samplemap, 0, sizeof(samplemap));
if (nsamples > 32) return TRUE;
@@ -429,11 +431,11 @@
}
// Reading samples
for (UINT ins=0; ins<nsamples; ins++)
{
if ((dwMemPos + sizeof(xmss) > dwMemLength)
- || (dwMemPos + xmsh.shsize > dwMemLength)) return TRUE;
+ || (xmsh.shsize >= dwMemLength) || (dwMemPos > dwMemLength - xmsh.shsize)) return TRUE;
SDL_memcpy(&xmss, lpStream+dwMemPos, sizeof(xmss));
xmss.samplen = bswapLE32(xmss.samplen);
xmss.loopstart = bswapLE32(xmss.loopstart);
xmss.looplen = bswapLE32(xmss.looplen);
dwMemPos += xmsh.shsize;
@@ -510,10 +512,11 @@
// Read midi config: "MIDI"
if ((dwMemPos + 8 < dwMemLength) && (bswapLE32(*((DWORD *)(lpStream+dwMemPos))) == 0x4944494D))
{
UINT len = *((DWORD *)(lpStream+dwMemPos+4));
dwMemPos += 8;
+ if (len >= dwMemLength || dwMemPos > dwMemLength - len) return TRUE;
if (len == sizeof(MODMIDICFG))
{
SDL_memcpy(&_this->m_MidiCfg, lpStream+dwMemPos, len);
_this->m_dwSongFlags |= SONG_EMBEDMIDICFG;
}
@@ -521,11 +524,12 @@
// Read pattern names: "PNAM"
if ((dwMemPos + 8 < dwMemLength) && (bswapLE32(*((DWORD *)(lpStream+dwMemPos))) == 0x4d414e50))
{
UINT len = *((DWORD *)(lpStream+dwMemPos+4));
dwMemPos += 8;
- if ((dwMemPos + len <= dwMemLength) && (len <= MAX_PATTERNS*MAX_PATTERNNAME) && (len >= MAX_PATTERNNAME))
+ if (len >= dwMemLength || dwMemPos > dwMemLength - len) return TRUE;
+ if ((len <= MAX_PATTERNS*MAX_PATTERNNAME) && (len >= MAX_PATTERNNAME))
{
_this->m_lpszPatternNames = (char *) SDL_malloc(len);
if (_this->m_lpszPatternNames)
{
_this->m_nPatternNames = len / MAX_PATTERNNAME;
@@ -537,11 +541,12 @@
// Read channel names: "CNAM"
if ((dwMemPos + 8 < dwMemLength) && (bswapLE32(*((DWORD *)(lpStream+dwMemPos))) == 0x4d414e43))
{
UINT len = *((DWORD *)(lpStream+dwMemPos+4));
dwMemPos += 8;
- if ((dwMemPos + len <= dwMemLength) && (len <= MAX_BASECHANNELS*MAX_CHANNELNAME))
+ if (len >= dwMemLength || dwMemPos > dwMemLength - len) return TRUE;
+ if (len <= MAX_BASECHANNELS*MAX_CHANNELNAME)
{
dwMemPos += len;
}
}
// Read mix plugins information
@@ -549,6 +554,5 @@
{
dwMemPos += CSoundFile_LoadMixPlugins(_this, lpStream+dwMemPos, dwMemLength-dwMemPos);
}
return TRUE;
}
-