From b06db05b78fd31fe6771bc431deb1481a71aa57e Mon Sep 17 00:00:00 2001
From: Ozkan Sezer <[EMAIL REDACTED]>
Date: Tue, 11 Aug 2026 07:02:04 +0300
Subject: [PATCH] readsbk.c: add a lot of error checking.
---
src/timidity/readsbk.c | 149 +++++++++++++++++++++++++----------------
1 file changed, 90 insertions(+), 59 deletions(-)
diff --git a/src/timidity/readsbk.c b/src/timidity/readsbk.c
index aa1246ff..80548005 100644
--- a/src/timidity/readsbk.c
+++ b/src/timidity/readsbk.c
@@ -76,13 +76,13 @@ static int READSTR(char *str, SDL_IOStream *io)
#define SKIPDW(io) SDL_SeekIO(io, 4, SDL_IO_SEEK_CUR);
static int getchunk(const char *id);
-static void process_chunk(int id, int s, SFInfo *sf, SDL_IOStream *io);
-static void load_sample_names(int size, SFInfo *sf, SDL_IOStream *io);
-static void load_preset_header(int size, SFInfo *sf, SDL_IOStream *io);
-static void load_inst_header(int size, SFInfo *sf, SDL_IOStream *io);
-static void load_bag(int size, SFInfo *sf, SDL_IOStream *io, int *totalp, Uint16 **bufp);
-static void load_gen(int size, SFInfo *sf, SDL_IOStream *io, int *totalp, tgenrec **bufp);
-static void load_sample_info(int size, SFInfo *sf, SDL_IOStream *io);
+static int process_chunk(int id, int s, SFInfo *sf, SDL_IOStream *io);
+static int load_sample_names(int size, SFInfo *sf, SDL_IOStream *io);
+static int load_preset_header(int size, SFInfo *sf, SDL_IOStream *io);
+static int load_inst_header(int size, SFInfo *sf, SDL_IOStream *io);
+static int load_bag(int size, SFInfo *sf, SDL_IOStream *io, int *totalp, Uint16 **bufp);
+static int load_gen(int size, SFInfo *sf, SDL_IOStream *io, int *totalp, tgenrec **bufp);
+static int load_sample_info(int size, SFInfo *sf, SDL_IOStream *io);
enum {
@@ -145,21 +145,22 @@ int load_sbk(SDL_IOStream *io, SFInfo *sf)
if (len < 32) /* better?? */
return -1;
- READCHUNK(&chunk, io);
+ if (READCHUNK(&chunk, io) < 0) return -1;
if (getchunk(chunk.id) != RIFF_ID) return -1;
if (chunk.size != len - 8) return -1;
- READID(chunk.id, io);
+ if (READID(chunk.id, io) < 0) return -1;
if (getchunk(chunk.id) != SFBK_ID) return -1;
sf->in_rom = 1;
while (SDL_GetIOStatus(io) != SDL_IO_STATUS_EOF) {
- READID(chunk.id, io);
+ if (READID(chunk.id, io) < 0) return -1;
switch (getchunk(chunk.id)) {
case LIST_ID:
- READDW(&chunk.size, io);
- READID(subchunk.id, io);
- process_chunk(getchunk(subchunk.id), chunk.size - 4, sf, io);
+ if (READDW(&chunk.size, io) < 0) return -1;
+ if (READID(subchunk.id, io) < 0) return -1;
+ if (process_chunk(getchunk(subchunk.id), chunk.size - 4, sf, io) < 0)
+ return -1;
break;
}
}
@@ -243,45 +244,52 @@ static int getchunk(const char *id)
}
-static void load_sample_names(int size, SFInfo *sf, SDL_IOStream *io)
+static int load_sample_names(int size, SFInfo *sf, SDL_IOStream *io)
{
int i;
sf->nrsamples = size / 20;
sf->samplenames = NEW(tsamplenames, sf->nrsamples);
+ if (!sf->samplenames) return -1;
for (i = 0; i < sf->nrsamples; i++) {
- READSTR(sf->samplenames[i].name, io);
+ if (READSTR(sf->samplenames[i].name, io) < 0)
+ return -1;
}
+ return 0;
}
-static void load_preset_header(int size, SFInfo *sf, SDL_IOStream *io)
+static int load_preset_header(int size, SFInfo *sf, SDL_IOStream *io)
{
int i;
sf->nrpresets = size / 38;
sf->presethdr = NEW(tpresethdr, sf->nrpresets);
+ if (!sf->presethdr) return -1;
for (i = 0; i < sf->nrpresets; i++) {
- READSTR(sf->presethdr[i].name, io);
- READW(&sf->presethdr[i].preset, io);
- READW(&sf->presethdr[i].bank, io);
- READW(&sf->presethdr[i].bagNdx, io);
+ if (READSTR(sf->presethdr[i].name, io) < 0) return -1;
+ if (READW(&sf->presethdr[i].preset, io) < 0) return -1;
+ if (READW(&sf->presethdr[i].bank, io) < 0) return -1;
+ if (READW(&sf->presethdr[i].bagNdx, io) < 0) return -1;
SKIPDW(io); /* lib */
SKIPDW(io); /* genre */
SKIPDW(io); /* morph */
}
+ return 0;
}
-static void load_inst_header(int size, SFInfo *sf, SDL_IOStream *io)
+static int load_inst_header(int size, SFInfo *sf, SDL_IOStream *io)
{
int i;
sf->nrinsts = size / 22;
sf->insthdr = NEW(tinsthdr, sf->nrinsts);
+ if (!sf->insthdr) return -1;
for (i = 0; i < sf->nrinsts; i++) {
- READSTR(sf->insthdr[i].name, io);
- READW(&sf->insthdr[i].bagNdx, io);
+ if (READSTR(sf->insthdr[i].name, io) < 0) return -1;
+ if (READW(&sf->insthdr[i].bagNdx, io) < 0) return -1;
}
+ return 0;
}
-static void load_bag(int size, SFInfo *sf, SDL_IOStream *io, int *totalp, Uint16 **bufp)
+static int load_bag(int size, SFInfo *sf, SDL_IOStream *io, int *totalp, Uint16 **bufp)
{
Uint16 *buf;
int i;
@@ -290,15 +298,18 @@ static void load_bag(int size, SFInfo *sf, SDL_IOStream *io, int *totalp, Uint16
debugval("bagsize", size);
size /= 4;
buf = NEW(Uint16, size);
+ if (!buf) return -1;
for (i = 0; i < size; i++) {
- READW(&buf[i], io);
+ if (READW(&buf[i],io) < 0)
+ return -1;
SKIPW(io); /* mod */
}
*totalp = size;
*bufp = buf;
+ return 0;
}
-static void load_gen(int size, SFInfo *sf, SDL_IOStream *io, int *totalp, tgenrec **bufp)
+static int load_gen(int size, SFInfo *sf, SDL_IOStream *io, int *totalp, tgenrec **bufp)
{
tgenrec *buf;
int i;
@@ -307,15 +318,17 @@ static void load_gen(int size, SFInfo *sf, SDL_IOStream *io, int *totalp, tgenre
debugval("gensize", size);
size /= 4;
buf = NEW(tgenrec, size);
+ if (!buf) return -1;
for (i = 0; i < size; i++) {
- READW((Uint16 *)&buf[i].oper, io);
- READW((Uint16 *)&buf[i].amount, io);
+ if (READW((Uint16 *)&buf[i].oper, io) < 0) return -1;
+ if (READW((Uint16 *)&buf[i].amount, io) < 0) return -1;
}
*totalp = size;
*bufp = buf;
+ return 0;
}
-static void load_sample_info(int size, SFInfo *sf, SDL_IOStream *io)
+static int load_sample_info(int size, SFInfo *sf, SDL_IOStream *io)
{
int i;
@@ -325,25 +338,31 @@ static void load_sample_info(int size, SFInfo *sf, SDL_IOStream *io)
sf->nrsamples = sf->nrinfos;
sf->sampleinfo = NEW(tsampleinfo, sf->nrinfos);
sf->samplenames = NEW(tsamplenames, sf->nrsamples);
+ if (!sf->sampleinfo || !sf->samplenames)
+ return -1;
}
else {
sf->nrinfos = size / 16;
sf->sampleinfo = NEW(tsampleinfo, sf->nrinfos);
+ if (!sf->sampleinfo)
+ return -1;
}
for (i = 0; i < sf->nrinfos; i++) {
- if (sf->version > 1)
- READSTR(sf->samplenames[i].name, io);
- READDW(&sf->sampleinfo[i].startsample, io);
- READDW(&sf->sampleinfo[i].endsample, io);
- READDW(&sf->sampleinfo[i].startloop, io);
- READDW(&sf->sampleinfo[i].endloop, io);
if (sf->version > 1) {
- READDW(&sf->sampleinfo[i].samplerate, io);
- READB(&sf->sampleinfo[i].originalPitch, io);
- READB(&sf->sampleinfo[i].pitchCorrection, io);
- READW(&sf->sampleinfo[i].samplelink, io);
- READW(&sf->sampleinfo[i].sampletype, io);
+ if (READSTR(sf->samplenames[i].name, io) < 0)
+ return -1;
+ }
+ if (READDW(&sf->sampleinfo[i].startsample, io) < 0) return -1;
+ if (READDW(&sf->sampleinfo[i].endsample, io) < 0) return -1;
+ if (READDW(&sf->sampleinfo[i].startloop, io) < 0) return -1;
+ if (READDW(&sf->sampleinfo[i].endloop, io) < 0) return -1;
+ if (sf->version > 1) {
+ if (READDW(&sf->sampleinfo[i].samplerate, io) < 0) return -1;
+ if (READB(&sf->sampleinfo[i].originalPitch, io) < 0) return -1;
+ if (READB(&sf->sampleinfo[i].pitchCorrection, io) < 0) return -1;
+ if (READW(&sf->sampleinfo[i].samplelink, io) < 0) return -1;
+ if (READW(&sf->sampleinfo[i].sampletype, io) < 0) return -1;
} else {
if (sf->sampleinfo[i].startsample == 0)
sf->in_rom = 0;
@@ -359,9 +378,10 @@ static void load_sample_info(int size, SFInfo *sf, SDL_IOStream *io)
sf->sampleinfo[i].sampletype = 1;
}
}
+ return 0;
}
-static void process_chunk(int id, int s, SFInfo *sf, SDL_IOStream *io)
+static int process_chunk(int id, int s, SFInfo *sf, SDL_IOStream *io)
{
int cid;
tchunk subchunk;
@@ -374,12 +394,13 @@ static void process_chunk(int id, int s, SFInfo *sf, SDL_IOStream *io)
while ((cid = getchunk(subchunk.id)) != LIST_ID) {
switch (cid) {
case IFIL_ID:
- READW(&sf->version, io);
- READW(&sf->minorversion, io);
+ if (READW(&sf->version, io) < 0) return -1;
+ if (READW(&sf->minorversion, io) < 0) return -1;
break;
/*
case INAM_ID:
sf->sf_name = (char *)SDL_malloc(subchunk.size + 1);
+ if (!sf->sf_name) return -1;
SDL_ReadIO(io, sf->sf_name, subchunk.size);
sf->sf_name[subchunk.size] = 0;
break;
@@ -390,7 +411,7 @@ static void process_chunk(int id, int s, SFInfo *sf, SDL_IOStream *io)
}
READCHUNK(&subchunk, io);
if (SDL_GetIOStatus(io) == SDL_IO_STATUS_EOF)
- return;
+ return 0;
}
SDL_SeekIO(io, -8, SDL_IO_SEEK_CUR); /* seek back */
break;
@@ -403,8 +424,10 @@ static void process_chunk(int id, int s, SFInfo *sf, SDL_IOStream *io)
if (sf->version > 1) {
SNDDBG(("**** version 2 has obsolete format??\n"));
SDL_SeekIO(io, subchunk.size, SDL_IO_SEEK_CUR);
- } else
- load_sample_names(subchunk.size, sf, io);
+ } else {
+ if (load_sample_names(subchunk.size, sf, io) < 0)
+ return -1;
+ }
break;
case SMPL_ID:
sf->samplepos = SDL_TellIO(io);
@@ -413,7 +436,7 @@ static void process_chunk(int id, int s, SFInfo *sf, SDL_IOStream *io)
}
READCHUNK(&subchunk, io);
if (SDL_GetIOStatus(io) == SDL_IO_STATUS_EOF)
- return;
+ return 0;
}
SDL_SeekIO(io, -8, SDL_IO_SEEK_CUR); /* seek back */
break;
@@ -423,12 +446,14 @@ static void process_chunk(int id, int s, SFInfo *sf, SDL_IOStream *io)
while ((cid = getchunk(subchunk.id)) != LIST_ID) {
switch (cid) {
case PHDR_ID:
- load_preset_header(subchunk.size, sf, io);
+ if (load_preset_header(subchunk.size, sf, io) < 0)
+ return -1;
break;
case PBAG_ID:
- load_bag(subchunk.size, sf, io,
- &sf->nrpbags, &sf->presetbag);
+ if (load_bag(subchunk.size, sf, io,
+ &sf->nrpbags, &sf->presetbag) < 0)
+ return -1;
break;
case PMOD_ID: /* ignored */
@@ -436,17 +461,20 @@ static void process_chunk(int id, int s, SFInfo *sf, SDL_IOStream *io)
break;
case PGEN_ID:
- load_gen(subchunk.size, sf, io,
- &sf->nrpgens, &sf->presetgen);
+ if (load_gen(subchunk.size, sf, io,
+ &sf->nrpgens, &sf->presetgen) < 0)
+ return -1;
break;
case INST_ID:
- load_inst_header(subchunk.size, sf, io);
+ if (load_inst_header(subchunk.size, sf, io) < 0)
+ return -1;
break;
case IBAG_ID:
- load_bag(subchunk.size, sf, io,
- &sf->nribags, &sf->instbag);
+ if (load_bag(subchunk.size, sf, io,
+ &sf->nribags, &sf->instbag) < 0)
+ return -1;
break;
case IMOD_ID: /* ingored */
@@ -454,12 +482,14 @@ static void process_chunk(int id, int s, SFInfo *sf, SDL_IOStream *io)
break;
case IGEN_ID:
- load_gen(subchunk.size, sf, io,
- &sf->nrigens, &sf->instgen);
+ if (load_gen(subchunk.size, sf, io,
+ &sf->nrigens, &sf->instgen) < 0)
+ return -1;
break;
case SHDR_ID:
- load_sample_info(subchunk.size, sf, io);
+ if (load_sample_info(subchunk.size, sf, io) < 0)
+ return -1;
break;
default:
@@ -470,11 +500,12 @@ static void process_chunk(int id, int s, SFInfo *sf, SDL_IOStream *io)
READCHUNK(&subchunk, io);
if (SDL_GetIOStatus(io) == SDL_IO_STATUS_EOF) {
debugid("file", "EOF");
- return;
+ return 0;
}
}
SDL_SeekIO(io, -8, SDL_IO_SEEK_CUR); /* rewind */
break;
}
+ return 0;
}