Skip to content

Commit

Permalink
src/src_sinc.c: Fix a buffer out-of-bounds read error
Browse files Browse the repository at this point in the history
The buffer out-of-bounds read that happens with the 'SRC_SINC_*' converters
when the `src_ratio` is dynamically decreased while processing.

This is a relatively naive fix for issue that seems to have an up to 3%
performance degradation with respect to the unfixed version. It may be
possible to come up with a better version of this fix that does not
degrade performance.

Closes: #5
  • Loading branch information
erikd committed Aug 25, 2019
1 parent 8c325e3 commit 1b3d5b1
Showing 1 changed file with 78 additions and 69 deletions.
147 changes: 78 additions & 69 deletions src/src_sinc.c
Original file line number Diff line number Diff line change
Expand Up @@ -295,12 +295,14 @@ calc_output_single (SINC_FILTER *filter, increment_t increment, increment_t star

left = 0.0 ;
do
{ fraction = fp_to_double (filter_index) ;
indx = fp_to_int (filter_index) ;
{ if (data_index >= 0) /* Avoid underflow access to filter->buffer. */
{ fraction = fp_to_double (filter_index) ;
indx = fp_to_int (filter_index) ;

icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ;
icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ;

left += icoeff * filter->buffer [data_index] ;
left += icoeff * filter->buffer [data_index] ;
} ;

filter_index -= increment ;
data_index = data_index + 1 ;
Expand Down Expand Up @@ -440,13 +442,15 @@ calc_output_stereo (SINC_FILTER *filter, increment_t increment, increment_t star

left [0] = left [1] = 0.0 ;
do
{ fraction = fp_to_double (filter_index) ;
indx = fp_to_int (filter_index) ;
{ if (data_index >= 0) /* Avoid underflow access to filter->buffer. */
{ fraction = fp_to_double (filter_index) ;
indx = fp_to_int (filter_index) ;

icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ;
icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ;

left [0] += icoeff * filter->buffer [data_index] ;
left [1] += icoeff * filter->buffer [data_index + 1] ;
left [0] += icoeff * filter->buffer [data_index] ;
left [1] += icoeff * filter->buffer [data_index + 1] ;
} ;

filter_index -= increment ;
data_index = data_index + 2 ;
Expand Down Expand Up @@ -587,15 +591,17 @@ calc_output_quad (SINC_FILTER *filter, increment_t increment, increment_t start_

left [0] = left [1] = left [2] = left [3] = 0.0 ;
do
{ fraction = fp_to_double (filter_index) ;
indx = fp_to_int (filter_index) ;
{ if (data_index >= 0) /* Avoid underflow access to filter->buffer. */
{ fraction = fp_to_double (filter_index) ;
indx = fp_to_int (filter_index) ;

icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ;
icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ;

left [0] += icoeff * filter->buffer [data_index] ;
left [1] += icoeff * filter->buffer [data_index + 1] ;
left [2] += icoeff * filter->buffer [data_index + 2] ;
left [3] += icoeff * filter->buffer [data_index + 3] ;
left [0] += icoeff * filter->buffer [data_index] ;
left [1] += icoeff * filter->buffer [data_index + 1] ;
left [2] += icoeff * filter->buffer [data_index + 2] ;
left [3] += icoeff * filter->buffer [data_index + 3] ;
} ;

filter_index -= increment ;
data_index = data_index + 4 ;
Expand Down Expand Up @@ -740,17 +746,19 @@ calc_output_hex (SINC_FILTER *filter, increment_t increment, increment_t start_f

left [0] = left [1] = left [2] = left [3] = left [4] = left [5] = 0.0 ;
do
{ fraction = fp_to_double (filter_index) ;
indx = fp_to_int (filter_index) ;

icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ;

left [0] += icoeff * filter->buffer [data_index] ;
left [1] += icoeff * filter->buffer [data_index + 1] ;
left [2] += icoeff * filter->buffer [data_index + 2] ;
left [3] += icoeff * filter->buffer [data_index + 3] ;
left [4] += icoeff * filter->buffer [data_index + 4] ;
left [5] += icoeff * filter->buffer [data_index + 5] ;
{ if (data_index >= 0) /* Avoid underflow access to filter->buffer. */
{ fraction = fp_to_double (filter_index) ;
indx = fp_to_int (filter_index) ;

icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ;

left [0] += icoeff * filter->buffer [data_index] ;
left [1] += icoeff * filter->buffer [data_index + 1] ;
left [2] += icoeff * filter->buffer [data_index + 2] ;
left [3] += icoeff * filter->buffer [data_index + 3] ;
left [4] += icoeff * filter->buffer [data_index + 4] ;
left [5] += icoeff * filter->buffer [data_index + 5] ;
} ;

filter_index -= increment ;
data_index = data_index + 6 ;
Expand Down Expand Up @@ -910,48 +918,49 @@ calc_output_multi (SINC_FILTER *filter, increment_t increment, increment_t start

icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ;

/*
** Duff's Device.
** See : http://en.wikipedia.org/wiki/Duff's_device
*/
ch = channels ;
do
{
switch (ch % 8)
{ default :
ch -- ;
left [ch] += icoeff * filter->buffer [data_index + ch] ;
/* Falls through. */
case 7 :
ch -- ;
left [ch] += icoeff * filter->buffer [data_index + ch] ;
/* Falls through. */
case 6 :
ch -- ;
left [ch] += icoeff * filter->buffer [data_index + ch] ;
/* Falls through. */
case 5 :
ch -- ;
left [ch] += icoeff * filter->buffer [data_index + ch] ;
/* Falls through. */
case 4 :
ch -- ;
left [ch] += icoeff * filter->buffer [data_index + ch] ;
/* Falls through. */
case 3 :
ch -- ;
left [ch] += icoeff * filter->buffer [data_index + ch] ;
/* Falls through. */
case 2 :
ch -- ;
left [ch] += icoeff * filter->buffer [data_index + ch] ;
/* Falls through. */
case 1 :
ch -- ;
left [ch] += icoeff * filter->buffer [data_index + ch] ;
} ;
}
while (ch > 0) ;
if (data_index >= 0) /* Avoid underflow access to filter->buffer. */
{ /*
** Duff's Device.
** See : http://en.wikipedia.org/wiki/Duff's_device
*/
ch = channels ;
do
{ switch (ch % 8)
{ default :
ch -- ;
left [ch] += icoeff * filter->buffer [data_index + ch] ;
/* Falls through. */
case 7 :
ch -- ;
left [ch] += icoeff * filter->buffer [data_index + ch] ;
/* Falls through. */
case 6 :
ch -- ;
left [ch] += icoeff * filter->buffer [data_index + ch] ;
/* Falls through. */
case 5 :
ch -- ;
left [ch] += icoeff * filter->buffer [data_index + ch] ;
/* Falls through. */
case 4 :
ch -- ;
left [ch] += icoeff * filter->buffer [data_index + ch] ;
/* Falls through. */
case 3 :
ch -- ;
left [ch] += icoeff * filter->buffer [data_index + ch] ;
/* Falls through. */
case 2 :
ch -- ;
left [ch] += icoeff * filter->buffer [data_index + ch] ;
/* Falls through. */
case 1 :
ch -- ;
left [ch] += icoeff * filter->buffer [data_index + ch] ;
} ;
}
while (ch > 0) ;
} ;

filter_index -= increment ;
data_index = data_index + channels ;
Expand Down

0 comments on commit 1b3d5b1

Please sign in to comment.