[libcxx-commits] [libcxx] [libc++] Fix possible out of range access in bitset (PR #121348)
Louis Dionne via libcxx-commits
libcxx-commits at lists.llvm.org
Wed May 21 10:07:25 PDT 2025
================
@@ -522,12 +571,40 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void __bitset<1, _Siz
template <size_t _Size>
inline _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long __bitset<1, _Size>::to_ulong() const {
- return __first_;
+ return __to_ulong(_BoolConstant<_Size <= sizeof(unsigned long) * CHAR_BIT>());
+}
+
+template <size_t _Size>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long __bitset<1, _Size>::__to_ulong(false_type) const {
+ if (auto __e = __make_iter(_Size); std::find(__make_iter(sizeof(unsigned long) * CHAR_BIT), __e, true) != __e)
+ __throw_overflow_error("__bitset<1, _Size>::__to_ulong overflow error");
+
+ return static_cast<unsigned long>(__first_);
+}
+
+template <size_t _Size>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long __bitset<1, _Size>::__to_ulong(true_type) const {
+ return static_cast<unsigned long>(__first_);
}
template <size_t _Size>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long __bitset<1, _Size>::to_ullong() const {
- return __first_;
+ return __to_ullong(_BoolConstant<_Size <= sizeof(unsigned long long) * CHAR_BIT>());
+}
+
+template <size_t _Size>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long
+__bitset<1, _Size>::__to_ullong(false_type) const {
+ if (auto __e = __make_iter(_Size); std::find(__make_iter(sizeof(unsigned long long) * CHAR_BIT), __e, true) != __e)
+ __throw_overflow_error("__bitset<1, _Size>::__to_ullong overflow error");
----------------
ldionne wrote:
```suggestion
// Handle the case where we have a bitset with leading zeros like 00000000000000101010101010110
if (auto __e = __make_iter(_Size); std::find(__make_iter(sizeof(unsigned long long) * CHAR_BIT), __e, true) == __e)
return static_cast<...>(...);
__throw_overflow_error("__bitset<1, _Size>::__to_ullong overflow error");
```
Flipping this around allows you to document what you're doing here, which is effectively a special case.
https://github.com/llvm/llvm-project/pull/121348
More information about the libcxx-commits
mailing list