From 57cbdda39a7ac096bc90c611e034a0cb88461208 Mon Sep 17 00:00:00 2001 From: derselbst Date: Thu, 18 Jan 2018 14:07:10 +0100 Subject: [PATCH] avoid a buffer overrun when loading corrupt soundfonts addresses #327 --- src/sfloader/fluid_defsfont.c | 8 ++++---- src/utils/fluid_sys.h | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/sfloader/fluid_defsfont.c b/src/sfloader/fluid_defsfont.c index e607aa48..5b2e646e 100644 --- a/src/sfloader/fluid_defsfont.c +++ b/src/sfloader/fluid_defsfont.c @@ -3451,7 +3451,7 @@ fixup_sample (SFData * sf) int invalid_loops=FALSE; int invalid_loopstart; int invalid_loopend, loopend_end_mismatch; - unsigned int sdtachunk_size = sf->samplesize; + unsigned int total_samples = sf->samplesize / FLUID_MEMBER_SIZE(fluid_defsfont_t, sampledata[0]); p = sf->sample; while (p) @@ -3464,14 +3464,14 @@ fixup_sample (SFData * sf) * this is as it should be. however we cannot be sure whether any of sam.loopend or sam.end * is correct. hours of thinking through this have concluded, that it would be best practice * to mangle with loops as little as necessary by only making sure loopend is within - * sdtachunk_size. incorrect soundfont shall preferably fail loudly. */ - invalid_loopend = (sam->loopend > sdtachunk_size) || (sam->loopstart >= sam->loopend); + * total_samples. incorrect soundfont shall preferably fail loudly. */ + invalid_loopend = (sam->loopend > total_samples) || (sam->loopstart >= sam->loopend); loopend_end_mismatch = (sam->loopend > sam->end); /* if sample is not a ROM sample and end is over the sample data chunk or sam start is greater than 4 less than the end (at least 4 samples) */ - if ((!(sam->sampletype & FLUID_SAMPLETYPE_ROM) && sam->end > sdtachunk_size) + if ((!(sam->sampletype & FLUID_SAMPLETYPE_ROM) && sam->end > total_samples) || sam->start > (sam->end - 4)) { FLUID_LOG (FLUID_WARN, _("Sample '%s' start/end file positions are invalid," diff --git a/src/utils/fluid_sys.h b/src/utils/fluid_sys.h index 44ef3e02..c099c23e 100644 --- a/src/utils/fluid_sys.h +++ b/src/utils/fluid_sys.h @@ -64,6 +64,7 @@ void fluid_time_config(void); #define FLUID_POINTER_TO_INT GPOINTER_TO_INT #define FLUID_INT_TO_POINTER GINT_TO_POINTER #define FLUID_N_ELEMENTS(struct) (sizeof (struct) / sizeof (struct[0])) +#define FLUID_MEMBER_SIZE(struct, member) ( sizeof (((struct *)0)->member) ) #define FLUID_IS_BIG_ENDIAN (G_BYTE_ORDER == G_BIG_ENDIAN)