Skip to content

Commit

Permalink
Fix a race condition when loading SF3 files containing multiple uncom…
Browse files Browse the repository at this point in the history
…pressed samples
  • Loading branch information
derselbst committed Dec 27, 2024
1 parent 4579469 commit e811c4b
Showing 1 changed file with 24 additions and 11 deletions.
35 changes: 24 additions & 11 deletions src/sfloader/fluid_sffile.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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)
Expand All @@ -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)
{
Expand All @@ -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);
Expand Down

0 comments on commit e811c4b

Please sign in to comment.