SDL_mixer: sndfont.c: add a lot of error checking.

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);