mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-12-03 00:53:32 +01:00
Don't compute ((uint64_t)1)<<64 in round_to_power_of_2
This would be undefined behavior if it happened. (It can't actually happen as we're using round_to_power_of_2, since we would have to be trying to allocate exabytes of data.) While we're at it, fix the behavior of round_to_power_of_2(0), and document the function better. Fix for bug 6831.
This commit is contained in:
parent
582f2187a7
commit
37953497d8
4
changes/bug6831
Normal file
4
changes/bug6831
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
o Minor bugfixes:
|
||||||
|
- Fix round_to_power_of_2 so it doesn't invoke undefined behavior
|
||||||
|
with large values. This was untriggered, but nevertheless incorrect.
|
||||||
|
Fixes bug 6831; bugfix on 0.2.0.1-alpha.
|
@ -394,12 +394,24 @@ tor_log2(uint64_t u64)
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return the power of 2 closest to <b>u64</b>. */
|
/** Return the power of 2 in range [1,UINT64_MAX] closest to <b>u64</b>. If
|
||||||
|
* there are two powers of 2 equally close, round down. */
|
||||||
uint64_t
|
uint64_t
|
||||||
round_to_power_of_2(uint64_t u64)
|
round_to_power_of_2(uint64_t u64)
|
||||||
{
|
{
|
||||||
int lg2 = tor_log2(u64);
|
int lg2;
|
||||||
uint64_t low = U64_LITERAL(1) << lg2, high = U64_LITERAL(1) << (lg2+1);
|
uint64_t low;
|
||||||
|
uint64_t high;
|
||||||
|
if (u64 == 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
lg2 = tor_log2(u64);
|
||||||
|
low = U64_LITERAL(1) << lg2;
|
||||||
|
|
||||||
|
if (lg2 == 63)
|
||||||
|
return low;
|
||||||
|
|
||||||
|
high = U64_LITERAL(1) << (lg2+1);
|
||||||
if (high - u64 < u64 - low)
|
if (high - u64 < u64 - low)
|
||||||
return high;
|
return high;
|
||||||
else
|
else
|
||||||
|
@ -1109,6 +1109,7 @@ test_util_pow2(void)
|
|||||||
test_eq(tor_log2(64), 6);
|
test_eq(tor_log2(64), 6);
|
||||||
test_eq(tor_log2(65), 6);
|
test_eq(tor_log2(65), 6);
|
||||||
test_eq(tor_log2(63), 5);
|
test_eq(tor_log2(63), 5);
|
||||||
|
test_eq(tor_log2(0), 0); /* incorrect mathematically, but as specified */
|
||||||
test_eq(tor_log2(1), 0);
|
test_eq(tor_log2(1), 0);
|
||||||
test_eq(tor_log2(2), 1);
|
test_eq(tor_log2(2), 1);
|
||||||
test_eq(tor_log2(3), 1);
|
test_eq(tor_log2(3), 1);
|
||||||
@ -1123,7 +1124,17 @@ test_util_pow2(void)
|
|||||||
test_eq(round_to_power_of_2(130), 128);
|
test_eq(round_to_power_of_2(130), 128);
|
||||||
test_eq(round_to_power_of_2(U64_LITERAL(40000000000000000)),
|
test_eq(round_to_power_of_2(U64_LITERAL(40000000000000000)),
|
||||||
U64_LITERAL(1)<<55);
|
U64_LITERAL(1)<<55);
|
||||||
test_eq(round_to_power_of_2(0), 2);
|
test_eq(round_to_power_of_2(U64_LITERAL(0xffffffffffffffff)),
|
||||||
|
U64_LITERAL(1)<<63);
|
||||||
|
test_eq(round_to_power_of_2(0), 1);
|
||||||
|
test_eq(round_to_power_of_2(1), 1);
|
||||||
|
test_eq(round_to_power_of_2(2), 2);
|
||||||
|
test_eq(round_to_power_of_2(3), 2);
|
||||||
|
test_eq(round_to_power_of_2(4), 4);
|
||||||
|
test_eq(round_to_power_of_2(4), 4);
|
||||||
|
test_eq(round_to_power_of_2(5), 4);
|
||||||
|
test_eq(round_to_power_of_2(6), 4);
|
||||||
|
test_eq(round_to_power_of_2(7), 8);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
;
|
;
|
||||||
|
Loading…
Reference in New Issue
Block a user