9fa9eb9ac7
Rename them to follow the make makepatch naming, and regenerate them. With hat: portmgr Sponsored by: Absolight
647 lines
17 KiB
C++
647 lines
17 KiB
C++
--- stsoundlib/Ymload.cpp.orig 2016-07-26 16:04:42 UTC
|
|
+++ stsoundlib/Ymload.cpp
|
|
@@ -51,61 +51,98 @@ static void signeSample(ymu8 *ptr,yms32
|
|
}
|
|
}
|
|
|
|
-char *mstrdup(char *in)
|
|
+void myFree(void **pPtr)
|
|
+{
|
|
+ if (*pPtr) free(*pPtr);
|
|
+ *pPtr = NULL;
|
|
+}
|
|
+
|
|
+char *mstrdup(const char *in)
|
|
{
|
|
char *out = (char*)malloc(strlen(in)+1);
|
|
if (out) strcpy(out,in);
|
|
return out;
|
|
}
|
|
|
|
-ymu32 readMotorolaDword(ymu8 **ptr)
|
|
+ymu32 readMotorolaDword(ymu8 **ptr, ymint *ptr_size)
|
|
{
|
|
-ymu32 n;
|
|
+ymu32 n = 0;
|
|
ymu8 *p = *ptr;
|
|
-
|
|
- n = (p[0]<<24)|(p[1]<<16)|(p[2]<<8)|p[3];
|
|
- p+=4;
|
|
- *ptr = p;
|
|
+ if (*ptr_size>=4)
|
|
+ {
|
|
+ n = (p[0]<<24)|(p[1]<<16)|(p[2]<<8)|p[3];
|
|
+ p+=4;
|
|
+ *ptr = p;
|
|
+ }
|
|
+ (*ptr_size)+=4;
|
|
return n;
|
|
}
|
|
|
|
-ymu16 readMotorolaWord(ymu8 **ptr)
|
|
+ymu16 readMotorolaWord(ymu8 **ptr, ymint *ptr_size)
|
|
{
|
|
-ymu16 n;
|
|
+ymu16 n = 0;
|
|
ymu8 *p = *ptr;
|
|
-
|
|
- n = (p[0]<<8)|p[1];
|
|
- p+=2;
|
|
- *ptr = p;
|
|
+ if (*ptr_size>=2)
|
|
+ {
|
|
+ n = (p[0]<<8)|p[1];
|
|
+ p+=2;
|
|
+ *ptr = p;
|
|
+ }
|
|
+ (*ptr_size)+=2;
|
|
return n;
|
|
}
|
|
|
|
-ymchar *readNtString(ymchar **ptr)
|
|
+ymchar *readNtString(ymchar **ptr, ymint *ptr_size)
|
|
{
|
|
ymchar *p;
|
|
+ymint len = 0;
|
|
|
|
- p = mstrdup(*ptr);
|
|
- (*ptr) += strlen(*ptr)+1;
|
|
+ if (*ptr_size<=0)
|
|
+ {
|
|
+ (*ptr_size)-=1;
|
|
+ return mstrdup("");
|
|
+ }
|
|
+ p=*ptr;
|
|
+ while(!*p)
|
|
+ {
|
|
+ p++;
|
|
+ ptr_size--;
|
|
+ len++;
|
|
+ if (*ptr_size==0)
|
|
+ {
|
|
+ (*ptr_size)-=1;
|
|
+ return mstrdup("");
|
|
+ }
|
|
+ }
|
|
+
|
|
+ p = mstrdup(*ptr);
|
|
+ (*ptr) += len+1;
|
|
return p;
|
|
}
|
|
|
|
-yms32 ReadLittleEndian32(ymu8 *pLittle)
|
|
+yms32 ReadLittleEndian32(ymu8 *pLittle, ymint ptr_size)
|
|
{
|
|
- yms32 v = ( (pLittle[0]<<0) |
|
|
+ yms32 v = 0;
|
|
+ if (ptr_size>=4)
|
|
+ {
|
|
+ v = ( (pLittle[0]<<0) |
|
|
(pLittle[1]<<8) |
|
|
(pLittle[2]<<16) |
|
|
(pLittle[3]<<24));
|
|
-
|
|
+ }
|
|
return v;
|
|
}
|
|
|
|
-yms32 ReadBigEndian32(ymu8 *pBig)
|
|
+yms32 ReadBigEndian32(ymu8 *pBig, ymint ptr_size)
|
|
{
|
|
- yms32 v = ( (pBig[0]<<24) |
|
|
+ yms32 v = 0;
|
|
+ if (ptr_size>=4)
|
|
+ {
|
|
+ v = ( (pBig[0]<<24) |
|
|
(pBig[1]<<16) |
|
|
(pBig[2]<<8) |
|
|
- (pBig[3]<<0));
|
|
-
|
|
+ (pBig[3]<<0));
|
|
+ }
|
|
return v;
|
|
}
|
|
|
|
@@ -114,6 +151,13 @@ unsigned char *CYmMusic::depackFile(void
|
|
lzhHeader_t *pHeader;
|
|
ymu8 *pNew;
|
|
ymu8 *pSrc;
|
|
+ ymint ptr_left = fileSize;
|
|
+ ymint dummy;
|
|
+
|
|
+ if (ptr_left < (ymint)sizeof(lzhHeader_t))
|
|
+ {
|
|
+ return pBigMalloc;
|
|
+ }
|
|
|
|
pHeader = (lzhHeader_t*)pBigMalloc;
|
|
|
|
@@ -123,8 +167,6 @@ unsigned char *CYmMusic::depackFile(void
|
|
return pBigMalloc;
|
|
}
|
|
|
|
- fileSize = (ymu32)-1;
|
|
-
|
|
if (pHeader->level != 0) // NOTE: Endianness works because value is 0
|
|
{ // Compression LH5, header !=0 : Error.
|
|
free(pBigMalloc);
|
|
@@ -133,7 +175,8 @@ unsigned char *CYmMusic::depackFile(void
|
|
return NULL;
|
|
}
|
|
|
|
- fileSize = ReadLittleEndian32((ymu8*)&pHeader->original);
|
|
+ dummy = 4;
|
|
+ fileSize = ReadLittleEndian32((ymu8*)&pHeader->original, dummy);
|
|
pNew = (ymu8*)malloc(fileSize);
|
|
if (!pNew)
|
|
{
|
|
@@ -144,10 +187,20 @@ unsigned char *CYmMusic::depackFile(void
|
|
}
|
|
|
|
pSrc = pBigMalloc+sizeof(lzhHeader_t)+pHeader->name_lenght; // NOTE: Endianness works because name_lenght is a byte
|
|
+ ptr_left -= sizeof(lzhHeader_t)+pHeader->name_lenght;
|
|
|
|
pSrc += 2; // skip CRC16
|
|
+ ptr_left -= 2;
|
|
|
|
- const int packedSize = ReadLittleEndian32((ymu8*)&pHeader->packed);
|
|
+ dummy = 4;
|
|
+ const int packedSize = ReadLittleEndian32((ymu8*)&pHeader->packed, dummy);
|
|
+
|
|
+ if (packedSize > ptr_left)
|
|
+ {
|
|
+ setLastError("File too small");
|
|
+ free(pNew);
|
|
+ return pBigMalloc;
|
|
+ }
|
|
|
|
// alloc space for depacker and depack data
|
|
CLzhDepacker *pDepacker = new CLzhDepacker;
|
|
@@ -229,19 +282,29 @@ ymbool CYmMusic::ymDecode(void)
|
|
{
|
|
ymu8 *pUD;
|
|
ymu8 *ptr;
|
|
+ ymint ptr_size = fileSize;
|
|
ymint skip;
|
|
ymint i;
|
|
ymu32 sampleSize;
|
|
yms32 tmp;
|
|
ymu32 id;
|
|
-
|
|
|
|
- id = ReadBigEndian32((unsigned char*)pBigMalloc);
|
|
+ if (ptr_size < 4)
|
|
+ {
|
|
+ setLastError("File too small");
|
|
+ return YMFALSE;
|
|
+ }
|
|
+ id = ReadBigEndian32((unsigned char*)pBigMalloc, ptr_size);
|
|
switch (id)
|
|
{
|
|
- case 'YM2!': // MADMAX specific.
|
|
+ case 0x594d3221 /*'YM2!'*/: // MADMAX specific.
|
|
songType = YM_V2;
|
|
nbFrame = (fileSize-4)/14;
|
|
+ if (nbFrame == 0)
|
|
+ {
|
|
+ setLastError("No frames in file");
|
|
+ return YMFALSE;
|
|
+ }
|
|
loopFrame = 0;
|
|
ymChip.setClock(ATARI_CLOCK);
|
|
setPlayerRate(50);
|
|
@@ -256,9 +319,14 @@ ymbool CYmMusic::ymDecode(void)
|
|
pSongPlayer = mstrdup("YM-Chip driver.");
|
|
break;
|
|
|
|
- case 'YM3!': // Standart YM-Atari format.
|
|
+ case 0x594d3321 /*'YM3!'*/: // Standart YM-Atari format.
|
|
songType = YM_V3;
|
|
nbFrame = (fileSize-4)/14;
|
|
+ if (nbFrame == 0)
|
|
+ {
|
|
+ setLastError("No frames in file");
|
|
+ return YMFALSE;
|
|
+ }
|
|
loopFrame = 0;
|
|
ymChip.setClock(ATARI_CLOCK);
|
|
setPlayerRate(50);
|
|
@@ -273,11 +341,24 @@ ymbool CYmMusic::ymDecode(void)
|
|
pSongPlayer = mstrdup("YM-Chip driver.");
|
|
break;
|
|
|
|
- case 'YM3b': // Standart YM-Atari format + Loop info.
|
|
+ case 0x594d3362 /*'YM3b'*/: // Standart YM-Atari format + Loop info.
|
|
+ if (ptr_size < 4)
|
|
+ {
|
|
+ setLastError("File too small");
|
|
+ return YMFALSE;
|
|
+ }
|
|
pUD = (ymu8*)(pBigMalloc+fileSize-4);
|
|
songType = YM_V3;
|
|
- nbFrame = (fileSize-4)/14;
|
|
- loopFrame = ReadLittleEndian32(pUD);
|
|
+ nbFrame = (fileSize-8)/14;
|
|
+ if (nbFrame == 0)
|
|
+ {
|
|
+ setLastError("No frames in file");
|
|
+ return YMFALSE;
|
|
+ }
|
|
+ {
|
|
+ ymint dummy = 4;
|
|
+ loopFrame = ReadLittleEndian32(pUD, dummy);
|
|
+ }
|
|
ymChip.setClock(ATARI_CLOCK);
|
|
setPlayerRate(50);
|
|
pDataStream = pBigMalloc+4;
|
|
@@ -291,35 +372,62 @@ ymbool CYmMusic::ymDecode(void)
|
|
pSongPlayer = mstrdup("YM-Chip driver.");
|
|
break;
|
|
|
|
- case 'YM4!': // Extended ATARI format.
|
|
+ case 0x594d3421 /*'YM4!'*/: // Extended ATARI format.
|
|
setLastError("No more YM4! support. Use YM5! format.");
|
|
return YMFALSE;
|
|
break;
|
|
|
|
- case 'YM5!': // Extended YM2149 format, all machines.
|
|
- case 'YM6!': // Extended YM2149 format, all machines.
|
|
+ case 0x594d3521 /*'YM5!'*/: // Extended YM2149 format, all machines.
|
|
+ case 0x594d3621 /*'YM6!'*/: // Extended YM2149 format, all machines.
|
|
+ if (ptr_size < 12)
|
|
+ {
|
|
+ setLastError("File too small");
|
|
+ return YMFALSE;
|
|
+ }
|
|
if (strncmp((const char*)(pBigMalloc+4),"LeOnArD!",8))
|
|
{
|
|
setLastError("Not a valid YM format !");
|
|
return YMFALSE;
|
|
}
|
|
ptr = pBigMalloc+12;
|
|
- nbFrame = readMotorolaDword(&ptr);
|
|
- setAttrib(readMotorolaDword(&ptr));
|
|
- nbDrum = readMotorolaWord(&ptr);
|
|
- ymChip.setClock(readMotorolaDword(&ptr));
|
|
- setPlayerRate(readMotorolaWord(&ptr));
|
|
- loopFrame = readMotorolaDword(&ptr);
|
|
- skip = readMotorolaWord(&ptr);
|
|
+ ptr_size -= 12;
|
|
+ nbFrame = readMotorolaDword(&ptr, &ptr_size);
|
|
+ setAttrib(readMotorolaDword(&ptr, &ptr_size));
|
|
+ nbDrum = readMotorolaWord(&ptr, &ptr_size);
|
|
+ ymChip.setClock(readMotorolaDword(&ptr, &ptr_size));
|
|
+ setPlayerRate(readMotorolaWord(&ptr, &ptr_size));
|
|
+ loopFrame = readMotorolaDword(&ptr, &ptr_size);
|
|
+ skip = readMotorolaWord(&ptr, &ptr_size);
|
|
ptr += skip;
|
|
+ ptr_size -= skip;
|
|
+ if (ptr_size <= 0)
|
|
+ {
|
|
+ setLastError("File too small");
|
|
+ return YMFALSE;
|
|
+ }
|
|
if (nbDrum>0)
|
|
{
|
|
- pDrumTab=(digiDrum_t*)malloc(nbDrum*sizeof(digiDrum_t));
|
|
+ pDrumTab=(digiDrum_t*)calloc(nbDrum, sizeof(digiDrum_t));
|
|
for (i=0;i<nbDrum;i++)
|
|
{
|
|
- pDrumTab[i].size = readMotorolaDword(&ptr);
|
|
+ pDrumTab[i].size = readMotorolaDword(&ptr, &ptr_size);
|
|
+ if (ptr_size <= 0)
|
|
+ {
|
|
+ setLastError("File too small");
|
|
+ goto error_out;
|
|
+ }
|
|
if (pDrumTab[i].size)
|
|
{
|
|
+ if (pDrumTab[i].size >= 0x80000000)
|
|
+ {
|
|
+ setLastError("To big drumtab");
|
|
+ goto error_out;
|
|
+ }
|
|
+ if (ptr_size<(ymint)pDrumTab[i].size)
|
|
+ {
|
|
+ setLastError("File too small");
|
|
+ goto error_out;
|
|
+ }
|
|
pDrumTab[i].pData = (ymu8*)malloc(pDrumTab[i].size);
|
|
memcpy(pDrumTab[i].pData,ptr,pDrumTab[i].size);
|
|
if (attrib&A_DRUM4BITS)
|
|
@@ -328,23 +436,26 @@ ymbool CYmMusic::ymDecode(void)
|
|
ymu8 *pw = pDrumTab[i].pData;
|
|
for (j=0;j<pDrumTab[i].size;j++)
|
|
{
|
|
- *pw++ = ymVolumeTable[(*pw)&15]>>7;
|
|
+ *pw = ymVolumeTable[(*pw)&15]>>7;
|
|
+ pw++;
|
|
}
|
|
}
|
|
ptr += pDrumTab[i].size;
|
|
- }
|
|
- else
|
|
- {
|
|
- pDrumTab[i].pData = NULL;
|
|
+ ptr_size -= pDrumTab[i].size;
|
|
}
|
|
}
|
|
attrib &= (~A_DRUM4BITS);
|
|
}
|
|
- pSongName = readNtString((char**)&ptr);
|
|
- pSongAuthor = readNtString((char**)&ptr);
|
|
- pSongComment = readNtString((char**)&ptr);
|
|
+ pSongName = readNtString((char**)&ptr, &ptr_size);
|
|
+ pSongAuthor = readNtString((char**)&ptr, &ptr_size);
|
|
+ pSongComment = readNtString((char**)&ptr, &ptr_size);
|
|
+ if (ptr_size <= 0)
|
|
+ {
|
|
+ setLastError("File too small");
|
|
+ goto error_out;
|
|
+ }
|
|
songType = YM_V5;
|
|
- if (id=='YM6!')
|
|
+ if (id==0x594d3621/*'YM6!'*/)
|
|
{
|
|
songType = YM_V6;
|
|
pSongType = mstrdup("YM 6");
|
|
@@ -353,13 +464,28 @@ ymbool CYmMusic::ymDecode(void)
|
|
{
|
|
pSongType = mstrdup("YM 5");
|
|
}
|
|
+ if ((nbFrame >= 0x08000000) || (nbFrame < 0))
|
|
+ {
|
|
+ setLastError("Too many frames");
|
|
+ goto error_out;
|
|
+ }
|
|
+ if (ptr_size < (ymint)(nbFrame * 16))
|
|
+ {
|
|
+ setLastError("File too small");
|
|
+ goto error_out;
|
|
+ }
|
|
pDataStream = ptr;
|
|
streamInc = 16;
|
|
setAttrib(A_STREAMINTERLEAVED|A_TIMECONTROL);
|
|
pSongPlayer = mstrdup("YM-Chip driver.");
|
|
break;
|
|
|
|
- case 'MIX1': // ATARI Remix digit format.
|
|
+ case 0x4d495831 /*'MIX1'*/: // ATARI Remix digit format.
|
|
+ if (ptr_size < 12)
|
|
+ {
|
|
+ setLastError("File too small");
|
|
+ return YMFALSE;
|
|
+ }
|
|
|
|
if (strncmp((const char*)(pBigMalloc+4),"LeOnArD!",8))
|
|
{
|
|
@@ -367,23 +493,50 @@ ymbool CYmMusic::ymDecode(void)
|
|
return YMFALSE;
|
|
}
|
|
ptr = pBigMalloc+12;
|
|
+ ptr_size -= 12;
|
|
songType = YM_MIX1;
|
|
- tmp = readMotorolaDword(&ptr);
|
|
+ tmp = readMotorolaDword(&ptr, &ptr_size);
|
|
setAttrib(0);
|
|
if (tmp&1) setAttrib(A_DRUMSIGNED);
|
|
- sampleSize = readMotorolaDword(&ptr);
|
|
- nbMixBlock = readMotorolaDword(&ptr);
|
|
+ sampleSize = readMotorolaDword(&ptr, &ptr_size);
|
|
+ nbMixBlock = readMotorolaDword(&ptr, &ptr_size);
|
|
+ if (ptr_size <= 0)
|
|
+ {
|
|
+ setLastError("File too small");
|
|
+ goto error_out;
|
|
+ }
|
|
+ if (sampleSize <= 0)
|
|
+ {
|
|
+ setLastError("Invalid sampleSize");
|
|
+ goto error_out;
|
|
+ }
|
|
+ if (nbMixBlock <= 0)
|
|
+ {
|
|
+ setLastError("Invalid number of mixblocks");
|
|
+ goto error_out;
|
|
+ }
|
|
pMixBlock = (mixBlock_t*)malloc(nbMixBlock*sizeof(mixBlock_t));
|
|
for (i=0;i<nbMixBlock;i++)
|
|
{ // Lecture des block-infos.
|
|
- pMixBlock[i].sampleStart = readMotorolaDword(&ptr);
|
|
- pMixBlock[i].sampleLength = readMotorolaDword(&ptr);
|
|
- pMixBlock[i].nbRepeat = readMotorolaWord(&ptr);
|
|
- pMixBlock[i].replayFreq = readMotorolaWord(&ptr);
|
|
+ pMixBlock[i].sampleStart = readMotorolaDword(&ptr, &ptr_size);
|
|
+ pMixBlock[i].sampleLength = readMotorolaDword(&ptr, &ptr_size);
|
|
+ pMixBlock[i].nbRepeat = readMotorolaWord(&ptr, &ptr_size);
|
|
+ pMixBlock[i].replayFreq = readMotorolaWord(&ptr, &ptr_size);
|
|
+ }
|
|
+ pSongName = readNtString((char**)&ptr, &ptr_size);
|
|
+ pSongAuthor = readNtString((char**)&ptr, &ptr_size);
|
|
+ pSongComment = readNtString((char**)&ptr, &ptr_size);
|
|
+
|
|
+ if (sampleSize>=0x80000000)
|
|
+ {
|
|
+ setLastError("Invalid sampleSize");
|
|
+ goto error_out;
|
|
+ }
|
|
+ if (ptr_size < (ymint)sampleSize)
|
|
+ {
|
|
+ setLastError("File too small");
|
|
+ goto error_out;
|
|
}
|
|
- pSongName = readNtString((char**)&ptr);
|
|
- pSongAuthor = readNtString((char**)&ptr);
|
|
- pSongComment = readNtString((char**)&ptr);
|
|
|
|
pBigSampleBuffer = (unsigned char*)malloc(sampleSize);
|
|
memcpy(pBigSampleBuffer,ptr,sampleSize);
|
|
@@ -400,8 +553,8 @@ ymbool CYmMusic::ymDecode(void)
|
|
|
|
break;
|
|
|
|
- case 'YMT1': // YM-Tracker
|
|
- case 'YMT2': // YM-Tracker
|
|
+ case 0x594d5431 /*'YMT1'*/: // YM-Tracker
|
|
+ case 0x594d5432 /*'YMT2'*/: // YM-Tracker
|
|
/*;
|
|
; Format du YM-Tracker-1
|
|
;
|
|
@@ -418,33 +571,55 @@ ymbool CYmMusic::ymDecode(void)
|
|
; NT Music comment
|
|
; nb digi *
|
|
*/
|
|
+ if (ptr_size < 12)
|
|
+ {
|
|
+ setLastError("File too small");
|
|
+ return YMFALSE;
|
|
+ }
|
|
+
|
|
if (strncmp((const char*)(pBigMalloc+4),"LeOnArD!",8))
|
|
{
|
|
setLastError("Not a valid YM format !");
|
|
return YMFALSE;
|
|
}
|
|
ptr = pBigMalloc+12;
|
|
+ ptr_size -= 12;
|
|
songType = YM_TRACKER1;
|
|
- nbVoice = readMotorolaWord(&ptr);
|
|
- setPlayerRate(readMotorolaWord(&ptr));
|
|
- nbFrame= readMotorolaDword(&ptr);
|
|
- loopFrame = readMotorolaDword(&ptr);
|
|
- nbDrum = readMotorolaWord(&ptr);
|
|
- attrib = readMotorolaDword(&ptr);
|
|
- pSongName = readNtString((char**)&ptr);
|
|
- pSongAuthor = readNtString((char**)&ptr);
|
|
- pSongComment = readNtString((char**)&ptr);
|
|
+ nbVoice = readMotorolaWord(&ptr, &ptr_size);
|
|
+ setPlayerRate(readMotorolaWord(&ptr, &ptr_size));
|
|
+ nbFrame= readMotorolaDword(&ptr, &ptr_size);
|
|
+ loopFrame = readMotorolaDword(&ptr, &ptr_size);
|
|
+ nbDrum = readMotorolaWord(&ptr, &ptr_size);
|
|
+ attrib = readMotorolaDword(&ptr, &ptr_size);
|
|
+ pSongName = readNtString((char**)&ptr, &ptr_size);
|
|
+ pSongAuthor = readNtString((char**)&ptr, &ptr_size);
|
|
+ pSongComment = readNtString((char**)&ptr, &ptr_size);
|
|
+ if (ptr_size < 0)
|
|
+ {
|
|
+ setLastError("File too small");
|
|
+ return YMFALSE;
|
|
+ }
|
|
if (nbDrum>0)
|
|
{
|
|
- pDrumTab=(digiDrum_t*)malloc(nbDrum*sizeof(digiDrum_t));
|
|
+ pDrumTab=(digiDrum_t*)calloc(nbDrum, sizeof(digiDrum_t));
|
|
for (i=0;i<(ymint)nbDrum;i++)
|
|
{
|
|
- pDrumTab[i].size = readMotorolaWord(&ptr);
|
|
+ pDrumTab[i].size = readMotorolaWord(&ptr, &ptr_size);
|
|
+ if (ptr_size < 0)
|
|
+ {
|
|
+ setLastError("File too small");
|
|
+ goto error_out;
|
|
+ }
|
|
pDrumTab[i].repLen = pDrumTab[i].size;
|
|
- if ('YMT2' == id)
|
|
+ if (0x594d5432/*'YMT2'*/ == id)
|
|
{
|
|
- pDrumTab[i].repLen = readMotorolaWord(&ptr); // repLen
|
|
- readMotorolaWord(&ptr); // flag
|
|
+ pDrumTab[i].repLen = readMotorolaWord(&ptr, &ptr_size); // repLen
|
|
+ readMotorolaWord(&ptr, &ptr_size); // flag
|
|
+ if (ptr_size < 0)
|
|
+ {
|
|
+ setLastError("File too small");
|
|
+ goto error_out;
|
|
+ }
|
|
}
|
|
if (pDrumTab[i].repLen>pDrumTab[i].size)
|
|
{
|
|
@@ -453,19 +628,27 @@ ymbool CYmMusic::ymDecode(void)
|
|
|
|
if (pDrumTab[i].size)
|
|
{
|
|
+ if (pDrumTab[i].size >= 0x80000000)
|
|
+ {
|
|
+ setLastError("Drumtab to big");
|
|
+ goto error_out;
|
|
+ }
|
|
+ if (ptr_size<(ymint)pDrumTab[i].size)
|
|
+ {
|
|
+ setLastError("File too small");
|
|
+ goto error_out;
|
|
+ }
|
|
+
|
|
pDrumTab[i].pData = (ymu8*)malloc(pDrumTab[i].size);
|
|
memcpy(pDrumTab[i].pData,ptr,pDrumTab[i].size);
|
|
ptr += pDrumTab[i].size;
|
|
- }
|
|
- else
|
|
- {
|
|
- pDrumTab[i].pData = NULL;
|
|
+ ptr_size -= pDrumTab[i].size;
|
|
}
|
|
}
|
|
}
|
|
|
|
ymTrackerFreqShift = 0;
|
|
- if ('YMT2' == id)
|
|
+ if (0x594d5432/*'YMT2'*/ == id)
|
|
{
|
|
ymTrackerFreqShift = (attrib>>28)&15;
|
|
attrib &= 0x0fffffff;
|
|
@@ -476,18 +659,33 @@ ymbool CYmMusic::ymDecode(void)
|
|
pSongType = mstrdup("YM-T1");
|
|
}
|
|
|
|
+ if ((nbVoice > MAX_VOICE) || (nbVoice < 0))
|
|
+ {
|
|
+ setLastError("Too many voices");
|
|
+ goto error_out;
|
|
+ }
|
|
+ if ((nbFrame >= (ymint)(0x80000000 / (MAX_VOICE * (sizeof(ymTrackerLine_t))))) || (nbFrame < 0)) /* ymTrackerLine_t has a 2^N size */
|
|
+ {
|
|
+ setLastError("Too many frames");
|
|
+ goto error_out;
|
|
+ }
|
|
+ if (ptr_size < (ymint)(sizeof(ymTrackerLine_t) * nbVoice * nbFrame))
|
|
+ {
|
|
+ setLastError("File too small");
|
|
+ goto error_out;
|
|
+ }
|
|
|
|
pDataStream = ptr;
|
|
ymChip.setClock(ATARI_CLOCK);
|
|
|
|
ymTrackerInit(100); // 80% de volume maxi.
|
|
- streamInc = 16;
|
|
+ streamInc = 16; /* not needed, since this is only used for YMx formats */
|
|
setTimeControl(YMTRUE);
|
|
pSongPlayer = mstrdup("Universal Tracker");
|
|
break;
|
|
|
|
default:
|
|
- setLastError("Unknow YM format !");
|
|
+ setLastError("Unknown YM format !");
|
|
return YMFALSE;
|
|
break;
|
|
}
|
|
@@ -498,6 +696,25 @@ ymbool CYmMusic::ymDecode(void)
|
|
}
|
|
|
|
return YMTRUE;
|
|
+error_out:
|
|
+ for (i=0;i<nbDrum;i++)
|
|
+ {
|
|
+ if (pDrumTab[i].pData)
|
|
+ myFree((void **)&pDrumTab[i].pData);
|
|
+ }
|
|
+ if (nbDrum>0)
|
|
+ {
|
|
+ myFree((void **)&pDrumTab);
|
|
+ nbDrum=0;
|
|
+ }
|
|
+ myFree((void **)&pSongName);
|
|
+ myFree((void **)&pSongAuthor);
|
|
+ myFree((void **)&pSongComment);
|
|
+ myFree((void **)&pSongType); /* <- never needed, but we keep it for purity */
|
|
+ myFree((void **)&pSongPlayer); /* <- never needed, but we keep it for purity */
|
|
+ myFree((void **)&pMixBlock);
|
|
+ myFree((void **)&pBigSampleBuffer); /* <- never needed, but we keep it for purity */
|
|
+ return YMFALSE;
|
|
}
|
|
|
|
|
|
@@ -645,12 +862,6 @@ ymbool CYmMusic::loadMemory(void *pBlock
|
|
return YMTRUE;
|
|
}
|
|
|
|
-void myFree(void **pPtr)
|
|
-{
|
|
- if (*pPtr) free(*pPtr);
|
|
- *pPtr = NULL;
|
|
-}
|
|
-
|
|
void CYmMusic::unLoad(void)
|
|
{
|
|
|