diff options
| author | bors <bors@rust-lang.org> | 2013-09-16 19:35:50 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2013-09-16 19:35:50 -0700 |
| commit | d5e9033a0d380fefb5610c97ff1048c809251bba (patch) | |
| tree | 86710ef0b5db291229c77c13263b565a412269f3 /src/libstd/num | |
| parent | 2f96c22a21299cfe5860b0bb6fdd1af8ac500b11 (diff) | |
| parent | e211888407db32fcec53f4fa9eb84acdbdf59f87 (diff) | |
| download | rust-d5e9033a0d380fefb5610c97ff1048c809251bba.tar.gz rust-d5e9033a0d380fefb5610c97ff1048c809251bba.zip | |
auto merge of #9108 : blake2-ppc/rust/hazards-on-overflow, r=alexcrichton
Fix uint overflow bugs in std::{at_vec, vec, str}
Closes #8742
Fix issue #8742, which summarized is: unsafe code in vec and str did assume
that a reservation for `X + Y` elements always succeeded, and didn't overflow.
Introduce the method `Vec::reserve_additional(n)` to make it easy to check for
overflow in `Vec::push` and `Vec::push_all`.
In std::str, simplify and remove a lot of the unsafe code and use `push_str`
instead. With improvements to `.push_str` and the new function
`vec::bytes::push_bytes`, it looks like this change has either no or positive
impact on performance.
I believe there are many places still where `v.reserve(A + B)` still can overflow.
This by itself is not an issue unless followed by (unsafe) code that steps aside
boundary checks.
Diffstat (limited to 'src/libstd/num')
| -rw-r--r-- | src/libstd/num/uint.rs | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/src/libstd/num/uint.rs b/src/libstd/num/uint.rs index dfdd6cf72f7..38a4df270fc 100644 --- a/src/libstd/num/uint.rs +++ b/src/libstd/num/uint.rs @@ -101,7 +101,17 @@ pub fn next_power_of_two(n: uint) -> uint { let mut tmp: uint = n - 1u; let mut shift: uint = 1u; while shift <= halfbits { tmp |= tmp >> shift; shift <<= 1u; } - return tmp + 1u; + tmp + 1u +} + +/// Returns the smallest power of 2 greater than or equal to `n` +#[inline] +pub fn next_power_of_two_opt(n: uint) -> Option<uint> { + let halfbits: uint = sys::size_of::<uint>() * 4u; + let mut tmp: uint = n - 1u; + let mut shift: uint = 1u; + while shift <= halfbits { tmp |= tmp >> shift; shift <<= 1u; } + tmp.checked_add(&1) } #[cfg(target_word_size = "32")] |
