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:
parent
6227a0ef73
commit
47b9eb37a3
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue