From e811c4be132be80ba145f9ea54d4254367ced270 Mon Sep 17 00:00:00 2001 From: derselbst Date: Fri, 27 Dec 2024 13:28:04 +0100 Subject: [PATCH] Fix a race condition when loading SF3 files containing multiple uncompressed samples --- src/sfloader/fluid_sffile.c | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/src/sfloader/fluid_sffile.c b/src/sfloader/fluid_sffile.c index 83594246d..21535c91c 100644 --- a/src/sfloader/fluid_sffile.c +++ b/src/sfloader/fluid_sffile.c @@ -669,6 +669,7 @@ static int process_info(SFData *sf, int size) sf->version.major = ver; READW(sf, ver); sf->version.minor = ver; + FLUID_LOG(FLUID_DBG, "SF Version: %hu.%hu", sf->version.major, sf->version.minor); if(sf->version.major < 2) { @@ -710,6 +711,7 @@ static int process_info(SFData *sf, int size) sf->romver.major = ver; READW(sf, ver); sf->romver.minor = ver; + FLUID_LOG(FLUID_DBG, "ROM Version: %hu.%hu", sf->version.major, sf->version.minor); } else if(chunkid(chunk.id) != UNKN_ID) { @@ -2219,21 +2221,23 @@ static int fluid_sffile_read_wav(SFData *sf, unsigned int start, unsigned int en goto error_exit; } + fluid_rec_mutex_lock(sf->mtx); + /* Load 16-bit sample data */ if(sf->fcbs->fseek(sf->sffd, sf->samplepos + (start * sizeof(short)), SEEK_SET) == FLUID_FAILED) { FLUID_LOG(FLUID_ERR, "Failed to seek to sample position"); - goto error_exit; + goto error_exit_unlock; } loaded_data = FLUID_ARRAY(short, num_samples); - if(loaded_data == NULL) { FLUID_LOG(FLUID_ERR, "Out of memory"); - goto error_exit; + goto error_exit_unlock; } + FLUID_LOG(FLUID_DBG, "ftell(): %llu, fread(): %ld bytes", sf->fcbs->ftell(sf->sffd), num_samples*sizeof(short)); if(sf->fcbs->fread(loaded_data, num_samples * sizeof(short), sf->sffd) == FLUID_FAILED) { #if FLUID_VERSION_CHECK(FLUIDSYNTH_VERSION_MAJOR, FLUIDSYNTH_VERSION_MINOR, FLUIDSYNTH_VERSION_MICRO) < FLUID_VERSION_CHECK(2,2,0) @@ -2245,9 +2249,11 @@ static int fluid_sffile_read_wav(SFData *sf, unsigned int start, unsigned int en } #endif FLUID_LOG(FLUID_ERR, "Failed to read sample data"); - goto error_exit; + goto error_exit_unlock; } + fluid_rec_mutex_unlock(sf->mtx); + /* If this machine is big endian, byte swap the 16 bit samples */ if(FLUID_IS_BIG_ENDIAN) { @@ -2272,37 +2278,44 @@ static int fluid_sffile_read_wav(SFData *sf, unsigned int start, unsigned int en goto error24_exit; } - if(sf->fcbs->fseek(sf->sffd, sf->sample24pos + start, SEEK_SET) == FLUID_FAILED) + loaded_data24 = FLUID_ARRAY(char, num_samples); + if(loaded_data24 == NULL) { - FLUID_LOG(FLUID_ERR, "Failed to seek position for 24-bit sample data in data file"); + FLUID_LOG(FLUID_ERR, "Out of memory reading 24-bit sample data"); goto error24_exit; } - loaded_data24 = FLUID_ARRAY(char, num_samples); + fluid_rec_mutex_lock(sf->mtx); - if(loaded_data24 == NULL) + if(sf->fcbs->fseek(sf->sffd, sf->sample24pos + start, SEEK_SET) == FLUID_FAILED) { - FLUID_LOG(FLUID_ERR, "Out of memory reading 24-bit sample data"); - goto error24_exit; + FLUID_LOG(FLUID_ERR, "Failed to seek position for 24-bit sample data in data file"); + goto error24_exit_unlock; } if(sf->fcbs->fread(loaded_data24, num_samples, sf->sffd) == FLUID_FAILED) { FLUID_LOG(FLUID_ERR, "Failed to read 24-bit sample data"); - goto error24_exit; + goto error24_exit_unlock; } + + fluid_rec_mutex_unlock(sf->mtx); } *data24 = loaded_data24; return num_samples; +error24_exit_unlock: + fluid_rec_mutex_unlock(sf->mtx); error24_exit: FLUID_LOG(FLUID_WARN, "Ignoring 24-bit sample data, sound quality might suffer"); FLUID_FREE(loaded_data24); *data24 = NULL; return num_samples; +error_exit_unlock: + fluid_rec_mutex_unlock(sf->mtx); error_exit: FLUID_FREE(loaded_data); FLUID_FREE(loaded_data24);