Procházet zdrojové kódy

Make round_to_next_multiple_of always round upwards.

Yes, even if it has to return a non-multiple.  This prevents us from
ever having a bug where we try to use it for allocation, and under-allocate.
Nick Mathewson před 8 roky
rodič
revize
0694263b75
2 změnil soubory, kde provedl 25 přidání a 15 odebrání
  1. 21 11
      src/common/util.c
  2. 4 4
      src/test/test_util.c

+ 21 - 11
src/common/util.c

@@ -487,48 +487,58 @@ round_to_power_of_2(uint64_t u64)
 }
 
 /** Return the lowest x such that x is at least <b>number</b>, and x modulo
- * <b>divisor</b> == 0. */
+ * <b>divisor</b> == 0.  If no such x can be expressed as an unsigned, return
+ * UINT_MAX */
 unsigned
 round_to_next_multiple_of(unsigned number, unsigned divisor)
 {
   tor_assert(divisor > 0);
-  if (UINT_MAX - divisor + 1 >= number)
-    number += divisor - 1;
+  if (UINT_MAX - divisor + 1 < number)
+    return UINT_MAX;
+  number += divisor - 1;
   number -= number % divisor;
   return number;
 }
 
 /** Return the lowest x such that x is at least <b>number</b>, and x modulo
- * <b>divisor</b> == 0. */
+ * <b>divisor</b> == 0. If no such x can be expressed as a uint32_t, return
+ * UINT32_MAX */
 uint32_t
 round_uint32_to_next_multiple_of(uint32_t number, uint32_t divisor)
 {
   tor_assert(divisor > 0);
-  if (UINT32_MAX - divisor + 1 >= number)
-    number += divisor - 1;
+  if (UINT32_MAX - divisor + 1 < number)
+    return UINT32_MAX;
+
+  number += divisor - 1;
   number -= number % divisor;
   return number;
 }
 
 /** Return the lowest x such that x is at least <b>number</b>, and x modulo
- * <b>divisor</b> == 0. */
+ * <b>divisor</b> == 0. If no such x can be expressed as a uint64_t, return
+ * UINT64_MAX */
 uint64_t
 round_uint64_to_next_multiple_of(uint64_t number, uint64_t divisor)
 {
   tor_assert(divisor > 0);
-  if (UINT64_MAX - divisor + 1 >= number)
-    number += divisor - 1;
+  if (UINT64_MAX - divisor + 1 < number)
+    return UINT64_MAX;
+  number += divisor - 1;
   number -= number % divisor;
   return number;
 }
 
 /** Return the lowest x in [INT64_MIN, INT64_MAX] such that x is at least
- * <b>number</b>, and x modulo <b>divisor</b> == 0. */
+ * <b>number</b>, and x modulo <b>divisor</b> == 0. If no such x can be
+ * expressed as an int64_t, return INT64_MAX */
 int64_t
 round_int64_to_next_multiple_of(int64_t number, int64_t divisor)
 {
   tor_assert(divisor > 0);
-  if (number >= 0 && INT64_MAX - divisor + 1 >= number)
+  if (INT64_MAX - divisor + 1 < number)
+    return INT64_MAX;
+  if (number >= 0)
     number += divisor - 1;
   number -= number % divisor;
   return number;

+ 4 - 4
src/test/test_util.c

@@ -4056,7 +4056,7 @@ test_util_round_to_next_multiple_of(void *arg)
   tt_u64_op(round_uint64_to_next_multiple_of(99,9), ==, 99);
 
   tt_u64_op(round_uint64_to_next_multiple_of(UINT64_MAX,2), ==,
-            UINT64_MAX-UINT64_MAX%2);
+            UINT64_MAX);
 
   tt_i64_op(round_int64_to_next_multiple_of(0,1), ==, 0);
   tt_i64_op(round_int64_to_next_multiple_of(0,7), ==, 0);
@@ -4071,7 +4071,7 @@ test_util_round_to_next_multiple_of(void *arg)
 
   tt_i64_op(round_int64_to_next_multiple_of(INT64_MIN,2), ==, INT64_MIN);
   tt_i64_op(round_int64_to_next_multiple_of(INT64_MAX,2), ==,
-                                            INT64_MAX-INT64_MAX%2);
+                                            INT64_MAX);
 
   tt_int_op(round_uint32_to_next_multiple_of(0,1), ==, 0);
   tt_int_op(round_uint32_to_next_multiple_of(0,7), ==, 0);
@@ -4081,7 +4081,7 @@ test_util_round_to_next_multiple_of(void *arg)
   tt_int_op(round_uint32_to_next_multiple_of(99,9), ==, 99);
 
   tt_int_op(round_uint32_to_next_multiple_of(UINT32_MAX,2), ==,
-            UINT32_MAX-UINT32_MAX%2);
+            UINT32_MAX);
 
   tt_uint_op(round_to_next_multiple_of(0,1), ==, 0);
   tt_uint_op(round_to_next_multiple_of(0,7), ==, 0);
@@ -4091,7 +4091,7 @@ test_util_round_to_next_multiple_of(void *arg)
   tt_uint_op(round_to_next_multiple_of(99,9), ==, 99);
 
   tt_uint_op(round_to_next_multiple_of(UINT_MAX,2), ==,
-            UINT_MAX-UINT_MAX%2);
+            UINT_MAX);
  done:
   ;
 }