diff options
author | Howard Hinnant <hhinnant@apple.com> | 2010-10-29 14:10:30 +0000 |
---|---|---|
committer | Howard Hinnant <hhinnant@apple.com> | 2010-10-29 14:10:30 +0000 |
commit | 5ec18264291e75ac807adbcc448086b10a31b952 (patch) | |
tree | 3cb83e117e91fd8ec265b7f17d86e8937070784d | |
parent | 08b8c534f7cae66e4319c6c9aa4ae21f75c64e1c (diff) | |
download | bcm5719-llvm-5ec18264291e75ac807adbcc448086b10a31b952.tar.gz bcm5719-llvm-5ec18264291e75ac807adbcc448086b10a31b952.zip |
Secure __next_prime from overflowing
llvm-svn: 117650
-rw-r--r-- | libcxx/src/hash.cpp | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/libcxx/src/hash.cpp b/libcxx/src/hash.cpp index dd4e8e3e1ac..6bd9c3b0d7a 100644 --- a/libcxx/src/hash.cpp +++ b/libcxx/src/hash.cpp @@ -9,6 +9,7 @@ #include "__hash_table" #include "algorithm" +#include "stdexcept" _LIBCPP_BEGIN_NAMESPACE_STD @@ -143,6 +144,26 @@ const unsigned indices[] = // are fewer potential primes to search, and fewer potential primes to divide // against. +inline _LIBCPP_INLINE_VISIBILITY +void +__check_for_overflow(size_t N, integral_constant<size_t, 32>) +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + if (N > 0xFFFFFFFB) + throw overflow_error("__next_prime overflow"); +#endif +} + +inline _LIBCPP_INLINE_VISIBILITY +void +__check_for_overflow(size_t N, integral_constant<size_t, 64>) +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + if (N > 0xFFFFFFFFFFFFFFC5ull) + throw overflow_error("__next_prime overflow"); +#endif +} + size_t __next_prime(size_t n) { @@ -152,6 +173,9 @@ __next_prime(size_t n) if (n <= small_primes[N-1]) return *std::lower_bound(small_primes, small_primes + N, n); // Else n > largest small_primes + // Check for overflow + __check_for_overflow(n, integral_constant<size_t, + sizeof(n) * __CHAR_BIT__>()); // Start searching list of potential primes: L * k0 + indices[in] const size_t M = sizeof(indices) / sizeof(indices[0]); // Select first potential prime >= n |