Skip to content

Commit 1f0d545

Browse files
authored
[libc++] Fix wraparound issue with -fsanitize=integer in string operator>> (#106263)
Fixes #106261 rdar://133991190
1 parent c490658 commit 1f0d545

File tree

2 files changed

+13
-9
lines changed

2 files changed

+13
-9
lines changed

libcxx/include/__type_traits/make_unsigned.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,12 +86,10 @@ template <class _Tp>
8686
using make_unsigned_t = __make_unsigned_t<_Tp>;
8787
#endif
8888

89-
#ifndef _LIBCPP_CXX03_LANG
9089
template <class _Tp>
91-
_LIBCPP_HIDE_FROM_ABI constexpr __make_unsigned_t<_Tp> __to_unsigned_like(_Tp __x) noexcept {
90+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __make_unsigned_t<_Tp> __to_unsigned_like(_Tp __x) _NOEXCEPT {
9291
return static_cast<__make_unsigned_t<_Tp> >(__x);
9392
}
94-
#endif
9593

9694
template <class _Tp, class _Up>
9795
using __copy_unsigned_t = __conditional_t<is_unsigned<_Tp>::value, __make_unsigned_t<_Up>, _Up>;

libcxx/include/istream

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ template <class Stream, class T>
165165
#include <__type_traits/conjunction.h>
166166
#include <__type_traits/enable_if.h>
167167
#include <__type_traits/is_base_of.h>
168+
#include <__type_traits/make_unsigned.h>
168169
#include <__utility/declval.h>
169170
#include <__utility/forward.h>
170171
#include <bitset>
@@ -1211,12 +1212,17 @@ operator>>(basic_istream<_CharT, _Traits>& __is, basic_string<_CharT, _Traits, _
12111212
try {
12121213
#endif
12131214
__str.clear();
1214-
streamsize __n = __is.width();
1215-
if (__n <= 0)
1216-
__n = __str.max_size();
1217-
if (__n <= 0)
1218-
__n = numeric_limits<streamsize>::max();
1219-
streamsize __c = 0;
1215+
using _Size = typename basic_string<_CharT, _Traits, _Allocator>::size_type;
1216+
streamsize const __width = __is.width();
1217+
_Size const __max_size = __str.max_size();
1218+
_Size __n;
1219+
if (__width <= 0) {
1220+
__n = __max_size;
1221+
} else {
1222+
__n = std::__to_unsigned_like(__width) < __max_size ? static_cast<_Size>(__width) : __max_size;
1223+
}
1224+
1225+
_Size __c = 0;
12201226
const ctype<_CharT>& __ct = std::use_facet<ctype<_CharT> >(__is.getloc());
12211227
while (__c < __n) {
12221228
typename _Traits::int_type __i = __is.rdbuf()->sgetc();

0 commit comments

Comments
 (0)