diff --git a/src/load_okt.cpp b/src/load_okt.cpp index 764ae320..21bf6db0 100644 --- a/src/load_okt.cpp +++ b/src/load_okt.cpp @@ -13,18 +13,20 @@ //#pragma warning(disable:4244) +#define MAGIC(a,b,c,d) (((a) << 24UL) | ((b) << 16UL) | ((c) << 8UL) | (d)) + +#pragma pack(1) typedef struct OKTFILEHEADER { DWORD okta; // "OKTA" DWORD song; // "SONG" DWORD cmod; // "CMOD" - DWORD fixed8; + DWORD cmodlen; BYTE chnsetup[8]; DWORD samp; // "SAMP" DWORD samplen; } OKTFILEHEADER; - typedef struct OKTSAMPLE { CHAR name[20]; @@ -36,20 +38,29 @@ typedef struct OKTSAMPLE BYTE pad2; BYTE pad3; } OKTSAMPLE; +#pragma pack() + +static DWORD readBE32(const BYTE *v) +{ + return (v[0] << 24UL) | (v[1] << 16UL) | (v[2] << 8UL) | v[3]; +} BOOL CSoundFile::ReadOKT(const BYTE *lpStream, DWORD dwMemLength) //--------------------------------------------------------------- { const OKTFILEHEADER *pfh = (OKTFILEHEADER *)lpStream; - DWORD dwMemPos = sizeof(OKTFILEHEADER); + DWORD dwMemPos = sizeof(OKTFILEHEADER), dwSize; UINT nsamples = 0, npatterns = 0, norders = 0; if ((!lpStream) || (dwMemLength < 1024)) return FALSE; - if ((pfh->okta != 0x41544B4F) || (pfh->song != 0x474E4F53) - || (pfh->cmod != 0x444F4D43) || (pfh->chnsetup[0]) || (pfh->chnsetup[2]) - || (pfh->chnsetup[4]) || (pfh->chnsetup[6]) || (pfh->fixed8 != 0x08000000) - || (pfh->samp != 0x504D4153)) return FALSE; + if ((bswapBE32(pfh->okta) != MAGIC('O','K','T','A')) + || (bswapBE32(pfh->song) != MAGIC('S','O','N','G')) + || (bswapBE32(pfh->cmod) != MAGIC('C','M','O','D')) + || (bswapBE32(pfh->cmodlen) != 8) + || (pfh->chnsetup[0]) || (pfh->chnsetup[2]) + || (pfh->chnsetup[4]) || (pfh->chnsetup[6]) + || (bswapBE32(pfh->samp) != MAGIC('S','A','M','P'))) return FALSE; m_nType = MOD_TYPE_OKT; m_nChannels = 4 + pfh->chnsetup[1] + pfh->chnsetup[3] + pfh->chnsetup[5] + pfh->chnsetup[7]; if (m_nChannels > MAX_CHANNELS) m_nChannels = MAX_CHANNELS; @@ -62,7 +73,7 @@ BOOL CSoundFile::ReadOKT(const BYTE *lpStream, DWORD dwMemLength) if (dwMemPos >= dwMemLength - sizeof(OKTSAMPLE)) return TRUE; if (smp < MAX_SAMPLES) { - OKTSAMPLE *psmp = (OKTSAMPLE *)(lpStream + dwMemPos); + const OKTSAMPLE *psmp = (const OKTSAMPLE *)(lpStream + dwMemPos); MODINSTRUMENT *pins = &Ins[smp]; memcpy(m_szNames[smp], psmp->name, 20); @@ -79,41 +90,51 @@ BOOL CSoundFile::ReadOKT(const BYTE *lpStream, DWORD dwMemLength) } // SPEE if (dwMemPos >= dwMemLength - 12) return TRUE; - if (*((DWORD *)(lpStream + dwMemPos)) == 0x45455053) + if (readBE32(lpStream + dwMemPos) == MAGIC('S','P','E','E')) { m_nDefaultSpeed = lpStream[dwMemPos+9]; - dwMemPos += bswapBE32(*((DWORD *)(lpStream + dwMemPos + 4))) + 8; + + dwSize = readBE32(lpStream + dwMemPos + 4); + if (dwSize > dwMemLength - 8 || dwMemPos > dwMemLength - dwSize - 8) return TRUE; + dwMemPos += dwSize + 8; } // SLEN if (dwMemPos + 10 > dwMemLength) return TRUE; - if (*((DWORD *)(lpStream + dwMemPos)) == 0x4E454C53) + if (readBE32(lpStream + dwMemPos) == MAGIC('S','L','E','N')) { - if (dwMemPos + 10 > dwMemLength) return TRUE; npatterns = lpStream[dwMemPos+9]; - dwMemPos += bswapBE32(*((DWORD *)(lpStream + dwMemPos + 4))) + 8; + + dwSize = readBE32(lpStream + dwMemPos + 4); + if (dwSize > dwMemLength - 8 || dwMemPos > dwMemLength - dwSize - 8) return TRUE; + dwMemPos += dwSize + 8; } // PLEN if (dwMemPos + 10 > dwMemLength) return TRUE; - if (*((DWORD *)(lpStream + dwMemPos)) == 0x4E454C50) + if (readBE32(lpStream + dwMemPos) == MAGIC('P','L','E','N')) { - if (dwMemPos + 10 > dwMemLength) return TRUE; norders = lpStream[dwMemPos+9]; - dwMemPos += bswapBE32(*((DWORD *)(lpStream + dwMemPos + 4))) + 8; + + dwSize = readBE32(lpStream + dwMemPos + 4); + if (dwSize > dwMemLength - 8 || dwMemPos > dwMemLength - dwSize - 8) return TRUE; + dwMemPos += dwSize + 8; } // PATT if (dwMemPos + 8 > dwMemLength) return TRUE; - if (*((DWORD *)(lpStream + dwMemPos)) == 0x54544150) + if (readBE32(lpStream + dwMemPos) == MAGIC('P','A','T','T')) { UINT orderlen = norders; if (orderlen >= MAX_ORDERS) orderlen = MAX_ORDERS-1; if (dwMemPos + 8 + orderlen > dwMemLength) return TRUE; for (UINT i=0; i1; j--) { if (Order[j-1]) break; Order[j-1] = 0xFF; } - dwMemPos += bswapBE32(*((DWORD *)(lpStream + dwMemPos + 4))) + 8; + + dwSize = readBE32(lpStream + dwMemPos + 4); + if (dwSize > dwMemLength - 8 || dwMemPos > dwMemLength - dwSize - 8) return TRUE; + dwMemPos += dwSize + 8; } // PBOD UINT npat = 0; - while ((dwMemPos < dwMemLength - 10) && (*((DWORD *)(lpStream + dwMemPos)) == 0x444F4250)) + while ((dwMemPos < dwMemLength - 10) && (readBE32(lpStream + dwMemPos) == MAGIC('P','B','O','D'))) { DWORD dwPos = dwMemPos + 10; UINT rows = lpStream[dwMemPos+9]; @@ -185,15 +206,21 @@ BOOL CSoundFile::ReadOKT(const BYTE *lpStream, DWORD dwMemLength) } } npat++; - dwMemPos += bswapBE32(*((DWORD *)(lpStream + dwMemPos + 4))) + 8; + + dwSize = readBE32(lpStream + dwMemPos + 4); + if (dwSize > dwMemLength - 8 || dwMemPos > dwMemLength - dwSize - 8) return TRUE; + dwMemPos += dwSize + 8; } // SBOD UINT nsmp = 1; - while ((dwMemPos < dwMemLength-10) && (*((DWORD *)(lpStream + dwMemPos)) == 0x444F4253)) + while ((dwMemPos < dwMemLength-10) && (readBE32(lpStream + dwMemPos) == MAGIC('S','B','O','D'))) { if (nsmp < MAX_SAMPLES) ReadSample(&Ins[nsmp], RS_PCM8S, (LPSTR)(lpStream+dwMemPos+8), dwMemLength-dwMemPos-8); - dwMemPos += bswapBE32(*((DWORD *)(lpStream + dwMemPos + 4))) + 8; nsmp++; + + dwSize = readBE32(lpStream + dwMemPos + 4); + if (dwSize > dwMemLength - 8 || dwMemPos > dwMemLength - dwSize - 8) return TRUE; + dwMemPos += dwSize + 8; } return TRUE; } diff --git a/src/load_s3m.cpp b/src/load_s3m.cpp index adcfb1f7..56f8f325 100644 --- a/src/load_s3m.cpp +++ b/src/load_s3m.cpp @@ -282,8 +282,6 @@ BOOL CSoundFile::ReadS3M(const BYTE *lpStream, DWORD dwMemLength) } if (psfh.panning_present == 252) { - if (dwMemPos + 32 > dwMemLength) return FALSE; - const BYTE *chnpan = lpStream+dwMemPos; if (dwMemPos > dwMemLength - 32) return FALSE; for (UINT i=0; i<32; i++) if (chnpan[i] & 0x20) diff --git a/src/load_ult.cpp b/src/load_ult.cpp index eddc9a43..91a732b9 100644 --- a/src/load_ult.cpp +++ b/src/load_ult.cpp @@ -155,16 +155,15 @@ BOOL CSoundFile::ReadUlt(const BYTE *lpStream, DWORD dwMemLength) UINT row = 0; while (row < 64) { - if (dwMemPos + 5 > dwMemLength) return TRUE; + if (dwMemPos > dwMemLength - 5) return TRUE; UINT rep = 1; UINT note = lpStream[dwMemPos++]; if (note == 0xFC) { - if (dwMemPos + 7 > dwMemLength) return TRUE; rep = lpStream[dwMemPos]; note = lpStream[dwMemPos+1]; dwMemPos += 2; - if (dwMemPos + 4 > dwMemLength) return TRUE; + if (dwMemPos > dwMemLength - 4) return TRUE; } UINT instr = lpStream[dwMemPos++];