@@ -87,11 +87,12 @@ BOOL CSoundFile::ReadDMF(const BYTE *lpStream, DWORD dwMemLength)
87
87
// ---------------------------------------------------------------
88
88
{
89
89
const DMFHEADER *pfh = (DMFHEADER *)lpStream;
90
- DMFINFO *psi;
91
- DMFSEQU *sequ;
90
+ const DMFINFO *psi;
91
+ const DMFPATT *patt;
92
+ const DMFSEQU *sequ;
92
93
DWORD dwMemPos;
93
94
BYTE infobyte[32 ];
94
- BYTE smplflags[MAX_SAMPLES], hasSMPI = 0 ;
95
+ BYTE smplflags[MAX_SAMPLES], hasSMPI = 0 , hasSMPD = 0 ;
95
96
96
97
if ((!lpStream) || (dwMemLength < 1024 )) return FALSE ;
97
98
if ((pfh->id != 0x464d4444 ) || (!pfh->version ) || (pfh->version & 0xF0 )) return FALSE ;
@@ -115,7 +116,7 @@ BOOL CSoundFile::ReadDMF(const BYTE *lpStream, DWORD dwMemLength)
115
116
case 0x47534d43 :
116
117
psi = (DMFINFO *)(lpStream+dwMemPos);
117
118
if (id == 0x47534d43 ) dwMemPos++;
118
- if ((psi->infosize > dwMemLength) || (psi-> infosize + dwMemPos + 8 > dwMemLength)) goto dmfexit;
119
+ if ((psi->infosize > dwMemLength) || (dwMemPos + 8 > dwMemLength - psi-> infosize )) goto dmfexit;
119
120
if ((psi->infosize >= 8 ) && (!m_lpszSongComments))
120
121
{
121
122
m_lpszSongComments = new char [psi->infosize ]; // changed from CHAR
@@ -138,9 +139,10 @@ BOOL CSoundFile::ReadDMF(const BYTE *lpStream, DWORD dwMemLength)
138
139
// "SEQU"
139
140
case 0x55514553 :
140
141
sequ = (DMFSEQU *)(lpStream+dwMemPos);
141
- if ((sequ->seqsize >= dwMemLength) || (dwMemPos + sequ->seqsize + 12 > dwMemLength)) goto dmfexit;
142
+ if ((sequ->seqsize >= dwMemLength) || (dwMemPos + 8 > dwMemLength - sequ->seqsize )) goto dmfexit;
143
+ if (sequ->seqsize >= 4 )
142
144
{
143
- UINT nseq = sequ->seqsize >> 1 ;
145
+ UINT nseq = ( sequ->seqsize - 4 ) >> 1 ;
144
146
if (nseq >= MAX_ORDERS-1 ) nseq = MAX_ORDERS-1 ;
145
147
if (sequ->loopstart < nseq) m_nRestartPos = sequ->loopstart ;
146
148
for (UINT i=0 ; i<nseq; i++) Order[i] = (BYTE)sequ->sequ [i];
@@ -150,12 +152,12 @@ BOOL CSoundFile::ReadDMF(const BYTE *lpStream, DWORD dwMemLength)
150
152
151
153
// "PATT"
152
154
case 0x54544150 :
153
- if (!m_nChannels)
155
+ patt = (DMFPATT *)(lpStream+dwMemPos);
156
+ if ((patt->patsize >= dwMemLength) || (dwMemPos + 8 > dwMemLength - patt->patsize )) goto dmfexit;
157
+ if (patt->patsize >= 4 && !m_nChannels)
154
158
{
155
- DMFPATT *patt = (DMFPATT *)(lpStream+dwMemPos);
156
159
UINT numpat;
157
160
DWORD dwPos = dwMemPos + 11 ;
158
- if ((patt->patsize >= dwMemLength) || (dwMemPos + patt->patsize + 8 > dwMemLength)) goto dmfexit;
159
161
numpat = patt->numpat ;
160
162
if (numpat > MAX_PATTERNS) numpat = MAX_PATTERNS;
161
163
m_nChannels = patt->tracks ;
@@ -164,7 +166,8 @@ BOOL CSoundFile::ReadDMF(const BYTE *lpStream, DWORD dwMemLength)
164
166
if (m_nChannels < 4 ) m_nChannels = 4 ;
165
167
for (UINT npat=0 ; npat<numpat; npat++)
166
168
{
167
- DMFTRACK *pt = (DMFTRACK *)(lpStream+dwPos);
169
+ const DMFTRACK *pt = (DMFTRACK *)(lpStream+dwPos);
170
+ if (dwPos + 8 >= dwMemLength) break ;
168
171
#ifdef DMFLOG
169
172
Log (" Pattern #%d: %d tracks, %d rows\n " , npat, pt->tracks , pt->ticks );
170
173
#endif
@@ -174,7 +177,7 @@ BOOL CSoundFile::ReadDMF(const BYTE *lpStream, DWORD dwMemLength)
174
177
if (ticks > 256 ) ticks = 256 ;
175
178
if (ticks < 16 ) ticks = 16 ;
176
179
dwPos += 8 ;
177
- if ((pt->jmpsize >= dwMemLength) || (dwPos + pt-> jmpsize + 4 >= dwMemLength)) break ;
180
+ if ((pt->jmpsize >= dwMemLength) || (dwPos + 4 > dwMemLength - pt-> jmpsize )) break ;
178
181
PatternSize[npat] = (WORD)ticks;
179
182
MODCOMMAND *m = AllocatePattern (PatternSize[npat], m_nChannels);
180
183
if (!m) goto dmfexit;
@@ -193,6 +196,7 @@ BOOL CSoundFile::ReadDMF(const BYTE *lpStream, DWORD dwMemLength)
193
196
// Parse track global effects
194
197
if (!glbinfobyte)
195
198
{
199
+ if (d+1 > dwPos) break ;
196
200
BYTE info = lpStream[d++];
197
201
BYTE infoval = 0 ;
198
202
if ((info & 0x80 ) && (d < dwPos)) glbinfobyte = lpStream[d++];
@@ -214,30 +218,40 @@ BOOL CSoundFile::ReadDMF(const BYTE *lpStream, DWORD dwMemLength)
214
218
// Parse channels
215
219
for (UINT i=0 ; i<tracks; i++) if (!infobyte[i])
216
220
{
221
+ if (d+1 > dwPos) break ;
217
222
MODCOMMAND cmd = {0 ,0 ,0 ,0 ,0 ,0 };
218
223
BYTE info = lpStream[d++];
219
- if (info & 0x80 ) infobyte[i] = lpStream[d++];
224
+ if (info & 0x80 )
225
+ {
226
+ if (d+1 > dwPos) break ;
227
+ infobyte[i] = lpStream[d++];
228
+ }
220
229
// Instrument
221
230
if (info & 0x40 )
222
231
{
232
+ if (d+1 > dwPos) break ;
223
233
cmd.instr = lpStream[d++];
224
234
}
225
235
// Note
226
236
if (info & 0x20 )
227
237
{
238
+ if (d+1 > dwPos) break ;
228
239
cmd.note = lpStream[d++];
229
240
if ((cmd.note ) && (cmd.note < 0xfe )) cmd.note &= 0x7f ;
230
241
if ((cmd.note ) && (cmd.note < 128 )) cmd.note += 24 ;
231
242
}
232
243
// Volume
233
244
if (info & 0x10 )
234
245
{
246
+ if (d+1 > dwPos) break ;
235
247
cmd.volcmd = VOLCMD_VOLUME;
236
248
cmd.vol = (lpStream[d++]+3 )>>2 ;
237
249
}
238
250
// Effect 1
239
251
if (info & 0x08 )
240
252
{
253
+ if (d+2 > dwPos) break ;
254
+
241
255
BYTE efx = lpStream[d++];
242
256
BYTE eval = lpStream[d++];
243
257
switch (efx)
@@ -259,6 +273,8 @@ BOOL CSoundFile::ReadDMF(const BYTE *lpStream, DWORD dwMemLength)
259
273
// Effect 2
260
274
if (info & 0x04 )
261
275
{
276
+ if (d+2 > dwPos) break ;
277
+
262
278
BYTE efx = lpStream[d++];
263
279
BYTE eval = lpStream[d++];
264
280
switch (efx)
@@ -289,6 +305,8 @@ BOOL CSoundFile::ReadDMF(const BYTE *lpStream, DWORD dwMemLength)
289
305
// Effect 3
290
306
if (info & 0x02 )
291
307
{
308
+ if (d+2 > dwPos) break ;
309
+
292
310
BYTE efx = lpStream[d++];
293
311
BYTE eval = lpStream[d++];
294
312
switch (efx)
@@ -372,22 +390,24 @@ BOOL CSoundFile::ReadDMF(const BYTE *lpStream, DWORD dwMemLength)
372
390
#endif
373
391
if (dwPos + 8 >= dwMemLength) break ;
374
392
}
375
- dwMemPos += patt->patsize + 8 ;
376
393
}
394
+ dwMemPos += patt->patsize + 8 ;
377
395
break ;
378
396
379
397
// "SMPI": Sample Info
380
398
case 0x49504d53 :
381
399
{
382
400
hasSMPI = 1 ;
383
- DMFSMPI *pds = (DMFSMPI *)(lpStream+dwMemPos);
384
- if (pds->size <= dwMemLength - dwMemPos)
401
+ const DMFSMPI *pds = (DMFSMPI *)(lpStream+dwMemPos);
402
+ if ((pds->size >= dwMemLength) || (dwMemPos + 8 > dwMemLength - pds->size )) goto dmfexit;
403
+ if (pds->size >= 1 )
385
404
{
386
405
DWORD dwPos = dwMemPos + 9 ;
387
406
m_nSamples = pds->samples ;
388
407
if (m_nSamples >= MAX_SAMPLES) m_nSamples = MAX_SAMPLES-1 ;
389
408
for (UINT iSmp=1 ; iSmp<=m_nSamples; iSmp++)
390
409
{
410
+ if (dwPos >= dwMemPos + pds->size + 8 ) break ;
391
411
UINT namelen = lpStream[dwPos];
392
412
smplflags[iSmp] = 0 ;
393
413
if (dwPos+namelen+1 +sizeof (DMFSAMPLE) > dwMemPos+pds->size +8 ) break ;
@@ -398,7 +418,7 @@ BOOL CSoundFile::ReadDMF(const BYTE *lpStream, DWORD dwMemLength)
398
418
m_szNames[iSmp][rlen] = 0 ;
399
419
}
400
420
dwPos += namelen + 1 ;
401
- DMFSAMPLE *psh = (DMFSAMPLE *)(lpStream+dwPos);
421
+ const DMFSAMPLE *psh = (DMFSAMPLE *)(lpStream+dwPos);
402
422
MODINSTRUMENT *psmp = &Ins[iSmp];
403
423
psmp->nLength = psh->len ;
404
424
psmp->nLoopStart = psh->loopstart ;
@@ -425,7 +445,7 @@ BOOL CSoundFile::ReadDMF(const BYTE *lpStream, DWORD dwMemLength)
425
445
{
426
446
DWORD dwPos = dwMemPos + 8 ;
427
447
UINT ismpd = 0 ;
428
- for (UINT iSmp=1 ; iSmp<=m_nSamples; iSmp++)
448
+ for (UINT iSmp=1 ; iSmp<=m_nSamples && !hasSMPD ; iSmp++)
429
449
{
430
450
ismpd++;
431
451
DWORD pksize;
@@ -458,6 +478,7 @@ BOOL CSoundFile::ReadDMF(const BYTE *lpStream, DWORD dwMemLength)
458
478
}
459
479
dwPos += pksize;
460
480
}
481
+ hasSMPD = 1 ;
461
482
dwMemPos = dwPos;
462
483
}
463
484
break ;
@@ -520,8 +541,8 @@ static BYTE DMFReadBits(DMF_HTREE *tree, UINT nbits)
520
541
{
521
542
tree->bitnum --;
522
543
} else
523
- {
524
- tree->bitbuf = (tree-> ibuf < tree-> ibufmax ) ? *(tree->ibuf ++) : 0 ;
544
+ if (tree-> ibuf < tree-> ibufmax ) {
545
+ tree->bitbuf = *(tree->ibuf ++);
525
546
tree->bitnum = 7 ;
526
547
}
527
548
if (tree->bitbuf & 1 ) x |= bitv;
@@ -576,14 +597,24 @@ int DMFUnpack(LPBYTE psample, LPBYTE ibuf, LPBYTE ibufmax, UINT maxlen)
576
597
DMF_HTREE tree;
577
598
UINT actnode;
578
599
BYTE value, sign, delta = 0 ;
579
-
600
+
580
601
memset (&tree, 0 , sizeof (tree));
581
602
tree.ibuf = ibuf;
582
603
tree.ibufmax = ibufmax;
583
604
DMFNewNode (&tree);
584
605
value = 0 ;
606
+
607
+ if (tree.ibuf >= ibufmax) return tree.ibuf - ibuf;
608
+
585
609
for (UINT i=0 ; i<maxlen; i++)
586
610
{
611
+ if ((tree.ibuf >= tree.ibufmax ) && (!tree.bitnum ))
612
+ {
613
+ #ifdef DMFLOG
614
+ Log (" DMFUnpack: unexpected EOF at output byte %d / %d\n " , i, maxlen);
615
+ #endif
616
+ break ;
617
+ }
587
618
actnode = 0 ;
588
619
sign = DMFReadBits (&tree, 1 );
589
620
do
0 commit comments