Skip to content

Commit ed6e7e2

Browse files
committed
Fix out of bound access in src_linear
Fix #208 about out of bount access in linear resampler. Also migrates to count the sumber of frames instead of the number of samples and remove some redundant member of the private state. Signed-off-by: Lionel Koenig Gélas <[email protected]>
1 parent e7c6d89 commit ed6e7e2

File tree

1 file changed

+35
-40
lines changed

1 file changed

+35
-40
lines changed

src/src_linear.c

Lines changed: 35 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,7 @@ static void linear_close (SRC_STATE *state) ;
3232

3333
typedef struct
3434
{ int linear_magic_marker ;
35-
bool dirty ;
36-
long in_count, in_used ;
37-
long out_count, out_gen ;
35+
bool initialized ;
3836
float *last_value ;
3937
} LINEAR_DATA ;
4038

@@ -54,7 +52,6 @@ static SRC_ERROR
5452
linear_vari_process (SRC_STATE *state, SRC_DATA *data)
5553
{ LINEAR_DATA *priv ;
5654
double src_ratio, input_index, rem ;
57-
int ch ;
5855

5956
if (data->input_frames <= 0)
6057
return SRC_ERR_NO_ERROR ;
@@ -64,16 +61,14 @@ linear_vari_process (SRC_STATE *state, SRC_DATA *data)
6461

6562
priv = (LINEAR_DATA*) state->private_data ;
6663

67-
if (!priv->dirty)
64+
if (!priv->initialized)
6865
{ /* If we have just been reset, set the last_value data. */
69-
for (ch = 0 ; ch < state->channels ; ch++)
66+
for (int ch = 0 ; ch < state->channels ; ch++)
7067
priv->last_value [ch] = data->data_in [ch] ;
71-
priv->dirty = true ;
68+
priv->initialized = true ;
7269
} ;
7370

74-
priv->in_count = data->input_frames * state->channels ;
75-
priv->out_count = data->output_frames * state->channels ;
76-
priv->in_used = priv->out_gen = 0 ;
71+
data->input_frames_used = data->output_frames_gen = 0 ;
7772

7873
src_ratio = state->last_ratio ;
7974

@@ -83,72 +78,72 @@ linear_vari_process (SRC_STATE *state, SRC_DATA *data)
8378
input_index = state->last_position ;
8479

8580
/* Calculate samples before first sample in input array. */
86-
while (input_index < 1.0 && priv->out_gen < priv->out_count)
81+
float* current_out = data->data_out;
82+
while (input_index < 1.0 && data->output_frames_gen < data->output_frames)
8783
{
88-
if (priv->in_used + state->channels * (1.0 + input_index) >= priv->in_count)
89-
break ;
84+
if (data->output_frames > 0 && fabs (state->last_ratio - data->src_ratio) > SRC_MIN_RATIO_DIFF)
85+
src_ratio = state->last_ratio + data->output_frames_gen * (data->src_ratio - state->last_ratio) / data->output_frames ;
9086

91-
if (priv->out_count > 0 && fabs (state->last_ratio - data->src_ratio) > SRC_MIN_RATIO_DIFF)
92-
src_ratio = state->last_ratio + priv->out_gen * (data->src_ratio - state->last_ratio) / priv->out_count ;
93-
94-
for (ch = 0 ; ch < state->channels ; ch++)
95-
{ data->data_out [priv->out_gen] = (float) (priv->last_value [ch] + input_index *
87+
for (int ch = 0 ; ch < state->channels ; ch++)
88+
{ *current_out++ = (float) (priv->last_value [ch] + input_index *
9689
((double) data->data_in [ch] - priv->last_value [ch])) ;
97-
priv->out_gen ++ ;
9890
} ;
91+
data->output_frames_gen ++ ;
9992

10093
/* Figure out the next index. */
10194
input_index += 1.0 / src_ratio ;
10295
} ;
10396

10497
rem = fmod_one (input_index) ;
105-
priv->in_used += state->channels * psf_lrint (input_index - rem) ;
98+
data->input_frames_used += psf_lrint (input_index - rem) ;
10699
input_index = rem ;
107100

108101
/* Main processing loop. */
109-
while (priv->out_gen < priv->out_count && priv->in_used + state->channels * input_index < priv->in_count)
102+
const float* current_in = data->data_in + data->input_frames_used * state->channels;
103+
while (data->output_frames_gen < data->output_frames && data->input_frames_used + input_index < data->input_frames)
110104
{
111-
if (priv->out_count > 0 && fabs (state->last_ratio - data->src_ratio) > SRC_MIN_RATIO_DIFF)
112-
src_ratio = state->last_ratio + priv->out_gen * (data->src_ratio - state->last_ratio) / priv->out_count ;
105+
if (data->output_frames > 0 && fabs (state->last_ratio - data->src_ratio) > SRC_MIN_RATIO_DIFF)
106+
src_ratio = state->last_ratio + data->output_frames_gen * (data->src_ratio - state->last_ratio) / data->output_frames ;
113107

114108
#if SRC_DEBUG
115-
if (priv->in_used < state->channels && input_index < 1.0)
109+
if (priv->in_used < 1 && input_index < 1.0)
116110
{ printf ("Whoops!!!! in_used : %ld channels : %d input_index : %f\n", priv->in_used, state->channels, input_index) ;
117111
exit (1) ;
118112
} ;
119113
#endif
120-
121-
for (ch = 0 ; ch < state->channels ; ch++)
122-
{ data->data_out [priv->out_gen] = (float) (data->data_in [priv->in_used - state->channels + ch] + input_index *
123-
((double) data->data_in [priv->in_used + ch] - data->data_in [priv->in_used - state->channels + ch])) ;
124-
priv->out_gen ++ ;
114+
const float* prev_in = current_in - state->channels;
115+
for (int ch = 0 ; ch < state->channels ; ch++)
116+
{ *current_out++ = (float) (prev_in[ch] + input_index *
117+
((double) current_in[ch] - prev_in[ch])) ;
125118
} ;
119+
data->output_frames_gen ++ ;
126120

127121
/* Figure out the next index. */
128122
input_index += 1.0 / src_ratio ;
129123
rem = fmod_one (input_index) ;
130124

131-
priv->in_used += state->channels * psf_lrint (input_index - rem) ;
125+
const int num_frame_used = psf_lrint (input_index - rem);
126+
current_in += num_frame_used * state->channels;
127+
data->input_frames_used += num_frame_used ;
132128
input_index = rem ;
133129
} ;
134130

135-
if (priv->in_used > priv->in_count)
136-
{ input_index += (priv->in_used - priv->in_count) / state->channels ;
137-
priv->in_used = priv->in_count ;
131+
if (data->input_frames_used > data->input_frames)
132+
{ input_index += (data->input_frames_used - data->input_frames) ;
133+
data->input_frames_used = data->input_frames ;
138134
} ;
139135

140136
state->last_position = input_index ;
141137

142-
if (priv->in_used > 0)
143-
for (ch = 0 ; ch < state->channels ; ch++)
144-
priv->last_value [ch] = data->data_in [priv->in_used - state->channels + ch] ;
138+
if (data->input_frames_used > 0) {
139+
const float *last_value = data->data_in + (data->input_frames_used - 1) * state->channels;
140+
for (int ch = 0 ; ch < state->channels ; ch++)
141+
priv->last_value [ch] = last_value[ch];
142+
}
145143

146144
/* Save current ratio rather then target ratio. */
147145
state->last_ratio = src_ratio ;
148146

149-
data->input_frames_used = priv->in_used / state->channels ;
150-
data->output_frames_gen = priv->out_gen / state->channels ;
151-
152147
return SRC_ERR_NO_ERROR ;
153148
} /* linear_vari_process */
154149

@@ -237,7 +232,7 @@ linear_reset (SRC_STATE *state)
237232
if (priv == NULL)
238233
return ;
239234

240-
priv->dirty = false ;
235+
priv->initialized = false ;
241236
memset (priv->last_value, 0, sizeof (priv->last_value [0]) * state->channels) ;
242237

243238
return ;

0 commit comments

Comments
 (0)