utils: GCD is 0 if both parameters are 0, don't divide by zero
authorSebastian Dröge <sebastian.droege@collabora.co.uk>
Thu, 13 May 2010 06:00:08 +0000 (08:00 +0200)
committerSebastian Dröge <sebastian.droege@collabora.co.uk>
Thu, 13 May 2010 06:01:14 +0000 (08:01 +0200)
And turn overflow checks from assertions into simple checks to
return FALSE.

gst/gstutils.c

index 8c80b32..7fbb8f8 100644 (file)
@@ -3989,8 +3989,10 @@ gst_util_double_to_fraction (gdouble src, gint * dest_n, gint * dest_d)
 
   /* simplify */
   gcd = gst_util_greatest_common_divisor (N, D);
-  N /= gcd;
-  D /= gcd;
+  if (gcd) {
+    N /= gcd;
+    D /= gcd;
+  }
 
   /* set results */
   *dest_n = N;
@@ -4025,20 +4027,31 @@ gst_util_fraction_multiply (gint a_n, gint a_d, gint b_n, gint b_d,
   g_return_val_if_fail (b_d != 0, FALSE);
 
   gcd = gst_util_greatest_common_divisor (a_n, b_d);
-  a_n /= gcd;
-  b_d /= gcd;
+  if (gcd) {
+    a_n /= gcd;
+    b_d /= gcd;
+  }
+
   gcd = gst_util_greatest_common_divisor (a_d, b_n);
-  a_d /= gcd;
-  b_n /= gcd;
+  if (gcd) {
+    a_d /= gcd;
+    b_n /= gcd;
+  }
 
-  g_return_val_if_fail (a_n == 0 || G_MAXINT / ABS (a_n) >= ABS (b_n), FALSE);
-  g_return_val_if_fail (G_MAXINT / ABS (a_d) >= ABS (b_d), FALSE);
+  /* This would result in overflow */
+  if (a_n != 0 && G_MAXINT / ABS (a_n) < ABS (b_n))
+    return FALSE;
+  if (G_MAXINT / ABS (a_d) < ABS (b_d))
+    return FALSE;
 
   *res_n = a_n * b_n;
   *res_d = a_d * b_d;
+
   gcd = gst_util_greatest_common_divisor (*res_n, *res_d);
-  *res_n /= gcd;
-  *res_d /= gcd;
+  if (gcd) {
+    *res_n /= gcd;
+    *res_d /= gcd;
+  }
 
   return TRUE;
 }
@@ -4081,16 +4094,22 @@ gst_util_fraction_add (gint a_n, gint a_d, gint b_n, gint b_d, gint * res_n,
     return TRUE;
   }
 
-  g_return_val_if_fail (a_n == 0 || G_MAXINT / ABS (a_n) >= ABS (b_n), FALSE);
-  g_return_val_if_fail (G_MAXINT / ABS (a_d) >= ABS (b_d), FALSE);
-  g_return_val_if_fail (G_MAXINT / ABS (a_d) >= ABS (b_d), FALSE);
+  /* This would result in overflow */
+  if (G_MAXINT / ABS (a_n) < ABS (b_n))
+    return FALSE;
+  if (G_MAXINT / ABS (a_d) < ABS (b_d))
+    return FALSE;
+  if (G_MAXINT / ABS (a_d) < ABS (b_d))
+    return FALSE;
 
   *res_n = (a_n * b_d) + (a_d * b_n);
   *res_d = a_d * b_d;
 
   gcd = gst_util_greatest_common_divisor (*res_n, *res_d);
-  *res_n /= gcd;
-  *res_d /= gcd;
+  if (gcd) {
+    *res_n /= gcd;
+    *res_d /= gcd;
+  }
 
   return TRUE;
 }