void-packages/srcpkgs/timidity/patches/sffile-2gb.patch

385 lines
13 KiB
Diff

From bc8da3fb74d46e534fd966359f8aae51445d2b3d Mon Sep 17 00:00:00 2001
From: SATO Kentaro <kentaro@ranvis.com>
Date: Sun, 5 May 2024 15:34:18 +0900
Subject: [PATCH] Fix soundfont handling over 2GiB.
This alone doesn't enable handling of such files for
sizeof(long) == 4 environments.
---
timidity/sffile.c | 99 ++++++++++++++++++++++++++++------------------
timidity/sffile.h | 13 +++---
timidity/sndfont.c | 20 +++++-----
3 files changed, 78 insertions(+), 54 deletions(-)
diff --git a/timidity/sffile.c b/timidity/sffile.c
index ce2cbf8..0ae6996 100644
--- a/timidity/sffile.c
+++ b/timidity/sffile.c
@@ -130,16 +130,16 @@ static int READSTR(char *str, struct timidity_file *tf)
/*----------------------------------------------------------------*/
static int chunkid(char *id);
-static int process_list(int size, SFInfo *sf, struct timidity_file *fd);
-static int process_info(int size, SFInfo *sf, struct timidity_file *fd);
-static int process_sdta(int size, SFInfo *sf, struct timidity_file *fd);
-static int process_pdta(int size, SFInfo *sf, struct timidity_file *fd);
-static void load_sample_names(int size, SFInfo *sf, struct timidity_file *fd);
-static void load_preset_header(int size, SFInfo *sf, struct timidity_file *fd);
-static void load_inst_header(int size, SFInfo *sf, struct timidity_file *fd);
-static void load_bag(int size, SFBags *bagp, struct timidity_file *fd);
-static void load_gen(int size, SFBags *bagp, struct timidity_file *fd);
-static void load_sample_info(int size, SFInfo *sf, struct timidity_file *fd);
+static int process_list(uint32 size, SFInfo *sf, struct timidity_file *fd);
+static int process_info(uint32 size, SFInfo *sf, struct timidity_file *fd);
+static int process_sdta(uint32 size, SFInfo *sf, struct timidity_file *fd);
+static int process_pdta(uint32 size, SFInfo *sf, struct timidity_file *fd);
+static void load_sample_names(uint32 size, SFInfo *sf, struct timidity_file *fd);
+static void load_preset_header(uint32 size, SFInfo *sf, struct timidity_file *fd);
+static void load_inst_header(uint32 size, SFInfo *sf, struct timidity_file *fd);
+static void load_bag(uint32 size, SFBags *bagp, struct timidity_file *fd);
+static void load_gen(uint32 size, SFBags *bagp, struct timidity_file *fd);
+static void load_sample_info(uint32 size, SFInfo *sf, struct timidity_file *fd);
static void convert_layers(SFInfo *sf);
static void generate_layers(SFHeader *hdr, SFHeader *next, SFBags *bags);
static void free_layer(SFHeader *hdr);
@@ -175,6 +175,7 @@ enum {
int load_soundfont(SFInfo *sf, struct timidity_file *fd)
{
SFChunk chunk;
+ int result = 0;
sf->preset = NULL;
sf->sample = NULL;
@@ -202,19 +203,25 @@ int load_soundfont(SFInfo *sf, struct timidity_file *fd)
for (;;) {
if(READCHUNK(&chunk, fd) <= 0)
break;
- else if (chunkid(chunk.id) == LIST_ID) {
- if (process_list(chunk.size, sf, fd))
+ if (chunkid(chunk.id) == LIST_ID) {
+ if (process_list(chunk.size, sf, fd)) {
+ ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
+ "%s: *** could not process list", current_filename);
+ result = -1;
break;
+ }
} else {
ctl->cmsg(CMSG_WARNING, VERB_NORMAL,
- "%s: *** illegal id in level 0: %4.4s %4d",
- current_filename, chunk.id, chunk.size);
+ "%s: *** illegal id in level 0: %4.4s %4u",
+ current_filename, chunk.id, (unsigned)chunk.size);
FSKIP(chunk.size, fd);
}
}
- /* parse layer structure */
- convert_layers(sf);
+ if (!result) {
+ /* parse layer structure */
+ convert_layers(sf);
+ }
/* free private tables */
if (prbags.bag) free(prbags.bag);
@@ -227,7 +234,7 @@ int load_soundfont(SFInfo *sf, struct timidity_file *fd)
inbags.bag = NULL;
inbags.gen = NULL;
- return 0;
+ return result;
}
@@ -308,11 +315,18 @@ static int chunkid(char *id)
* process a list chunk
*================================================================*/
-static int process_list(int size, SFInfo *sf, struct timidity_file *fd)
+static int process_list(uint32 size, SFInfo *sf, struct timidity_file *fd)
{
SFChunk chunk;
/* read the following id string */
+ if (size < 4) {
+ ctl->cmsg(CMSG_WARNING, VERB_NORMAL,
+ "%s: *** illegal size in level 1: %4.4s %4u",
+ current_filename, chunk.id, size);
+ FSKIP(size, fd); /* skip it */
+ return 0;
+ }
READID(chunk.id, fd); size -= 4;
ctl->cmsg(CMSG_INFO, VERB_DEBUG, "%c%c%c%c:",
chunk.id[0], chunk.id[1], chunk.id[2], chunk.id[3]);
@@ -337,7 +351,7 @@ static int process_list(int size, SFInfo *sf, struct timidity_file *fd)
* process info list
*================================================================*/
-static int process_info(int size, SFInfo *sf, struct timidity_file *fd)
+static int process_info(uint32 size, SFInfo *sf, struct timidity_file *fd)
{
sf->infopos = tf_tell(fd);
sf->infosize = size;
@@ -347,9 +361,11 @@ static int process_info(int size, SFInfo *sf, struct timidity_file *fd)
SFChunk chunk;
/* read a sub chunk */
- if(READCHUNK(&chunk, fd) <= 0)
+ if (size < 8 || READCHUNK(&chunk, fd) <= 0)
return -1;
size -= 8;
+ if (chunk.size > size)
+ return -1;
ctl->cmsg(CMSG_INFO, VERB_DEBUG, " %c%c%c%c:",
chunk.id[0], chunk.id[1], chunk.id[2], chunk.id[3]);
@@ -406,15 +422,17 @@ static int process_info(int size, SFInfo *sf, struct timidity_file *fd)
* process sample data list
*================================================================*/
-static int process_sdta(int size, SFInfo *sf, struct timidity_file *fd)
+static int process_sdta(uint32 size, SFInfo *sf, struct timidity_file *fd)
{
while (size > 0) {
SFChunk chunk;
/* read a sub chunk */
- if(READCHUNK(&chunk, fd) <= 0)
+ if (size < 8 || READCHUNK(&chunk, fd) <= 0)
return -1;
size -= 8;
+ if (chunk.size > size)
+ return -1;
ctl->cmsg(CMSG_INFO, VERB_DEBUG, " %c%c%c%c:",
chunk.id[0], chunk.id[1], chunk.id[2], chunk.id[3]);
@@ -443,15 +461,17 @@ static int process_sdta(int size, SFInfo *sf, struct timidity_file *fd)
* process preset data list
*================================================================*/
-static int process_pdta(int size, SFInfo *sf, struct timidity_file *fd)
+static int process_pdta(uint32 size, SFInfo *sf, struct timidity_file *fd)
{
while (size > 0) {
SFChunk chunk;
/* read a subchunk */
- if(READCHUNK(&chunk, fd) <= 0)
+ if (size < 8 || READCHUNK(&chunk, fd) <= 0)
return -1;
size -= 8;
+ if (chunk.size > size)
+ return -1;
ctl->cmsg(CMSG_INFO, VERB_DEBUG, " %c%c%c%c:",
chunk.id[0], chunk.id[1], chunk.id[2], chunk.id[3]);
@@ -493,7 +513,7 @@ static int process_pdta(int size, SFInfo *sf, struct timidity_file *fd)
* store sample name list; sf1 only
*----------------------------------------------------------------*/
-static void load_sample_names(int size, SFInfo *sf, struct timidity_file *fd)
+static void load_sample_names(uint32 size, SFInfo *sf, struct timidity_file *fd)
{
int i, nsamples;
if (sf->version > 1) {
@@ -528,7 +548,7 @@ static void load_sample_names(int size, SFInfo *sf, struct timidity_file *fd)
* preset header list
*----------------------------------------------------------------*/
-static void load_preset_header(int size, SFInfo *sf, struct timidity_file *fd)
+static void load_preset_header(uint32 size, SFInfo *sf, struct timidity_file *fd)
{
int i;
@@ -560,7 +580,7 @@ static void load_preset_header(int size, SFInfo *sf, struct timidity_file *fd)
* instrument header list
*----------------------------------------------------------------*/
-static void load_inst_header(int size, SFInfo *sf, struct timidity_file *fd)
+static void load_inst_header(uint32 size, SFInfo *sf, struct timidity_file *fd)
{
int i;
@@ -584,9 +604,9 @@ static void load_inst_header(int size, SFInfo *sf, struct timidity_file *fd)
* load preset/instrument bag list on the private table
*----------------------------------------------------------------*/
-static void load_bag(int size, SFBags *bagp, struct timidity_file *fd)
+static void load_bag(uint32 size, SFBags *bagp, struct timidity_file *fd)
{
- int i;
+ uint32 i;
size /= 4;
bagp->bag = NEW(uint16, size);
@@ -602,9 +622,9 @@ static void load_bag(int size, SFBags *bagp, struct timidity_file *fd)
* load preset/instrument generator list on the private table
*----------------------------------------------------------------*/
-static void load_gen(int size, SFBags *bagp, struct timidity_file *fd)
+static void load_gen(uint32 size, SFBags *bagp, struct timidity_file *fd)
{
- int i;
+ uint32 i;
size /= 4;
bagp->gen = NEW(SFGenRec, size);
@@ -620,7 +640,7 @@ static void load_gen(int size, SFBags *bagp, struct timidity_file *fd)
* load sample info list
*----------------------------------------------------------------*/
-static void load_sample_info(int size, SFInfo *sf, struct timidity_file *fd)
+static void load_sample_info(uint32 size, SFInfo *sf, struct timidity_file *fd)
{
int i;
int in_rom;
@@ -652,12 +672,12 @@ static void load_sample_info(int size, SFInfo *sf, struct timidity_file *fd)
for (i = 0; i < sf->nsamples; i++) {
if (sf->version > 1) /* SF2 only */
READSTR(sf->sample[i].name, fd);
- READDW((uint32 *)&sf->sample[i].startsample, fd);
- READDW((uint32 *)&sf->sample[i].endsample, fd);
- READDW((uint32 *)&sf->sample[i].startloop, fd);
- READDW((uint32 *)&sf->sample[i].endloop, fd);
+ READDW(&sf->sample[i].startsample, fd);
+ READDW(&sf->sample[i].endsample, fd);
+ READDW(&sf->sample[i].startloop, fd);
+ READDW(&sf->sample[i].endloop, fd);
if (sf->version > 1) { /* SF2 only */
- READDW((uint32 *)&sf->sample[i].samplerate, fd);
+ READDW(&sf->sample[i].samplerate, fd);
READB(sf->sample[i].originalPitch, fd);
READB(sf->sample[i].pitchCorrection, fd);
READW(&sf->sample[i].samplelink, fd);
@@ -764,7 +784,7 @@ void correct_samples(SFInfo *sf)
{
int i;
SFSampleInfo *sp;
- int prev_end;
+ uint32 prev_end;
prev_end = 0;
for (sp = sf->sample, i = 0; i < sf->nsamples; i++, sp++) {
@@ -784,7 +804,8 @@ void correct_samples(SFInfo *sf)
if (!auto_add_blank && i != sf->nsamples-1)
sp->size = sp[1].startsample - sp->startsample;
if (sp->size < 0)
- sp->size = sp->endsample - sp->startsample + 48; }
+ sp->size = sp->endsample - sp->startsample + 48;
+ }
prev_end = sp->endsample;
/* calculate short-shot loop size */
diff --git a/timidity/sffile.h b/timidity/sffile.h
index 73075f3..348fd79 100644
--- a/timidity/sffile.h
+++ b/timidity/sffile.h
@@ -49,7 +49,7 @@
/* chunk record header */
typedef struct _SFChunk {
char id[4];
- int32 size;
+ uint32 size;
} SFChunk;
/* generator record */
@@ -88,10 +88,10 @@ typedef struct _SFInstHdr {
/* sample info record */
typedef struct _SFSampleInfo {
char name[20];
- int32 startsample, endsample;
- int32 startloop, endloop;
+ uint32 startsample, endsample;
+ uint32 startloop, endloop;
/* ver.2 additional info */
- int32 samplerate;
+ uint32 samplerate;
uint8 originalPitch;
int8 pitchCorrection;
uint16 samplelink;
@@ -114,10 +114,11 @@ typedef struct _SFInfo {
uint16 version, minorversion;
/* sample position (from origin) & total size (in bytes) */
long samplepos;
- int32 samplesize;
+ uint32 samplesize;
/* raw INFO chunk list */
- long infopos, infosize;
+ long infopos;
+ uint32 infosize;
/* preset headers */
int npresets;
diff --git a/timidity/sndfont.c b/timidity/sndfont.c
index 50e9694..9813b01 100644
--- a/timidity/sndfont.c
+++ b/timidity/sndfont.c
@@ -99,8 +99,8 @@ typedef struct _SFPatchRec {
typedef struct _SampleList {
Sample v;
struct _SampleList *next;
- int32 start;
- int32 len;
+ long start; /* file offset */
+ uint32 len;
int32 cutoff_freq;
int16 resonance;
int16 root, tune;
@@ -1147,7 +1147,7 @@ static int make_patch(SFInfo *sf, int pridx, LayerTable *tbl)
else
{
SampleList *cur, *prev;
- int32 start;
+ long start;
/* Insert sample */
start = sp->start;
@@ -1248,17 +1248,18 @@ static void set_envelope_parameters(SampleList *vp)
static void set_sample_info(SFInfo *sf, SampleList *vp, LayerTable *tbl)
{
SFSampleInfo *sp = &sf->sample[tbl->val[SF_sampleId]];
+ int32 len;
/* set sample position */
vp->start = (tbl->val[SF_startAddrsHi] << 15)
+ tbl->val[SF_startAddrs]
+ sp->startsample;
- vp->len = (tbl->val[SF_endAddrsHi] << 15)
+ len = (tbl->val[SF_endAddrsHi] << 15)
+ tbl->val[SF_endAddrs]
+ sp->endsample - vp->start;
vp->start = abs(vp->start);
- vp->len = abs(vp->len);
+ vp->len = abs(len);
/* set loop position */
vp->v.loop_start = (tbl->val[SF_startloopAddrsHi] << 15)
@@ -1452,8 +1453,10 @@ static void set_init_info(SFInfo *sf, SampleList *vp, LayerTable *tbl)
/* initial cutoff & resonance */
vp->cutoff_freq = 0;
- if((int)tbl->val[SF_initialFilterFc] < 0)
- tbl->set[SF_initialFilterFc] = tbl->val[SF_initialFilterFc] = 0;
+ if((int)tbl->val[SF_initialFilterFc] < 0) {
+ tbl->set[SF_initialFilterFc] = 0;
+ tbl->val[SF_initialFilterFc] = 0;
+ }
if(current_sfrec->def_cutoff_allowed && tbl->set[SF_initialFilterFc]
&& (int)tbl->val[SF_initialFilterFc] >= 1500 && (int)tbl->val[SF_initialFilterFc] <= 13500)
{
@@ -1477,8 +1480,7 @@ static void set_init_info(SFInfo *sf, SampleList *vp, LayerTable *tbl)
vp->resonance = 0;
if(current_sfrec->def_resonance_allowed && tbl->set[SF_initialFilterQ])
{
- val = (int)tbl->val[SF_initialFilterQ];
- vp->resonance = val;
+ vp->resonance = tbl->val[SF_initialFilterQ];
}
vp->v.resonance = vp->resonance;
--
2.45.2