Skip to content

Commit

Permalink
timidity: handle malloc() failures. revise library init.
Browse files Browse the repository at this point in the history
  • Loading branch information
sezero committed Mar 17, 2021
1 parent f3a2193 commit 7132377
Show file tree
Hide file tree
Showing 7 changed files with 169 additions and 77 deletions.
10 changes: 4 additions & 6 deletions src/timidity/common.c
Expand Up @@ -82,22 +82,20 @@ SDL_RWops *open_file(const char *name)
}

/* This adds a directory to the path list */
void add_to_pathlist(const char *s, size_t l)
int add_to_pathlist(const char *s, size_t l)
{
PathList *plp = SDL_malloc(sizeof(PathList));

if (plp == NULL)
return;

if (plp == NULL) return -2;
plp->path = SDL_malloc(l + 1);
if (plp->path == NULL) {
SDL_free (plp);
return;
return -2;
}
SDL_memcpy(plp->path, s, l);
plp->path[l] = 0;
plp->next = pathlist;
pathlist = plp;
return 0;
}

void free_pathlist(void)
Expand Down
2 changes: 1 addition & 1 deletion src/timidity/common.h
Expand Up @@ -9,5 +9,5 @@
*/

extern SDL_RWops *open_file(const char *name);
extern void add_to_pathlist(const char *s, size_t len);
extern int add_to_pathlist(const char *s, size_t len);
extern void free_pathlist(void);
92 changes: 53 additions & 39 deletions src/timidity/instrum.c
Expand Up @@ -27,12 +27,13 @@ static void free_instrument(Instrument *ip)
Sample *sp;
int i;
if (!ip) return;
for (i=0; i<ip->samples; i++)
{
if (ip->sample) {
for (i=0; i<ip->samples; i++) {
sp=&(ip->sample[i]);
SDL_free(sp->data);
}
SDL_free(ip->sample);
SDL_free(ip->sample);
}
SDL_free(ip);
}

