Fix tv_divide().
authorAndre Noll <maan@systemlinux.org>
Tue, 13 Nov 2007 19:13:02 +0000 (20:13 +0100)
committerAndre Noll <maan@systemlinux.org>
Tue, 13 Nov 2007 19:13:02 +0000 (20:13 +0100)
The old code contained an integer overflow which caused the mp3 audio
format handler to compute the chunk of large mp3 files incorrectly.

Moreover, the code was more complicated than necessary. So replace it
by a simple calculation which just transforms the given struct timeval
into its number of microseconds, does the division and transforms
the quotient back to a struct timeval.

Thanks to Gerrit Renker for pointing out the problem.

time.c

diff --git a/time.c b/time.c
index 83231c895020245d72cea40cd34cae03e9951a29..6672dca4215c3e04de75f576dabc2dfd7c95eb30 100644 (file)
--- a/time.c
+++ b/time.c
@@ -113,21 +113,10 @@ void tv_scale(const unsigned long mult, const struct timeval *tv,
 void tv_divide(const unsigned long divisor, const struct timeval *tv,
        struct timeval *result)
 {
-       long unsigned q;
+       uint64_t x = ((uint64_t)tv->tv_sec * 1000 * 1000 + tv->tv_usec) / divisor;
 
-       if (!divisor) {
-               PARA_EMERG_LOG("%s\n", "division by zero");
-               exit(EXIT_FAILURE);
-       }
-       q = tv->tv_usec / divisor;
-       result->tv_sec = tv->tv_sec / divisor;
-       result->tv_usec = (tv->tv_sec - result->tv_sec * divisor)
-               * 1000 * 1000 / divisor;
-       if (result->tv_usec + q >= 1000 * 1000) {
-               result->tv_sec++;
-               result->tv_usec = 1000 * 1000 - result->tv_usec - q;
-       } else
-               result->tv_usec += q;
+       result->tv_sec = x / 1000 / 1000;
+       result->tv_usec = x % (1000 * 1000);
 }
 
 /**