XM import: possibly fix crash

thanks LTVA for diagnosis
issue #2453
This commit is contained in:
tildearrow 2025-05-30 07:01:03 -05:00
parent 01348628a8
commit 4d7945f778

View file

@ -162,13 +162,18 @@ void readEnvelope(DivInstrument* ins, int env, unsigned char flags, unsigned cha
}
}
#define XM_FINISH \
delete[] sampleVol; \
delete[] samplePan; \
delete[] noteMap;
bool DivEngine::loadXM(unsigned char* file, size_t len) {
struct InvalidHeaderException {};
bool success=false;
char magic[32];
unsigned char sampleVol[256][256];
unsigned char samplePan[256][256];
unsigned char noteMap[256][128];
unsigned char* sampleVol=new unsigned char[256*256];
unsigned char* samplePan=new unsigned char[256*256];
unsigned char* noteMap=new unsigned char[256*128];
unsigned short patLen[256];
@ -216,6 +221,7 @@ bool DivEngine::loadXM(unsigned char* file, size_t len) {
logE("premature end of file!");
lastError="incomplete file";
delete[] file;
XM_FINISH;
return false;
}
reader.read(magic,17);
@ -255,6 +261,7 @@ bool DivEngine::loadXM(unsigned char* file, size_t len) {
logE("invalid order count!");
lastError="invalid order count";
delete[] file;
XM_FINISH;
return false;
}
@ -262,6 +269,7 @@ bool DivEngine::loadXM(unsigned char* file, size_t len) {
logE("too many patterns!");
lastError="too many patterns";
delete[] file;
XM_FINISH;
return false;
}
@ -269,6 +277,7 @@ bool DivEngine::loadXM(unsigned char* file, size_t len) {
logE("invalid instrument count!");
lastError="invalid instrument count";
delete[] file;
XM_FINISH;
return false;
}
@ -278,6 +287,7 @@ bool DivEngine::loadXM(unsigned char* file, size_t len) {
logE("invalid channel count!");
lastError="invalid channel count";
delete[] file;
XM_FINISH;
return false;
}
@ -306,6 +316,7 @@ bool DivEngine::loadXM(unsigned char* file, size_t len) {
logE("premature end of file!");
lastError="incomplete file";
delete[] file;
XM_FINISH;
return false;
}
@ -322,6 +333,7 @@ bool DivEngine::loadXM(unsigned char* file, size_t len) {
lastError="unknown packing type";
ds.unload();
delete[] file;
XM_FINISH;
return false;
}
@ -334,6 +346,7 @@ bool DivEngine::loadXM(unsigned char* file, size_t len) {
logE("too many rows! %d",totalRows);
lastError="too many rows";
delete[] file;
XM_FINISH;
return false;
}
@ -344,6 +357,7 @@ bool DivEngine::loadXM(unsigned char* file, size_t len) {
logE("premature end of file!");
lastError="incomplete file";
delete[] file;
XM_FINISH;
return false;
}
@ -491,6 +505,7 @@ bool DivEngine::loadXM(unsigned char* file, size_t len) {
logE("premature end of file!");
lastError="incomplete file";
delete[] file;
XM_FINISH;
return false;
}
}
@ -518,6 +533,7 @@ bool DivEngine::loadXM(unsigned char* file, size_t len) {
delete ins;
song.unload();
delete[] file;
XM_FINISH;
return false;
}*/
@ -532,7 +548,7 @@ bool DivEngine::loadXM(unsigned char* file, size_t len) {
for (int j=0; j<96; j++) {
unsigned char nextMap=reader.readC();
ins->amiga.noteMap[j].map=ds.sample.size()+nextMap;
noteMap[i][j]=nextMap;
noteMap[(i<<7)|j]=nextMap;
}
for (int j=0; j<24; j++) {
@ -611,6 +627,7 @@ bool DivEngine::loadXM(unsigned char* file, size_t len) {
logE("premature end of file!");
lastError="incomplete file";
delete[] file;
XM_FINISH;
return false;
}
@ -625,17 +642,18 @@ bool DivEngine::loadXM(unsigned char* file, size_t len) {
lastError="bad sample size";
delete s;
delete[] file;
XM_FINISH;
return false;
}
s->loopStart=reader.readI();
s->loopEnd=reader.readI()+s->loopStart;
sampleVol[i][j]=reader.readC();
sampleVol[(i<<8)|j]=reader.readC();
signed char fine=reader.readC();
unsigned char flags=reader.readC();
samplePan[i][j]=reader.readC();
samplePan[(i<<8)|j]=reader.readC();
signed char note=reader.readC();
switch (flags&3) {
@ -706,6 +724,7 @@ bool DivEngine::loadXM(unsigned char* file, size_t len) {
logE("premature end of file!");
lastError="incomplete file";
delete[] file;
XM_FINISH;
return false;
}
}
@ -717,6 +736,7 @@ bool DivEngine::loadXM(unsigned char* file, size_t len) {
logE("premature end of file!");
lastError="incomplete file";
delete[] file;
XM_FINISH;
return false;
}
@ -799,6 +819,7 @@ bool DivEngine::loadXM(unsigned char* file, size_t len) {
lastError="unknown packing type";
ds.unload();
delete[] file;
XM_FINISH;
return false;
}
@ -811,6 +832,7 @@ bool DivEngine::loadXM(unsigned char* file, size_t len) {
logE("too many rows! %d",totalRows);
lastError="too many rows";
delete[] file;
XM_FINISH;
return false;
}
@ -821,6 +843,7 @@ bool DivEngine::loadXM(unsigned char* file, size_t len) {
logE("premature end of file!");
lastError="incomplete file";
delete[] file;
XM_FINISH;
return false;
}
@ -880,7 +903,7 @@ bool DivEngine::loadXM(unsigned char* file, size_t len) {
p->data[j][2]=((int)ins)-1;
// default volume
if (lastNote[k]<96 && ins>0) {
p->data[j][3]=sampleVol[(ins-1)&255][noteMap[(ins-1)&255][lastNote[k]&127]];
p->data[j][3]=sampleVol[(((ins-1)&255)<<8)|(noteMap[(((ins-1)&255)<<7)|(lastNote[k]&127)])];
}
writePanning=true;
}
@ -1189,7 +1212,7 @@ bool DivEngine::loadXM(unsigned char* file, size_t len) {
if (writePanning && hasNote && note<96 && ins>0) {
p->data[j][effectCol[k]++]=0x80;
p->data[j][effectCol[k]++]=samplePan[(ins-1)&255][noteMap[(ins-1)&255][note&127]];
p->data[j][effectCol[k]++]=samplePan[(((ins-1)&255)<<8)|(noteMap[(((ins-1)&255)<<7)|(note&127)])];
}
}
@ -1305,6 +1328,7 @@ bool DivEngine::loadXM(unsigned char* file, size_t len) {
logE("premature end of file!");
lastError="incomplete file";
delete[] file;
XM_FINISH;
return false;
}
}
@ -1315,6 +1339,7 @@ bool DivEngine::loadXM(unsigned char* file, size_t len) {
lastError="too many samples";
ds.unload();
delete[] file;
XM_FINISH;
return false;
}
@ -1351,6 +1376,7 @@ bool DivEngine::loadXM(unsigned char* file, size_t len) {
//logE("invalid header!");
lastError="invalid header!";
}
XM_FINISH;
return success;
}