From 0694263b7533ba000d3d95a2936115b21b806a5d Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Thu, 12 Nov 2015 11:32:14 -0500 Subject: 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. --- src/common/util.c | 32 +++++++++++++++++++++----------- src/test/test_util.c | 8 ++++---- 2 files changed, 25 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/common/util.c b/src/common/util.c index cc7760bff8..63bd1cc6f3 100644 --- a/src/common/util.c +++ b/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 number, and x modulo - * divisor == 0. */ + * divisor == 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 number, and x modulo - * divisor == 0. */ + * divisor == 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 number, and x modulo - * divisor == 0. */ + * divisor == 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 - * number, and x modulo divisor == 0. */ + * number, and x modulo divisor == 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; diff --git a/src/test/test_util.c b/src/test/test_util.c index d23ce5f9a9..8ae5bb3105 100644 --- a/src/test/test_util.c +++ b/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: ; } -- cgit v1.2.3-54-g00ecf