diff options
author | Nick Mathewson <nickm@torproject.org> | 2012-09-13 10:34:49 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2012-09-14 09:51:24 -0400 |
commit | 37953497d8689bdde65837b00f56bf8ff1e0e459 (patch) | |
tree | eba5ce37971b301dffc9fe788b2ab1d439717284 /src/common | |
parent | 582f2187a769ea723f6bf13bc91f7a4b3c861408 (diff) | |
download | tor-37953497d8689bdde65837b00f56bf8ff1e0e459.tar.gz tor-37953497d8689bdde65837b00f56bf8ff1e0e459.zip |
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.
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/util.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/src/common/util.c b/src/common/util.c index 84b31502e6..0e0dcb179c 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -394,12 +394,24 @@ tor_log2(uint64_t u64) 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 round_to_power_of_2(uint64_t u64) { - int lg2 = tor_log2(u64); - uint64_t low = U64_LITERAL(1) << lg2, high = U64_LITERAL(1) << (lg2+1); + int lg2; + 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) return high; else |