Merge 5d42ca4e59 into 1fe009caed
This commit is contained in:
commit
0a4dd57db3
|
|
@ -3195,6 +3195,14 @@ static bool log_mel_spectrogram(
|
|||
int64_t stage_1_pad = WHISPER_SAMPLE_RATE * 30;
|
||||
int64_t stage_2_pad = frame_size / 2;
|
||||
|
||||
// The reflective padding below reads samples[1 .. stage_2_pad], so an input
|
||||
// shorter than stage_2_pad + 1 would read past the end of the buffer.
|
||||
if (n_samples < stage_2_pad + 1) {
|
||||
WHISPER_LOG_ERROR("%s: audio too short: %d samples, need at least %d\n",
|
||||
__func__, n_samples, (int) stage_2_pad + 1);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Initialize a vector and copy data from C array to it.
|
||||
std::vector<float> samples_padded;
|
||||
samples_padded.resize(n_samples + stage_1_pad + stage_2_pad * 2);
|
||||
|
|
|
|||
|
|
@ -178,3 +178,13 @@ add_parakeet_transcription_test(
|
|||
tests/parakeet-expected-diffusion-output.txt
|
||||
0.95)
|
||||
|
||||
# log_mel_spectrogram out-of-bounds read on very short audio (issue #3923)
|
||||
set(MEL_OOB_TEST test-log-mel-oob)
|
||||
add_executable(${MEL_OOB_TEST} ${MEL_OOB_TEST}.cpp)
|
||||
target_include_directories(${MEL_OOB_TEST} PRIVATE ../include ../ggml/include ../examples)
|
||||
target_link_libraries(${MEL_OOB_TEST} PRIVATE common)
|
||||
target_compile_definitions(${MEL_OOB_TEST} PRIVATE
|
||||
WHISPER_MODEL_PATH="${PROJECT_SOURCE_DIR}/models/for-tests-ggml-tiny.bin")
|
||||
add_test(NAME ${MEL_OOB_TEST} COMMAND ${MEL_OOB_TEST})
|
||||
set_tests_properties(${MEL_OOB_TEST} PROPERTIES LABELS "unit;gh")
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,35 @@
|
|||
#include "whisper.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#ifdef NDEBUG
|
||||
#undef NDEBUG
|
||||
#endif
|
||||
#include <cassert>
|
||||
|
||||
// Regression test for the heap out-of-bounds read in log_mel_spectrogram().
|
||||
// Reflective padding reads samples[1 .. WHISPER_N_FFT/2], so an input shorter
|
||||
// than WHISPER_N_FFT/2 + 1 (201) samples used to read past the end of the
|
||||
// caller's buffer. Such inputs must now be rejected with a non-zero return.
|
||||
|
||||
int main() {
|
||||
std::string model_path = WHISPER_MODEL_PATH;
|
||||
|
||||
struct whisper_context_params cparams = whisper_context_default_params();
|
||||
struct whisper_context * ctx = whisper_init_from_file_with_params(model_path.c_str(), cparams);
|
||||
assert(ctx != nullptr);
|
||||
|
||||
std::vector<float> samples(256, 0.0f);
|
||||
|
||||
// Shorter than the reflective-pad window: must be rejected, not read OOB.
|
||||
assert(whisper_pcm_to_mel(ctx, samples.data(), 4, 1) != 0);
|
||||
assert(whisper_pcm_to_mel(ctx, samples.data(), 200, 1) != 0);
|
||||
|
||||
// Long enough to pad safely: must still succeed.
|
||||
assert(whisper_pcm_to_mel(ctx, samples.data(), 201, 1) == 0);
|
||||
|
||||
whisper_free(ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Loading…
Reference in New Issue