The rate effect used to hang in an endless loop (until memory exhaustion) when the number of output samples exceeded 2^31 (on "normal" platforms; depending on size and signedness of size_t and int), as in this example: sox -V -S -n -n trim 0 3:10:00 rate 192000 Use 64-bit numbers for counting samples, and don't subtract unsigned numbers without checking. Reported and analyzed by MrMod in tracker item 3592482. This same problem is already fixed in the post-14.4.1 branch (commit c20cfab; in conjunction with commit eb20581 for the 64-bit numbers).
Showing the changes to src (1 of 1 file). Show all
Unified · Split
| @@ -223,7 +223,7 @@ static void half_band_filter_init(rate_shared_t * p, unsigned which, · 222 unmodified lines | |||
| 223 | 223 | ||
| 224 | typedef struct { | 224 | typedef struct { |
| 225 | double factor; | 225 | double factor; |
| 226 | size_t samples_in, samples_out; | 226 | uint64_t samples_in, samples_out; |
| 227 | int level, input_stage_num, output_stage_num; | 227 | int level, input_stage_num, output_stage_num; |
| 228 | sox_bool upsample; | 228 | sox_bool upsample; |
| 229 | stage_t * stages; | 229 | stage_t * stages; |
| @@ -393,11 +393,12 @@ static sample_t const * rate_output(rate_t * p, sample_t * samples, size_t * n) · 163 unmodified lines | |||
| 393 | static void rate_flush(rate_t * p) | 393 | static void rate_flush(rate_t * p) |
| 394 | { | 394 | { |
| 395 | fifo_t * fifo = &p->stages[p->output_stage_num].fifo; | 395 | fifo_t * fifo = &p->stages[p->output_stage_num].fifo; |
| 396 | size_t samples_out = p->samples_in / p->factor + .5; | 396 | uint64_t samples_out = p->samples_in / p->factor + .5; |
| 397 | size_t remaining = samples_out - p->samples_out; | 397 | size_t remaining = samples_out > p->samples_out ? |
| 398 | (size_t)(samples_out - p->samples_out) : 0; | ||
| 398 | sample_t * buff = calloc(1024, sizeof(*buff)); | 399 | sample_t * buff = calloc(1024, sizeof(*buff)); |
| 399 | 400 | ||
| 400 | if ((int)remaining > 0) { | 401 | if (remaining > 0) { |
| 401 | while ((size_t)fifo_occupancy(fifo) < remaining) { | 402 | while ((size_t)fifo_occupancy(fifo) < remaining) { |
| 402 | rate_input(p, buff, (size_t) 1024); | 403 | rate_input(p, buff, (size_t) 1024); |
| 403 | rate_process(p); | 404 | rate_process(p); |