Commit 4e0976c7 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

bandlimited resampler: fix heap overflow at high playback rate

We simply make sure the buffer is big enough, instead of trying (and
failing) to guess the biggest possible size.
parent d123196e
...@@ -71,7 +71,7 @@ static void FilterFloatUD( const float Imp[], const float ImpD[], uint16_t Nwing ...@@ -71,7 +71,7 @@ static void FilterFloatUD( const float Imp[], const float ImpD[], uint16_t Nwing
struct filter_sys_t struct filter_sys_t
{ {
int32_t *p_buf; /* this filter introduces a delay */ int32_t *p_buf; /* this filter introduces a delay */
int i_buf_size; size_t i_buf_size;
double d_old_factor; double d_old_factor;
int i_old_wing; int i_old_wing;
...@@ -360,9 +360,32 @@ static block_t *Resample( filter_t * p_filter, block_t * p_in_buf ) ...@@ -360,9 +360,32 @@ static block_t *Resample( filter_t * p_filter, block_t * p_in_buf )
p_sys->i_remainder -= p_filter->fmt_out.audio.i_rate; p_sys->i_remainder -= p_filter->fmt_out.audio.i_rate;
} }
/* Finalize aout buffer */
p_out_buf->i_nb_samples = i_out;
p_out_buf->i_pts = date_Get( &p_sys->end_date );
p_out_buf->i_length = date_Increment( &p_sys->end_date,
p_out_buf->i_nb_samples ) - p_out_buf->i_pts;
p_out_buf->i_buffer = p_out_buf->i_nb_samples *
i_nb_channels * sizeof(int32_t);
/* Buffer i_filter_wing * 2 samples for next time */ /* Buffer i_filter_wing * 2 samples for next time */
if( p_sys->i_old_wing ) if( p_sys->i_old_wing )
{ {
size_t newsize = p_sys->i_old_wing * 2
* p_filter->fmt_in.audio.i_bytes_per_frame;
if( newsize > p_sys->i_buf_size )
{
free( p_sys->p_buf );
p_sys->p_buf = malloc( newsize );
if( p_sys->p_buf != NULL )
p_sys->i_buf_size = newsize;
else
{
p_sys->i_buf_size = p_sys->i_old_wing = 0; /* oops! */
return p_out_buf;
}
}
memcpy( p_sys->p_buf, memcpy( p_sys->p_buf,
p_in_orig + (i_in_nb - 2 * p_sys->i_old_wing) * p_in_orig + (i_in_nb - 2 * p_sys->i_old_wing) *
i_nb_channels, (2 * p_sys->i_old_wing) * i_nb_channels, (2 * p_sys->i_old_wing) *
...@@ -374,14 +397,6 @@ static block_t *Resample( filter_t * p_filter, block_t * p_in_buf ) ...@@ -374,14 +397,6 @@ static block_t *Resample( filter_t * p_filter, block_t * p_in_buf )
i_out * p_filter->fmt_in.audio.i_bytes_per_frame ); i_out * p_filter->fmt_in.audio.i_bytes_per_frame );
#endif #endif
/* Finalize aout buffer */
p_out_buf->i_nb_samples = i_out;
p_out_buf->i_pts = date_Get( &p_sys->end_date );
p_out_buf->i_length = date_Increment( &p_sys->end_date,
p_out_buf->i_nb_samples ) - p_out_buf->i_pts;
p_out_buf->i_buffer = p_out_buf->i_nb_samples *
i_nb_channels * sizeof(int32_t);
return p_out_buf; return p_out_buf;
} }
...@@ -393,8 +408,6 @@ static int OpenFilter( vlc_object_t *p_this ) ...@@ -393,8 +408,6 @@ static int OpenFilter( vlc_object_t *p_this )
filter_t *p_filter = (filter_t *)p_this; filter_t *p_filter = (filter_t *)p_this;
filter_sys_t *p_sys; filter_sys_t *p_sys;
unsigned int i_out_rate = p_filter->fmt_out.audio.i_rate; unsigned int i_out_rate = p_filter->fmt_out.audio.i_rate;
double d_factor;
int i_filter_wing;
if( p_filter->fmt_in.audio.i_rate == p_filter->fmt_out.audio.i_rate || if( p_filter->fmt_in.audio.i_rate == p_filter->fmt_out.audio.i_rate ||
p_filter->fmt_in.i_codec != VLC_CODEC_FL32 ) p_filter->fmt_in.i_codec != VLC_CODEC_FL32 )
...@@ -414,20 +427,8 @@ static int OpenFilter( vlc_object_t *p_this ) ...@@ -414,20 +427,8 @@ static int OpenFilter( vlc_object_t *p_this )
if( p_sys == NULL ) if( p_sys == NULL )
return VLC_ENOMEM; return VLC_ENOMEM;
/* Calculate worst case for the length of the filter wing */ p_sys->p_buf = NULL;
d_factor = (double)i_out_rate / p_filter->fmt_in.audio.i_rate; p_sys->i_buf_size = 0;
i_filter_wing = ((SMALL_FILTER_NMULT + 1)/2.0)
* __MAX(1.0, 1.0/d_factor) + 10;
p_sys->i_buf_size = p_filter->fmt_in.audio.i_channels *
sizeof(int32_t) * 2 * i_filter_wing;
/* Allocate enough memory to buffer previous samples */
p_sys->p_buf = malloc( p_sys->i_buf_size );
if( p_sys->p_buf == NULL )
{
free( p_sys );
return VLC_ENOMEM;
}
p_sys->i_old_wing = 0; p_sys->i_old_wing = 0;
p_sys->b_first = true; p_sys->b_first = true;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment