Skip to content

Commit bed1a5b

Browse files
authored
[libc++][hardening] Categorize all ryu assertions as internal (#71853)
These assertions can only be triggered by bugs in the algorithm's implementation; all user inputs should be handled gracefully.
1 parent f544533 commit bed1a5b

File tree

5 files changed

+28
-28
lines changed

5 files changed

+28
-28
lines changed

libcxx/src/include/ryu/common.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
5252
// Function precondition: __v is not a 10-digit number.
5353
// (f2s: 9 digits are sufficient for round-tripping.)
5454
// (d2fixed: We print 9-digit blocks.)
55-
_LIBCPP_ASSERT_UNCATEGORIZED(__v < 1000000000, "");
55+
_LIBCPP_ASSERT_INTERNAL(__v < 1000000000, "");
5656
if (__v >= 100000000) { return 9; }
5757
if (__v >= 10000000) { return 8; }
5858
if (__v >= 1000000) { return 7; }
@@ -69,24 +69,24 @@ _LIBCPP_BEGIN_NAMESPACE_STD
6969
// This approximation works up to the point that the multiplication overflows at __e = 3529.
7070
// If the multiplication were done in 64 bits, it would fail at 5^4004 which is just greater
7171
// than 2^9297.
72-
_LIBCPP_ASSERT_UNCATEGORIZED(__e >= 0, "");
73-
_LIBCPP_ASSERT_UNCATEGORIZED(__e <= 3528, "");
72+
_LIBCPP_ASSERT_INTERNAL(__e >= 0, "");
73+
_LIBCPP_ASSERT_INTERNAL(__e <= 3528, "");
7474
return static_cast<int32_t>(((static_cast<uint32_t>(__e) * 1217359) >> 19) + 1);
7575
}
7676

7777
// Returns floor(log_10(2^__e)).
7878
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __log10Pow2(const int32_t __e) {
7979
// The first value this approximation fails for is 2^1651 which is just greater than 10^297.
80-
_LIBCPP_ASSERT_UNCATEGORIZED(__e >= 0, "");
81-
_LIBCPP_ASSERT_UNCATEGORIZED(__e <= 1650, "");
80+
_LIBCPP_ASSERT_INTERNAL(__e >= 0, "");
81+
_LIBCPP_ASSERT_INTERNAL(__e <= 1650, "");
8282
return (static_cast<uint32_t>(__e) * 78913) >> 18;
8383
}
8484

8585
// Returns floor(log_10(5^__e)).
8686
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __log10Pow5(const int32_t __e) {
8787
// The first value this approximation fails for is 5^2621 which is just greater than 10^1832.
88-
_LIBCPP_ASSERT_UNCATEGORIZED(__e >= 0, "");
89-
_LIBCPP_ASSERT_UNCATEGORIZED(__e <= 2620, "");
88+
_LIBCPP_ASSERT_INTERNAL(__e >= 0, "");
89+
_LIBCPP_ASSERT_INTERNAL(__e <= 2620, "");
9090
return (static_cast<uint32_t>(__e) * 732923) >> 20;
9191
}
9292

libcxx/src/include/ryu/d2s_intrinsics.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
6363
// (The shift value is in the range [49, 58].)
6464
// Check this here in case a future change requires larger shift
6565
// values. In this case this function needs to be adjusted.
66-
_LIBCPP_ASSERT_UNCATEGORIZED(__dist < 64, "");
66+
_LIBCPP_ASSERT_INTERNAL(__dist < 64, "");
6767
return __shiftright128(__lo, __hi, static_cast<unsigned char>(__dist));
6868
}
6969

@@ -85,7 +85,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
8585
// (The shift value is in the range [49, 58].)
8686
// Check this here in case a future change requires larger shift
8787
// values. In this case this function needs to be adjusted.
88-
_LIBCPP_ASSERT_UNCATEGORIZED(__dist < 64, "");
88+
_LIBCPP_ASSERT_INTERNAL(__dist < 64, "");
8989
auto __temp = __lo | ((unsigned __int128)__hi << 64);
9090
// For x64 128-bit shfits using the `shrd` instruction and two 64-bit
9191
// registers, the shift value is modulo 64. Thus the `& 63` is free.
@@ -126,13 +126,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD
126126