Expand All @@ -43,7 +44,6 @@ static void free_bank(MidiSong *song, int dr, int b)
for (i=0; i<128; i++)
if (bank->instrument[i])
{
/* Not that this could ever happen, of course */
if (bank->instrument[i] != MAGIC_LOAD_INSTRUMENT)
free_instrument(bank->instrument[i]);
bank->instrument[i]=0;
Expand Down Expand Up @@ -142,7 +142,8 @@ static void reverse_data(Sint16 *sp, Sint32 ls, Sint32 le)
undefined.
TODO: do reverse loops right */
static Instrument *load_instrument(MidiSong *song, const char *name,
static void load_instrument(MidiSong *song, const char *name,
Instrument **out,
int percussion, int panning,
int amp, int note_to_use,
int strip_loop, int strip_envelope,
Expand All @@ -156,7 +157,8 @@ static Instrument *load_instrument(MidiSong *song, const char *name,
static char *patch_ext[] = PATCH_EXT_LIST;

(void)percussion; /* unused */
if (!name) return 0;
*out = NULL;
if (!name) return;

/* Open patch file */
if ((rw=open_file(name)) == NULL)
Expand All @@ -173,7 +175,7 @@ static Instrument *load_instrument(MidiSong *song, const char *name,
if (rw == NULL)
{
SNDDBG(("Instrument `%s' can't be found.\n", name));
return 0;
return;
}

SNDDBG(("Loading instrument %s\n", tmp));
Expand All @@ -187,28 +189,30 @@ static Instrument *load_instrument(MidiSong *song, const char *name,
differences are */
{
SNDDBG(("%s: not an instrument\n", name));
SDL_RWclose(rw);
return 0;
goto badpat;
}

if (tmp[82] != 1 && tmp[82] != 0) /* instruments. To some patch makers,
0 means 1 */
{
SNDDBG(("Can't handle patches with %d instruments\n", tmp[82]));
SDL_RWclose(rw);
return 0;
goto badpat;
}

if (tmp[151] != 1 && tmp[151] != 0) /* layers. What's a layer? */
{
SNDDBG(("Can't handle instruments with %d layers\n", tmp[151]));
SDL_RWclose(rw);
return 0;
goto badpat;
}

ip=SDL_malloc(sizeof(Instrument));
*out=SDL_malloc(sizeof(Instrument));
ip = *out;
if (!ip) goto nomem;

ip->samples = tmp[198];
ip->sample = SDL_malloc(sizeof(Sample) * ip->samples);
if (!ip->sample) goto nomem;

for (i=0; i<ip->samples; i++)
{
Uint8 fractions;
Expand All @@ -217,28 +221,19 @@ static Instrument *load_instrument(MidiSong *song, const char *name,
Uint8 tmpchar;

#define READ_CHAR(thing) \
if (1 != SDL_RWread(rw, &tmpchar, 1, 1)) goto fail; \
if (1 != SDL_RWread(rw, &tmpchar, 1, 1)) goto badread; \
thing = tmpchar;
#define READ_SHORT(thing) \
if (1 != SDL_RWread(rw, &tmpshort, 2, 1)) goto fail; \
if (1 != SDL_RWread(rw, &tmpshort, 2, 1)) goto badread; \
thing = SDL_SwapLE16(tmpshort);
#define READ_LONG(thing) \
if (1 != SDL_RWread(rw, &tmplong, 4, 1)) g oto fail; \
if (1 != SDL_RWread(rw, &tmplong, 4, 1)) goto badread; \
thing = (Sint32)SDL_SwapLE32((Uint32)tmplong);

SDL_RWseek(rw, 7, RW_SEEK_CUR); /* Skip the wave name */

if (1 != SDL_RWread(rw, &fractions, 1, 1))
{
fail:
SNDDBG(("Error reading sample %d\n", i));
for (j=0; j<i; j++)
SDL_free(ip->sample[j].data);
SDL_free(ip->sample);
SDL_free(ip);
SDL_RWclose(rw);
return 0;
}
goto badread;

sp=&(ip->sample[i]);

Expand All @@ -260,7 +255,8 @@ static Instrument *load_instrument(MidiSong *song, const char *name,
sp->panning=(Uint8)(panning & 0x7F);

/* envelope, tremolo, and vibrato */
if (18 != SDL_RWread(rw, tmp, 1, 18)) goto fail;
if (18 != SDL_RWread(rw, tmp, 1, 18))
goto badread;

if (!tmp[13] || !tmp[14])
{
Expand Down Expand Up @@ -370,8 +366,10 @@ static Instrument *load_instrument(MidiSong *song, const char *name,

/* Then read the sample data */
sp->data = (sample_t *) SDL_malloc(sp->data_length+4);
if (!sp->data) goto nomem;

if (1 != SDL_RWread(rw, sp->data, sp->data_length, 1))
goto fail;
goto badread;

if (!(sp->modes & MODES_16BIT)) /* convert to 16-bit data */
{
Expand All @@ -382,6 +380,7 @@ static Instrument *load_instrument(MidiSong *song, const char *name,
sp->loop_start *= 2;
sp->loop_end *= 2;
tmp16 = new16 = (Uint16 *) SDL_malloc(sp->data_length+4);
if (!new16) goto nomem;
while (k--)
*tmp16++ = (Uint16)(*cp++) << 8;
SDL_free(sp->data);
Expand Down Expand Up @@ -477,8 +476,10 @@ static Instrument *load_instrument(MidiSong *song, const char *name,

/* If this instrument will always be played on the same note,
and it's not looped, we can resample it now. */
if (sp->note_to_use && !(sp->modes & MODES_LOOPING))
if (sp->note_to_use && !(sp->modes & MODES_LOOPING)) {
pre_resample(song, sp);
if (song->oom) goto fail;
}

if (strip_tail==1)
{
Expand All @@ -489,7 +490,18 @@ static Instrument *load_instrument(MidiSong *song, const char *name,
}

SDL_RWclose(rw);
return ip;
return;

nomem:
song->oom=1;
goto fail;
badread:
SNDDBG(("Error reading sample %d\n", i));
fail:
free_instrument (ip);
badpat:
SDL_RWclose(rw);
*out = NULL;
}

static int fill_bank(MidiSong *song, int dr, int b)
Expand Down Expand Up @@ -531,9 +543,11 @@ static int fill_bank(MidiSong *song, int dr, int b)
bank->instrument[i] = 0;
errors++;
}
else if (!(bank->instrument[i] =
load_instrument(song,
else
{
load_instrument(song,
bank->tone[i].name,
&bank->instrument[i],
(dr) ? 1 : 0,
bank->tone[i].pan,
bank->tone[i].amp,
Expand All @@ -546,13 +560,14 @@ static int fill_bank(MidiSong *song, int dr, int b)
(bank->tone[i].strip_envelope != -1) ?
bank->tone[i].strip_envelope :
((dr) ? 1 : -1),
bank->tone[i].strip_tail )))
{
SNDDBG(("Couldn't load instrument %s (%s %d, program %d)\n",
bank->tone[i].strip_tail);
if (!bank->instrument[i]) {
SNDDBG(("Couldn't load instrument %s (%s %d, program %d)\n",
bank->tone[i].name,
(dr)? "drum set" : "tone bank", b, i));
errors++;
}
}
}
}
return errors;
Expand Down Expand Up @@ -585,10 +600,9 @@ void free_instruments(MidiSong *song)

int set_default_instrument(MidiSong *song, const char *name)
{
Instrument *ip;
if (!(ip=load_instrument(song, name, 0, -1, -1, -1, 0, 0, 0)))
load_instrument(song, name, &song->default_instrument, 0, -1, -1, -1, 0, 0, 0);
if (!song->default_instrument)
return -1;
song->default_instrument = ip;
song->default_program = SPECIAL_PROGRAM;
return 0;
}
16 changes: 16 additions & 0 deletions src/timidity/readmidi.c
Expand Up @@ -53,11 +53,17 @@ static int dumpstring(SDL_RWops *rw, Sint32 len, Uint8 type)
"Text event: ", "Text: ", "Copyright: ", "Track name: ",
"Instrument: ", "Lyric: ", "Marker: ", "Cue point: " };
signed char *s = SDL_malloc(len+1);
if (!s)
{
SDL_RWseek(song->rw, len, RW_SEEK_CUR);/* should I ? */
return -1;
}
if (len != (Sint32) SDL_RWread(rw, s, 1, len))
{
SDL_free(s);
return -1;
}

s[len]='\0';
while (len--)
{
Expand All @@ -72,6 +78,7 @@ static int dumpstring(SDL_RWops *rw, Sint32 len, Uint8 type)

#define MIDIEVENT(at,t,ch,pa,pb) \
newlist = (MidiEventList *) SDL_malloc(sizeof(MidiEventList));\
if (!newlist) {song->oom = 1; return NULL;} \
newlist->event.time = at; \
newlist->event.type = t; \
newlist->event.channel = ch; \
Expand Down Expand Up @@ -367,6 +374,11 @@ static MidiEvent *groom_list(MidiSong *song, Sint32 divisions,Sint32 *eventsp,

/* This may allocate a bit more than we need */
groomed_list=lp=SDL_malloc(sizeof(MidiEvent) * (song->event_count+1));
if (!groomed_list) {
song->oom=1;
free_midi_list(song);
return NULL;
}
meep=song->evlist;

our_event_count=0;
Expand Down Expand Up @@ -582,6 +594,10 @@ MidiEvent *read_midi_file(MidiSong *song, Sint32 *count, Sint32 *sp)

/* Put a do-nothing event first in the list for easier processing */
song->evlist=SDL_calloc(1, sizeof(MidiEventList));
if (!song->evlist) {
song->oom=1;
return NULL;
}
song->event_count++;

switch(format)
Expand Down
4 changes: 3 additions & 1 deletion src/timidity/resample.c
Expand Up @@ -553,8 +553,10 @@ void pre_resample(MidiSong *song, Sample *sp)
}

dest = newdata = (Sint16 *) SDL_malloc((newlen >> (FRACTION_BITS - 1)) + 2);
if (!dest)
if (!dest) {
song->oom = 1;
return;
}

if (--count)
*dest++ = src[0];
Expand Down

0 comments on commit 7132377

Please sign in to comment.