[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:23 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
----------------
ldionne wrote:

Can you make sure that we either already have a test for [this condition](http://eel.is/c++draft/bitset#members-40), or write one?

https://github.com/llvm/llvm-project/pull/121348


More information about the libcxx-commits mailing list