diff options
author | Emanuel Haupt <ehaupt@FreeBSD.org> | 2010-04-23 12:06:32 +0000 |
---|---|---|
committer | Emanuel Haupt <ehaupt@FreeBSD.org> | 2010-04-23 12:06:32 +0000 |
commit | b244f636f203fa4a6cf32157354a34afa4bb48ad (patch) | |
tree | d9c583c7d6e1076e2a68c36e29da5be1d91d5339 /audio/stymulator/files/patch-stsoundlib__Ymload.cpp | |
parent | Move to my new address. (diff) |
Include additional patchset.
Obtained from: http://stian.cubic.org/blog-20100422.php
Diffstat (limited to 'audio/stymulator/files/patch-stsoundlib__Ymload.cpp')
-rw-r--r-- | audio/stymulator/files/patch-stsoundlib__Ymload.cpp | 742 |
1 files changed, 578 insertions, 164 deletions
diff --git a/audio/stymulator/files/patch-stsoundlib__Ymload.cpp b/audio/stymulator/files/patch-stsoundlib__Ymload.cpp index c724d024dcf1..9b5bd81f3e2c 100644 --- a/audio/stymulator/files/patch-stsoundlib__Ymload.cpp +++ b/audio/stymulator/files/patch-stsoundlib__Ymload.cpp @@ -1,233 +1,647 @@ ---- stsoundlib/Ymload.cpp.orig 2010-03-27 16:37:51.000000000 +0100 -+++ stsoundlib/Ymload.cpp 2010-03-27 16:40:46.000000000 +0100 -@@ -129,7 +129,7 @@ +--- ./stsoundlib/Ymload.cpp.orig 2010-04-23 13:49:47.000000000 +0200 ++++ ./stsoundlib/Ymload.cpp 2010-04-23 13:50:07.000000000 +0200 +@@ -51,61 +51,98 @@ + } + } + +-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 @@ + 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 @@ + return pBigMalloc; + } + +- fileSize = (ymu32)-1; +- + if (pHeader->level != 0) // NOTE: Endianness works because value is 0 { // Compression LH5, header !=0 : Error. free(pBigMalloc); - pBigMalloc = NULL; -- setLastError("LHARC Header must be 0 !"); -+ setLastError(((char *)"LHARC Header must be 0 !")); +@@ -133,7 +175,8 @@ return NULL; } -@@ -137,7 +137,7 @@ +- fileSize = ReadLittleEndian32((ymu8*)&pHeader->original); ++ dummy = 4; ++ fileSize = ReadLittleEndian32((ymu8*)&pHeader->original, dummy); pNew = (ymu8*)malloc(fileSize); if (!pNew) { -- setLastError("MALLOC Failed !"); -+ setLastError(((char *)"MALLOC Failed !")); - free(pBigMalloc); - pBigMalloc = NULL; - return NULL; -@@ -159,7 +159,7 @@ - - if (!bRet) - { // depacking error -- setLastError("LH5 Depacking Error !"); -+ setLastError(((char *)"LH5 Depacking Error !")); - free(pNew); - pNew = NULL; +@@ -144,10 +187,20 @@ } -@@ -197,7 +197,7 @@ - tmpBuff = (ymu8*)malloc(nbFrame*streamInc); - if (!tmpBuff) - { -- setLastError("Malloc error in deInterleave()\n"); -+ setLastError(((char *)"Malloc error in deInterleave()\n")); - return YMFALSE; - } -@@ -249,11 +249,11 @@ - streamInc = 14; - nbDrum = 0; - setAttrib(A_STREAMINTERLEAVED|A_TIMECONTROL); -- pSongName = mstrdup("Unknown"); -- pSongAuthor = mstrdup("Unknown"); -- pSongComment = mstrdup("Converted by Leonard."); -- pSongType = mstrdup("YM 2"); -- pSongPlayer = mstrdup("YM-Chip driver."); -+ pSongName = mstrdup(((char *)"Unknown")); -+ pSongAuthor = mstrdup(((char *)"Unknown")); -+ pSongComment = mstrdup(((char *)"Converted by Leonard.")); -+ pSongType = mstrdup(((char *)"YM 2")); -+ pSongPlayer = mstrdup(((char *)"YM-Chip driver.")); + 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 @@ + { + 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 @@ + pSongPlayer = mstrdup("YM-Chip driver."); break; - case 'YM3!': // Standart YM-Atari format. -@@ -266,11 +266,11 @@ - streamInc = 14; - nbDrum = 0; - setAttrib(A_STREAMINTERLEAVED|A_TIMECONTROL); -- pSongName = mstrdup("Unknown"); -- pSongAuthor = mstrdup("Unknown"); -- pSongComment = mstrdup(""); -- pSongType = mstrdup("YM 3"); -- pSongPlayer = mstrdup("YM-Chip driver."); -+ pSongName = mstrdup(((char *)"Unknown")); -+ pSongAuthor = mstrdup(((char *)"Unknown")); -+ pSongComment = mstrdup(((char *)"")); -+ pSongType = mstrdup(((char *)"YM 3")); -+ pSongPlayer = mstrdup(((char *)"YM-Chip driver.")); +- 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 @@ + pSongPlayer = mstrdup("YM-Chip driver."); break; - case 'YM3b': // Standart YM-Atari format + Loop info. -@@ -284,15 +284,15 @@ - streamInc = 14; - nbDrum = 0; - setAttrib(A_STREAMINTERLEAVED|A_TIMECONTROL); -- pSongName = mstrdup("Unknown"); -- pSongAuthor = mstrdup("Unknown"); -- pSongComment = mstrdup(""); -- pSongType = mstrdup("YM 3b (loop)"); -- pSongPlayer = mstrdup("YM-Chip driver."); -+ pSongName = mstrdup(((char *)"Unknown")); -+ pSongAuthor = mstrdup(((char *)"Unknown")); -+ pSongComment = mstrdup(((char *)"")); -+ pSongType = mstrdup(((char *)"YM 3b (loop)")); -+ pSongPlayer = mstrdup(((char *)"YM-Chip driver.")); +- 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 @@ + pSongPlayer = mstrdup("YM-Chip driver."); break; - case 'YM4!': // Extended ATARI format. -- setLastError("No more YM4! support. Use YM5! format."); -+ setLastError(((char *)"No more YM4! support. Use YM5! format.")); +- case 'YM4!': // Extended ATARI format. ++ case 0x594d3421 /*'YM4!'*/: // Extended ATARI format. + setLastError("No more YM4! support. Use YM5! format."); return YMFALSE; break; -@@ -300,7 +300,7 @@ - case 'YM6!': // Extended YM2149 format, all machines. +- 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 !"); -+ setLastError(((char *)"Not a valid YM format !")); + setLastError("Not a valid YM format !"); return YMFALSE; } ptr = pBigMalloc+12; -@@ -347,23 +347,23 @@ - if (id=='YM6!') +- 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) { - songType = YM_V6; -- pSongType = mstrdup("YM 6"); -+ pSongType = mstrdup(((char *)"YM 6")); +- 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 @@ + 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); } - else +- 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!'*/) { -- pSongType = mstrdup("YM 5"); -+ pSongType = mstrdup(((char *)"YM 5")); + songType = YM_V6; + pSongType = mstrdup("YM 6"); +@@ -353,13 +464,28 @@ + { + 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."); -+ pSongPlayer = mstrdup(((char *)"YM-Chip driver.")); + pSongPlayer = mstrdup("YM-Chip driver."); break; - case 'MIX1': // ATARI Remix digit format. +- 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)) { -- setLastError("Not a valid YM format !"); -+ setLastError(((char *)"Not a valid YM format !")); +@@ -367,23 +493,50 @@ return YMFALSE; } ptr = pBigMalloc+12; -@@ -395,8 +395,8 @@ ++ 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); - mixPos = -1; // numero du block info. -- pSongType = mstrdup("MIX1"); -- pSongPlayer = mstrdup("Digi-Mix driver."); -+ pSongType = mstrdup(((char *)"MIX1")); -+ pSongPlayer = mstrdup(((char *)"Digi-Mix driver.")); + pBigSampleBuffer = (unsigned char*)malloc(sampleSize); + memcpy(pBigSampleBuffer,ptr,sampleSize); +@@ -400,8 +553,8 @@ break; -@@ -420,7 +420,7 @@ +- 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 @@ + ; 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 !"); -+ setLastError(((char *)"Not a valid YM format !")); + setLastError("Not a valid YM format !"); return YMFALSE; } ptr = pBigMalloc+12; -@@ -469,11 +469,11 @@ ++ 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) { - ymTrackerFreqShift = (attrib>>28)&15; - attrib &= 0x0fffffff; -- pSongType = mstrdup("YM-T2"); -+ pSongType = mstrdup(((char *)"YM-T2")); +- 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 @@ + + 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; + } + } } - else + + ymTrackerFreqShift = 0; +- if ('YMT2' == id) ++ if (0x594d5432/*'YMT2'*/ == id) { -- pSongType = mstrdup("YM-T1"); -+ pSongType = mstrdup(((char *)"YM-T1")); + ymTrackerFreqShift = (attrib>>28)&15; + attrib &= 0x0fffffff; +@@ -476,18 +659,33 @@ + 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); -@@ -483,11 +483,11 @@ ymTrackerInit(100); // 80% de volume maxi. - streamInc = 16; +- streamInc = 16; ++ streamInc = 16; /* not needed, since this is only used for YMx formats */ setTimeControl(YMTRUE); -- pSongPlayer = mstrdup("Universal Tracker"); -+ pSongPlayer = mstrdup(((char *)"Universal Tracker")); + pSongPlayer = mstrdup("Universal Tracker"); break; default: - setLastError("Unknow YM format !"); -+ setLastError(((char *)"Unknow YM format !")); ++ setLastError("Unknown YM format !"); return YMFALSE; break; } -@@ -503,7 +503,7 @@ - - ymbool CYmMusic::checkCompilerTypes() - { -- setLastError("Basic types size are not correct (check ymTypes.h)"); -+ setLastError(((char *)"Basic types size are not correct (check ymTypes.h)")); - - if (1 != sizeof(ymu8)) return YMFALSE; - if (1 != sizeof(yms8)) return YMFALSE; -@@ -522,7 +522,7 @@ - - if (sizeof(ymint) < 4) return YMFALSE; // ymint should be at least 32bits +@@ -498,6 +696,25 @@ + } -- setLastError(""); -+ setLastError(((char *)"")); - return YMTRUE; - } + 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; + } -@@ -541,7 +541,7 @@ - in = fopen(fileName,"rb"); - if (!in) - { -- setLastError("File not Found"); -+ setLastError(((char *)"File not Found")); - return YMFALSE; - } + +@@ -645,12 +862,6 @@ + return YMTRUE; + } -@@ -552,7 +552,7 @@ - pBigMalloc = (unsigned char*)malloc(fileSize); - if (!pBigMalloc) - { -- setLastError("MALLOC Error"); -+ setLastError(((char *)"MALLOC Error")); - fclose(in); - return YMFALSE; - } -@@ -563,7 +563,7 @@ - if (fread(pBigMalloc,1,fileSize,in)!=(size_t)fileSize) - { - free(pBigMalloc); -- setLastError("File is corrupted."); -+ setLastError(((char *)"File is corrupted.")); - fclose(in); - return YMFALSE; - } -@@ -611,7 +611,7 @@ - pBigMalloc = (unsigned char*)malloc(fileSize); - if (!pBigMalloc) - { -- setLastError("MALLOC Error"); -+ setLastError(((char *)"MALLOC Error")); - return YMFALSE; - } +-void myFree(void **pPtr) +-{ +- if (*pPtr) free(*pPtr); +- *pPtr = NULL; +-} +- + void CYmMusic::unLoad(void) + { |