examples : fix memory leak in read_audio_data (#3810)

This commit addresses a memory leak in the `read_audio_data` function
where it is currently possible that a call to `ma_decoder_init_file`
succeeds and the function returns early without calling
`ma_decoder_uninit`. A similar situation can occur with
`ma_decoder_init_memory`.

Refs: https://bugs.debian.org/1124796

Co-authored-by: Daniel Bevenius <daniel.bevenius@gmail.com>
This commit is contained in:
petterreinholdtsen 2026-05-18 12:16:39 +02:00 committed by GitHub
parent 6227a0ef73
commit 47b9eb37a3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 34 additions and 21 deletions

View File

@ -44,7 +44,18 @@ bool read_audio_data(const std::string & fname, std::vector<float>& pcmf32, std:
ma_result result;
ma_decoder_config decoder_config;
ma_decoder decoder;
struct decoder_guard {
ma_decoder decoder;
bool initialized = false;
ma_decoder * operator&() { return &decoder; }
~decoder_guard() {
if (initialized) {
ma_decoder_uninit(&decoder);
}
}
};
decoder_guard decoder{};
decoder_config = ma_decoder_config_init(ma_format_f32, stereo ? 2 : 1, WHISPER_SAMPLE_RATE);
@ -63,32 +74,36 @@ bool read_audio_data(const std::string & fname, std::vector<float>& pcmf32, std:
audio_data.insert(audio_data.end(), buf, buf + n);
}
if ((result = ma_decoder_init_memory(audio_data.data(), audio_data.size(), &decoder_config, &decoder)) != MA_SUCCESS) {
result = ma_decoder_init_memory(audio_data.data(), audio_data.size(), &decoder_config, &decoder);
if (result != MA_SUCCESS) {
fprintf(stderr, "Error: failed to open audio data from stdin (%s)\n", ma_result_description(result));
return false;
}
decoder.initialized = true;
fprintf(stderr, "%s: read %zu bytes from stdin\n", __func__, audio_data.size());
}
else if (((result = ma_decoder_init_file(fname.c_str(), &decoder_config, &decoder)) != MA_SUCCESS)) {
else {
result = ma_decoder_init_file(fname.c_str(), &decoder_config, &decoder);
if (result == MA_SUCCESS) {
decoder.initialized = true;
}
#if defined(WHISPER_FFMPEG)
if (ffmpeg_decode_audio(fname, audio_data) != 0) {
fprintf(stderr, "error: failed to ffmpeg decode '%s'\n", fname.c_str());
return false;
}
if ((result = ma_decoder_init_memory(audio_data.data(), audio_data.size(), &decoder_config, &decoder)) != MA_SUCCESS) {
fprintf(stderr, "error: failed to read audio data as wav (%s)\n", ma_result_description(result));
return false;
}
if (!decoder.initialized) {
if (ffmpeg_decode_audio(fname, audio_data) != 0) {
fprintf(stderr, "error: failed to ffmpeg decode '%s'\n", fname.c_str());
return false;
}
result = ma_decoder_init_memory(audio_data.data(), audio_data.size(), &decoder_config, &decoder);
if (result != MA_SUCCESS) {
fprintf(stderr, "error: failed to read audio data as wav (%s)\n", ma_result_description(result));
return false;
}
decoder.initialized = true;
}
#else
if ((result = ma_decoder_init_memory(fname.c_str(), fname.size(), &decoder_config, &decoder)) != MA_SUCCESS) {
fprintf(stderr, "error: failed to read audio data as wav (%s)\n", ma_result_description(result));
if (!decoder.initialized) {
fprintf(stderr, "error: failed to read audio data from (%s)\n", fname.c_str());
return false;
}
#endif
@ -128,8 +143,6 @@ bool read_audio_data(const std::string & fname, std::vector<float>& pcmf32, std:
}
}
ma_decoder_uninit(&decoder);
return true;
}