shithub: sox

Download patch

ref: ea3eb44fd59337c3ebe06264aa158a5df9e202eb
parent: a1fea160b4111bbd744941c1586c0b6e0311bc6f
author: Ulrich Klauer <ulrich@chirlu.de>
date: Sun Jan 13 04:26:25 EST 2013

rate: don't hang if more than 2^31 output samples

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).

--- a/src/rate.c
+++ b/src/rate.c
@@ -223,7 +223,7 @@
 
 typedef struct {
   double     factor;
-  size_t     samples_in, samples_out;
+  uint64_t   samples_in, samples_out;
   int        level, input_stage_num, output_stage_num;
   sox_bool   upsample;
   stage_t    * stages;
@@ -393,11 +393,12 @@
 static void rate_flush(rate_t * p)
 {
   fifo_t * fifo = &p->stages[p->output_stage_num].fifo;
-  size_t samples_out = p->samples_in / p->factor + .5;
-  size_t remaining = samples_out - p->samples_out;
+  uint64_t samples_out = p->samples_in / p->factor + .5;
+  size_t remaining = samples_out > p->samples_out ?
+      (size_t)(samples_out - p->samples_out) : 0;
   sample_t * buff = calloc(1024, sizeof(*buff));
 
-  if ((int)remaining > 0) {
+  if (remaining > 0) {
     while ((size_t)fifo_occupancy(fifo) < remaining) {
       rate_input(p, buff, (size_t) 1024);
       rate_process(p);