Detect integer math overflow to avoid division crash
authorAri Johnson <ari@theari.com>
Mon, 22 Oct 2012 18:20:15 +0000 (14:20 -0400)
committerAri Johnson <ari@theari.com>
Mon, 22 Oct 2012 18:20:15 +0000 (14:20 -0400)
Fixes #273

game/txt/changes/0.73p3
src/funmath.c

index 5a428993971576738398fd58e9746a4e961dd9f7..2b625a02b3ccd498275621926119a4c9ad129ca8 100644 (file)
@@ -9,3 +9,4 @@ CobraMUSH Version 0.73p3
 
   Fixes:
     * Rename Idle_Times() to Unidle_Times(), fixes #259 [AEJ]
+    * Detect integer math overflow to avoid crash crash, fixes #273 [AEJ]
index a37167eb017715e0af2297648a1dd0a7c98e785b..574180a55e862aa0d369c06c763d1d03307d66cf 100644 (file)
@@ -1917,6 +1917,8 @@ MATH_FUNC(math_div)
 
   for (n = 1; n < nptr; n++) {
     int temp;
+    div_t q;
+
     if (!is_integer(ptr[n])) {
       safe_str(T(e_ints), buff, bp);
       return;
@@ -1928,17 +1930,13 @@ MATH_FUNC(math_div)
       return;
     }
 
-    if (divresult < 0) {
-      if (temp < 0)
-        divresult = -divresult / -temp;
-      else
-        divresult = -(-divresult / temp);
-    } else {
-      if (temp < 0)
-        divresult = -(divresult / -temp);
-      else
-        divresult = divresult / temp;
+    if (divresult == INT_MAX && temp == -1) {
+      safe_str(T("#-1 DOMAIN ERROR"), buff, bp);
+      return;
     }
+
+    q = div(divresult, temp);
+    divresult = q.quot;
   }
   safe_integer(divresult, buff, bp);
 }
@@ -1972,6 +1970,11 @@ MATH_FUNC(math_floordiv)
       return;
     }
 
+    if (divresult == INT_MIN && temp == -1) {
+      safe_str(T("#-1 DOMAIN ERROR"), buff, bp);
+      return;
+    }
+
     if (divresult < 0) {
       if (temp < 0)
         divresult = -divresult / -temp;
@@ -2051,6 +2054,11 @@ MATH_FUNC(math_modulo)
       return;
     }
 
+    if (divresult == INT_MIN && temp == -1) {
+      safe_str(T("#-1 DOMAIN ERROR"), buff, bp);
+      return;
+    }
+
     if (divresult < 0) {
       if (temp < 0)
         divresult = -(-divresult % -temp);
@@ -2084,6 +2092,8 @@ MATH_FUNC(math_remainder)
 
   for (n = 1; n < nptr; n++) {
     int temp;
+    div_t r;
+
     if (!is_integer(ptr[n])) {
       safe_str(T(e_ints), buff, bp);
       return;
@@ -2095,17 +2105,13 @@ MATH_FUNC(math_remainder)
       return;
     }
 
-    if (divresult < 0) {
-      if (temp < 0)
-        divresult = -(-divresult % -temp);
-      else
-        divresult = -(-divresult % temp);
-    } else {
-      if (temp < 0)
-        divresult = divresult % -temp;
-      else
-        divresult = divresult % temp;
+    if (divresult == INT_MIN && temp == -1) {
+      safe_str(T("#-1 DOMAIN ERROR"), buff, bp);
+      return;
     }
+
+    r = div(divresult, temp);
+    divresult = r.rem;
   }
   safe_integer(divresult, buff, bp);
 }