mirror of
https://github.com/cookiengineer/audacity
synced 2025-11-08 22:23:59 +01:00
Bug1501: Fix bad_alloc crash for some effects with extreme inputs
This commit is contained in:
@@ -87,7 +87,16 @@ bool EffectEcho::ProcessInitialize(sampleCount WXUNUSED(totalLen), ChannelNames
|
||||
|
||||
histPos = 0;
|
||||
histLen = (sampleCount) (mSampleRate * delay);
|
||||
|
||||
// Guard against extreme delay values input by the user
|
||||
try {
|
||||
history = new float[histLen];
|
||||
}
|
||||
catch ( const std::bad_alloc& ) {
|
||||
wxMessageBox(_("Requested value exceeds memory capacity."));
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(history, 0, sizeof(float) * histLen);
|
||||
|
||||
return history != NULL;
|
||||
|
||||
@@ -223,26 +223,47 @@ void EffectPaulstretch::OnText(wxCommandEvent & WXUNUSED(evt))
|
||||
EnableApply(mUIParent->TransferDataFromWindow());
|
||||
}
|
||||
|
||||
int EffectPaulstretch::GetBufferSize(double rate)
|
||||
size_t EffectPaulstretch::GetBufferSize(double rate)
|
||||
{
|
||||
// Audacity's fft requires a power of 2
|
||||
float tmp = rate * mTime_resolution / 2.0;
|
||||
tmp = log(tmp) / log(2.0);
|
||||
tmp = pow(2.0, floor(tmp + 0.5));
|
||||
|
||||
return std::max<int>((int)tmp, 128);
|
||||
auto stmp = size_t(tmp);
|
||||
if (stmp != tmp)
|
||||
// overflow
|
||||
return 0;
|
||||
if (stmp >= 2 * stmp)
|
||||
// overflow
|
||||
return 0;
|
||||
|
||||
return std::max<size_t>(stmp, 128);
|
||||
}
|
||||
|
||||
bool EffectPaulstretch::ProcessOne(WaveTrack *track,double t0,double t1,int count)
|
||||
{
|
||||
int stretch_buf_size = GetBufferSize(track->GetRate());
|
||||
auto badAllocMessage = _("Requested value exceeds memory capacity.");
|
||||
|
||||
const auto stretch_buf_size = GetBufferSize(track->GetRate());
|
||||
if (stretch_buf_size == 0) {
|
||||
::wxMessageBox( badAllocMessage );
|
||||
return false;
|
||||
}
|
||||
|
||||
double amount = this->mAmount;
|
||||
|
||||
auto start = track->TimeToLongSamples(t0);
|
||||
auto end = track->TimeToLongSamples(t1);
|
||||
auto len = end - start;
|
||||
|
||||
int minDuration = stretch_buf_size * 2 + 1;
|
||||
const auto minDuration = stretch_buf_size * 2 + 1;
|
||||
if (minDuration < stretch_buf_size) {
|
||||
// overflow!
|
||||
::wxMessageBox( badAllocMessage );
|
||||
return false;
|
||||
}
|
||||
|
||||
if (len < minDuration){ //error because the selection is too short
|
||||
|
||||
float maxTimeRes = log(len) / log(2.0);
|
||||
@@ -290,6 +311,10 @@ bool EffectPaulstretch::ProcessOne(WaveTrack *track,double t0,double t1,int coun
|
||||
|
||||
auto outputTrack = mFactory->NewWaveTrack(track->GetSampleFormat(),track->GetRate());
|
||||
|
||||
try {
|
||||
// This encloses all the allocations of buffers, including those in
|
||||
// the constructor of the PaulStretch object
|
||||
|
||||
PaulStretch stretch(amount,stretch_buf_size,track->GetRate());
|
||||
|
||||
auto nget = stretch.get_nsamples_for_fill();
|
||||
@@ -353,6 +378,11 @@ bool EffectPaulstretch::ProcessOne(WaveTrack *track,double t0,double t1,int coun
|
||||
delete []buffer0;
|
||||
|
||||
return !cancelled;
|
||||
}
|
||||
catch ( const std::bad_alloc& ) {
|
||||
::wxMessageBox( badAllocMessage );
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/*************************************************************/
|
||||
|
||||
@@ -50,7 +50,7 @@ private:
|
||||
// EffectPaulstretch implementation
|
||||
|
||||
void OnText(wxCommandEvent & evt);
|
||||
int GetBufferSize(double rate);
|
||||
size_t GetBufferSize(double rate);
|
||||
|
||||
bool ProcessOne(WaveTrack *track, double t0, double t1, int count);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user