127127
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint64_t __ryu_shiftright128(const uint64_t __lo, const uint64_t __hi, const uint32_t __dist) {
128128
// We don't need to handle the case __dist >= 64 here (see above).
129-
_LIBCPP_ASSERT_UNCATEGORIZED(__dist < 64, "");
129+
_LIBCPP_ASSERT_INTERNAL(__dist < 64, "");
130130
#ifdef _LIBCPP_64_BIT
131-
_LIBCPP_ASSERT_UNCATEGORIZED(__dist > 0, "");
131+
_LIBCPP_ASSERT_INTERNAL(__dist > 0, "");
132132
return (__hi << (64 - __dist)) | (__lo >> __dist);
133133
#else // ^^^ 64-bit ^^^ / vvv 32-bit vvv
134134
// Avoid a 64-bit shift by taking advantage of the range of shift values.
135-
_LIBCPP_ASSERT_UNCATEGORIZED(__dist >= 32, "");
135+
_LIBCPP_ASSERT_INTERNAL(__dist >= 32, "");
136136
return (__hi << (64 - __dist)) | (static_cast<uint32_t>(__lo >> 32) >> (__dist - 32));
137137
#endif // ^^^ 32-bit ^^^
138138
}
@@ -227,7 +227,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
227227
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __pow5Factor(uint64_t __value) {
228228
uint32_t __count = 0;
229229
for (;;) {
230-
_LIBCPP_ASSERT_UNCATEGORIZED(__value != 0, "");
230+
_LIBCPP_ASSERT_INTERNAL(__value != 0, "");
231231
const uint64_t __q = __div5(__value);
232232
const uint32_t __r = static_cast<uint32_t>(__value) - 5 * static_cast<uint32_t>(__q);
233233
if (__r != 0) {
@@ -247,8 +247,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD
247247

248248
// Returns true if __value is divisible by 2^__p.
249249
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline bool __multipleOfPowerOf2(const uint64_t __value, const uint32_t __p) {
250-
_LIBCPP_ASSERT_UNCATEGORIZED(__value != 0, "");
251-
_LIBCPP_ASSERT_UNCATEGORIZED(__p < 64, "");
250+
_LIBCPP_ASSERT_INTERNAL(__value != 0, "");
251+
_LIBCPP_ASSERT_INTERNAL(__p < 64, "");
252252
// __builtin_ctzll doesn't appear to be faster here.
253253
return (__value & ((1ull << __p) - 1)) == 0;
254254
}

libcxx/src/ryu/d2fixed.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,8 @@ inline constexpr int __POW10_ADDITIONAL_BITS = 120;
102102
const uint64_t __s1low = __low2 + __high1 + __c1; // 128
103103
const uint32_t __c2 = __s1low < __low2; // __high1 + __c1 can't overflow, so compare against __low2
104104
const uint64_t __s1high = __high2 + __c2; // 192
105-
_LIBCPP_ASSERT_UNCATEGORIZED(__j >= 128, "");
106-
_LIBCPP_ASSERT_UNCATEGORIZED(__j <= 180, "");
105+
_LIBCPP_ASSERT_INTERNAL(__j >= 128, "");
106+
_LIBCPP_ASSERT_INTERNAL(__j <= 180, "");
107107
#ifdef _LIBCPP_INTRINSIC128
108108
const uint32_t __dist = static_cast<uint32_t>(__j - 128); // __dist: [0, 52]
109109
const uint64_t __shiftedhigh = __s1high >> __dist;

libcxx/src/ryu/d2s.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
154154
// The average output length is 16.38 digits, so we check high-to-low.
155155
// Function precondition: __v is not an 18, 19, or 20-digit number.
156156
// (17 digits are sufficient for round-tripping.)
157-
_LIBCPP_ASSERT_UNCATEGORIZED(__v < 100000000000000000u, "");
157+
_LIBCPP_ASSERT_INTERNAL(__v < 100000000000000000u, "");
158158
if (__v >= 10000000000000000u) { return 17; }
159159
if (__v >= 1000000000000000u) { return 16; }
160160
if (__v >= 100000000000000u) { return 15; }

libcxx/src/ryu/f2s.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ inline constexpr uint64_t __FLOAT_POW5_SPLIT[47] = {
8686
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __pow5Factor(uint32_t __value) {
8787
uint32_t __count = 0;
8888
for (;;) {
89-
_LIBCPP_ASSERT_UNCATEGORIZED(__value != 0, "");
89+
_LIBCPP_ASSERT_INTERNAL(__value != 0, "");
9090
const uint32_t __q = __value / 5;
9191
const uint32_t __r = __value % 5;
9292
if (__r != 0) {
@@ -105,14 +105,14 @@ inline constexpr uint64_t __FLOAT_POW5_SPLIT[47] = {
105105

106106
// Returns true if __value is divisible by 2^__p.
107107
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline bool __multipleOfPowerOf2(const uint32_t __value, const uint32_t __p) {
108-
_LIBCPP_ASSERT_UNCATEGORIZED(__value != 0, "");
109-
_LIBCPP_ASSERT_UNCATEGORIZED(__p < 32, "");
108+
_LIBCPP_ASSERT_INTERNAL(__value != 0, "");
109+
_LIBCPP_ASSERT_INTERNAL(__p < 32, "");
110110
// __builtin_ctz doesn't appear to be faster here.
111111
return (__value & ((1u << __p) - 1)) == 0;
112112
}
113113

114114
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __mulShift(const uint32_t __m, const uint64_t __factor, const int32_t __shift) {
115-
_LIBCPP_ASSERT_UNCATEGORIZED(__shift > 32, "");
115+
_LIBCPP_ASSERT_INTERNAL(__shift > 32, "");
116116

117117
// The casts here help MSVC to avoid calls to the __allmul library
118118
// function.
@@ -134,7 +134,7 @@ inline constexpr uint64_t __FLOAT_POW5_SPLIT[47] = {
134134
#else // ^^^ 32-bit ^^^ / vvv 64-bit vvv
135135
const uint64_t __sum = (__bits0 >> 32) + __bits1;
136136
const uint64_t __shiftedSum = __sum >> (__shift - 32);
137-
_LIBCPP_ASSERT_UNCATEGORIZED(__shiftedSum <= UINT32_MAX, "");
137+
_LIBCPP_ASSERT_INTERNAL(__shiftedSum <= UINT32_MAX, "");
138138
return static_cast<uint32_t>(__shiftedSum);
139139
#endif // ^^^ 64-bit ^^^
140140
}
@@ -309,8 +309,8 @@ struct __floating_decimal_32 {
309309
// Performance note: Long division appears to be faster than losslessly widening float to double and calling
310310
// __d2fixed_buffered_n(). If __f2fixed_buffered_n() is implemented, it might be faster than long division.
311311

312-
_LIBCPP_ASSERT_UNCATEGORIZED(_Exponent2 > 0, "");
313-
_LIBCPP_ASSERT_UNCATEGORIZED(_Exponent2 <= 104, ""); // because __ieeeExponent <= 254
312+
_LIBCPP_ASSERT_INTERNAL(_Exponent2 > 0, "");
313+
_LIBCPP_ASSERT_INTERNAL(_Exponent2 <= 104, ""); // because __ieeeExponent <= 254
314314

315315
// Manually represent _Mantissa2 * 2^_Exponent2 as a large integer. _Mantissa2 is always 24 bits
316316
// (due to the implicit bit), while _Exponent2 indicates a shift of at most 104 bits.
@@ -328,7 +328,7 @@ struct __floating_decimal_32 {
328328

329329
// _Maxidx is the index of the most significant nonzero element.
330330
uint32_t _Maxidx = ((24 + static_cast<uint32_t>(_Exponent2) + 31) / 32) - 1;
331-
_LIBCPP_ASSERT_UNCATEGORIZED(_Maxidx < _Data_size, "");
331+
_LIBCPP_ASSERT_INTERNAL(_Maxidx < _Data_size, "");
332332

333333
const uint32_t _Bit_shift = static_cast<uint32_t>(_Exponent2) % 32;
334334
if (_Bit_shift <= 8) { // _Mantissa2's 24 bits don't cross an element boundary
@@ -388,9 +388,9 @@ struct __floating_decimal_32 {
388388
}
389389
}
390390

391-
_LIBCPP_ASSERT_UNCATEGORIZED(_Data[0] != 0, "");
391+
_LIBCPP_ASSERT_INTERNAL(_Data[0] != 0, "");
392392
for (uint32_t _Idx = 1; _Idx < _Data_size; ++_Idx) {
393-
_LIBCPP_ASSERT_UNCATEGORIZED(_Data[_Idx] == 0, "");
393+
_LIBCPP_ASSERT_INTERNAL(_Data[_Idx] == 0, "");
394394
}
395395

396396
const uint32_t _Data_olength = _Data[0] >= 1000000000 ? 10 : __decimalLength9(_Data[0]);

0 commit comments

Comments
 (0)