From 408f6ae0245f5987553d9fa029e5b653f2a3d68f Mon Sep 17 00:00:00 2001
From: Ozkan Sezer <[EMAIL REDACTED]>
Date: Tue, 11 Aug 2026 07:02:28 +0300
Subject: [PATCH] sndfont.c: add a lot of error checking.
make init_soundfont() failures to fail midi loading
---
src/timidity/instrum.c | 2 +-
src/timidity/instrum.h | 2 ++
src/timidity/sndfont.c | 47 +++++++++++++++++++++++++++++++++++------
src/timidity/sndfont.h | 6 +++---
src/timidity/timidity.c | 12 +++++++----
5 files changed, 55 insertions(+), 14 deletions(-)
diff --git a/src/timidity/instrum.c b/src/timidity/instrum.c
index f6655229..6fff5b4d 100644
--- a/src/timidity/instrum.c
+++ b/src/timidity/instrum.c
@@ -22,7 +22,7 @@
#include "resample.h"
#include "tables.h"
-static void free_instrument(Instrument *ip)
+void free_instrument(Instrument *ip)
{
Sample *sp;
int i;
diff --git a/src/timidity/instrum.h b/src/timidity/instrum.h
index 0fa65051..012d8eba 100644
--- a/src/timidity/instrum.h
+++ b/src/timidity/instrum.h
@@ -29,9 +29,11 @@
#define load_missing_instruments TIMI_NAMESPACE(load_missing_instruments)
#define free_instruments TIMI_NAMESPACE(free_instruments)
#define set_default_instrument TIMI_NAMESPACE(set_default_instrument)
+#define free_instrument TIMI_NAMESPACE(free_instrument)
extern int load_missing_instruments(MidiSong *song);
extern void free_instruments(MidiSong *song);
+extern void free_instrument(Instrument *inst);
extern int set_default_instrument(MidiSong *song, const char *name);
#endif /* TIMIDITY_INSTRUM_H */
diff --git a/src/timidity/sndfont.c b/src/timidity/sndfont.c
index 84015c99..c9f00bd4 100644
--- a/src/timidity/sndfont.c
+++ b/src/timidity/sndfont.c
@@ -132,7 +132,7 @@ static const int cutoff_allowed = 0;
#endif
-void init_soundfont(MidiSong *song, const char *fname, int order)
+int init_soundfont(MidiSong *song, const char *fname, int order)
{
static SFInfo sfinfo;
int i;
@@ -141,7 +141,7 @@ void init_soundfont(MidiSong *song, const char *fname, int order)
if ((sfrec.io = timi_openfile(fname)) == NULL) {
SNDDBG(("can't open soundfont file %s\n", fname));
- return;
+ return -1;
}
sfrec.fname = SDL_strdup(fname);
if (load_sbk(sfrec.io, &sfinfo) < 0) {
@@ -151,7 +151,7 @@ void init_soundfont(MidiSong *song, const char *fname, int order)
SDL_free(sfrec.fname);
sfrec.fname = NULL;
free_sbk(&sfinfo);
- return;
+ return -1;
}
for (i = 0; i < sfinfo.nrpresets - 1; i++) {
@@ -162,12 +162,16 @@ void init_soundfont(MidiSong *song, const char *fname, int order)
if (bank == 128) {
if (!song->drumset[preset]) {
song->drumset[preset] = (ToneBank*)SDL_calloc(1, sizeof(ToneBank));
+ if (!song->drumset[preset]) goto fail;
song->drumset[preset]->tone = (ToneBankElement *) SDL_calloc(128, sizeof(ToneBankElement));
+ if (!song->drumset[preset]->tone) goto fail;
}
} else {
if (!song->tonebank[bank]) {
song->tonebank[bank] = (ToneBank*)SDL_calloc(1, sizeof(ToneBank));
+ if (!song->tonebank[bank]) goto fail;
song->tonebank[bank]->tone = (ToneBankElement *) SDL_calloc(128, sizeof(ToneBankElement));
+ if (!song->tonebank[bank]->tone) goto fail;
}
}
parse_preset(song, &sfrec, &sfinfo, i, order);
@@ -185,6 +189,11 @@ void init_soundfont(MidiSong *song, const char *fname, int order)
SDL_CloseIO(sfrec.io);
sfrec.io = NULL;
#endif
+ return 0;
+fail:
+ song->oom = 1;
+ return -1;
+
}
@@ -265,9 +274,11 @@ static Instrument *load_from_file(MidiSong *song, SFInsts *rec, InstList *ip)
SNDDBG(("Loading SF bank%d prg%d note%d\n", ip->bank, ip->preset, ip->keynote));
inst = (Instrument*)SDL_malloc(sizeof(Instrument));
+ if (!inst) goto nomem;
inst->type = INST_SF2;
inst->samples = ip->samples;
inst->sample = (Sample*) SDL_calloc(ip->samples, sizeof(Sample));
+ if (!inst->sample) goto nomem;
for (i = 0, sp = ip->slist; i < ip->samples && sp; i++, sp = sp->next) {
Sample *sample = inst->sample + i;
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
@@ -276,8 +287,10 @@ static Instrument *load_from_file(MidiSong *song, SFInsts *rec, InstList *ip)
#endif
SDL_memcpy(sample, &sp->v, sizeof(Sample));
sample->data = (sample_t*) SDL_malloc(sp->endsample + 6);
+ if (!sample->data) goto nomem;
SDL_SeekIO(rec->io, sp->startsample, SDL_IO_SEEK_SET);
- SDL_ReadIO(rec->io, sample->data, sp->endsample);
+ if (SDL_ReadIO(rec->io, sample->data, sp->endsample) != (size_t)sp->endsample)
+ goto badread;
/* initialize the 3 extra samples at the end (those +6 bytes) */
sample->data[sp->endsample/2] = sample->data[sp->endsample/2 + 1] =
sample->data[sp->endsample/2 + 2] = 0;
@@ -307,6 +320,12 @@ static Instrument *load_from_file(MidiSong *song, SFInsts *rec, InstList *ip)
pre_resample(song, sample);
}
return inst;
+
+nomem:
+ song->oom = 1;
+badread:
+ free_instrument (inst);
+ return NULL;
}
@@ -314,15 +333,17 @@ static Instrument *load_from_file(MidiSong *song, SFInsts *rec, InstList *ip)
* excluded samples
*----------------------------------------------------------------*/
-void exclude_soundfont(int bank, int preset, int keynote)
+int exclude_soundfont(int bank, int preset, int keynote)
{
SFExclude *rec;
rec = (SFExclude*)SDL_malloc(sizeof(SFExclude));
+ if (!rec) return -1;
rec->bank = bank;
rec->preset = preset;
rec->keynote = keynote;
rec->next = sfexclude;
sfexclude = rec;
+ return 0;
}
/* check the instrument is specified to be excluded */
@@ -354,16 +375,18 @@ static void free_exclude(void)
* ordered samples
*----------------------------------------------------------------*/
-void order_soundfont(int bank, int preset, int keynote, int order)
+int order_soundfont(int bank, int preset, int keynote, int order)
{
SFOrder *rec;
rec = (SFOrder*)SDL_malloc(sizeof(SFOrder));
+ if (!rec) return -1;
rec->bank = bank;
rec->preset = preset;
rec->keynote = keynote;
rec->order = order;
rec->next = sforder;
sforder = rec;
+ return 0;
}
/* check the instrument is specified to be ordered */
@@ -556,6 +579,10 @@ static void make_inst(MidiSong *song, SFInsts *rec, Layer *lay, SFInfo *sf, int
if (*namep == NULL) {
*namep = (char*) SDL_malloc(21);
+ if (!*namep) {
+ song->oom = 1;
+ return;
+ }
SDL_memcpy(*namep, sf->insthdr[in_idx].name, 20);
(*namep)[20] = 0;
}
@@ -568,6 +595,10 @@ static void make_inst(MidiSong *song, SFInsts *rec, Layer *lay, SFInfo *sf, int
}
if (ip == NULL) {
ip = (InstList*)SDL_malloc(sizeof(InstList));
+ if (!ip) {
+ song->oom = 1;
+ return;
+ }
ip->bank = bank;
ip->preset = preset;
ip->keynote = keynote;
@@ -580,6 +611,10 @@ static void make_inst(MidiSong *song, SFInsts *rec, Layer *lay, SFInfo *sf, int
/* add a sample */
sp = (SampleList*)SDL_malloc(sizeof(SampleList));
+ if (!sp) {
+ song->oom = 1;
+ return;
+ }
sp->next = ip->slist;
ip->slist = sp;
ip->samples++;
diff --git a/src/timidity/sndfont.h b/src/timidity/sndfont.h
index bfaa13bb..f3a1615b 100644
--- a/src/timidity/sndfont.h
+++ b/src/timidity/sndfont.h
@@ -16,10 +16,10 @@
#define exclude_soundfont TIMI_NAMESPACE(exclude_soundfont)
#define order_soundfont TIMI_NAMESPACE(order_soundfont)
-void init_soundfont(MidiSong *song, const char *fname, int order);
+int init_soundfont(MidiSong *song, const char *fname, int order);
void end_soundfont(void);
Instrument *load_soundfont(MidiSong *song, int order, int bank, int preset, int keynote);
-void exclude_soundfont(int bank, int preset, int keynote);
-void order_soundfont(int bank, int preset, int keynote, int order);
+int exclude_soundfont(int bank, int preset, int keynote);
+int order_soundfont(int bank, int preset, int keynote, int order);
#endif /* TIMIDITY_SNDFONT_H */
diff --git a/src/timidity/timidity.c b/src/timidity/timidity.c
index eec8a34c..a29ee70e 100644
--- a/src/timidity/timidity.c
+++ b/src/timidity/timidity.c
@@ -343,7 +343,8 @@ static int read_config_file(const char *name, int rcf_count)
bank = SDL_atoi(w[2]);
preset = (words >= 4)? SDL_atoi(w[3]) : -1;
keynote = (words >= 5)? SDL_atoi(w[4]) : -1;
- exclude_soundfont(bank, preset, keynote);
+ if (exclude_soundfont(bank, preset, keynote) < 0)
+ goto fail;
} else if (!SDL_strcmp(w[1], "order")) {
int order;
if (words < 4) {
@@ -354,7 +355,8 @@ static int read_config_file(const char *name, int rcf_count)
bank = SDL_atoi(w[3]);
preset = (words >= 5)? SDL_atoi(w[4]) : -1;
keynote = (words >= 6)? SDL_atoi(w[5]) : -1;
- order_soundfont(bank, preset, keynote, order);
+ if (order_soundfont(bank, preset, keynote, order) < 0)
+ goto fail;
}
}
else
@@ -674,8 +676,10 @@ static void do_song_load(SDL_IOStream *io, const SDL_AudioSpec *audio, MidiSong
song->default_instrument = NULL;
song->default_program = DEFAULT_PROGRAM;
- if (sf_file)
- init_soundfont(song, sf_file, sf_order);
+ if (sf_file) {
+ if (init_soundfont(song, sf_file, sf_order) < 0)
+ goto fail;
+ }
if (*def_instr_name)
set_default_instrument(song, def_instr_name);