From 30fb4afccf883f4b3295735c4502bea6e56de4e4 Mon Sep 17 00:00:00 2001 From: Matt Stephanson Date: Tue, 23 Sep 2025 22:39:23 -0700 Subject: [PATCH 1/3] Prevent full-width shifts in `independent_bits_engine` --- stl/inc/random | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/stl/inc/random b/stl/inc/random index 7a033d12e4c..93cc44efab2 100644 --- a/stl/inc/random +++ b/stl/inc/random @@ -1900,29 +1900,27 @@ public: } _NODISCARD result_type operator()() { - size_t _Idx = 0; - result_type _Res = 0; result_type _Mask = ((result_type{1} << (_Wx0 - 1)) << 1) - 1; _Eres _Val; + do { // get a small enough value + _Val = _Eng() - (_Engine::min) (); + } while (_Val > _Yx0); + result_type _Res = static_cast(_Val) & _Mask; + + size_t _Idx = 1; for (; _Idx < _Nx0; ++_Idx) { // pack _Wx0-bit values - for (;;) { // get a small enough value + do { _Val = _Eng() - (_Engine::min) (); - if (_Val <= _Yx0) { - break; - } - } + } while (_Val > _Yx0); _Res = _Res << _Wx0 | (static_cast(_Val) & _Mask); } _Mask = _Mask << 1 | 1; for (; _Idx < _Nx; ++_Idx) { // pack _Wx0+1-bit values - for (;;) { // get a small enough value + do { _Val = _Eng() - (_Engine::min) (); - if (_Val <= _Yx1) { - break; - } - } + } while (_Val > _Yx1); _Res = _Res << (_Wx0 + 1) | (static_cast(_Val) & _Mask); } return _Res; @@ -1974,8 +1972,13 @@ private: _Nx = (_Wx + _Mx - 1) / _Mx + _Nfix; // trial _Nx _Wx0 = _Wx / _Nx; _Nx0 = _Nx - _Wx % _Nx; - _Yx0 = (_Rx >> _Wx0) << _Wx0; - _Yx1 = (((_Rx >> _Wx0) >> 1) << _Wx0) << 1; + if (_Wx < sizeof(_Eres) * CHAR_BIT) { + _Yx0 = (_Rx >> _Wx0) << _Wx0; + _Yx1 = (((_Rx >> _Wx0) >> 1) << _Wx0) << 1; + } else { + _Yx0 = 0; + _Yx1 = 0; + } if (_Nfix == 1 || _Rx - _Yx0 <= _Yx0 / _Nx) { break; // also works if _Rx == 0 (_Mx == all bits) } From cae489ea5bf385f0e0fa13b228036e813921e659 Mon Sep 17 00:00:00 2001 From: Matt Stephanson Date: Wed, 24 Sep 2025 19:57:38 -0700 Subject: [PATCH 2/3] Fix typo --- stl/inc/random | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stl/inc/random b/stl/inc/random index 93cc44efab2..dddb30fc2ec 100644 --- a/stl/inc/random +++ b/stl/inc/random @@ -1972,7 +1972,7 @@ private: _Nx = (_Wx + _Mx - 1) / _Mx + _Nfix; // trial _Nx _Wx0 = _Wx / _Nx; _Nx0 = _Nx - _Wx % _Nx; - if (_Wx < sizeof(_Eres) * CHAR_BIT) { + if (_Wx0 < sizeof(_Eres) * CHAR_BIT) { _Yx0 = (_Rx >> _Wx0) << _Wx0; _Yx1 = (((_Rx >> _Wx0) >> 1) << _Wx0) << 1; } else { From 32bf2ea1fc13130859f545d61bd38a2f0340f04b Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Wed, 24 Sep 2025 22:09:36 -0700 Subject: [PATCH 3/3] Add newline. --- stl/inc/random | 1 + 1 file changed, 1 insertion(+) diff --git a/stl/inc/random b/stl/inc/random index dddb30fc2ec..f2f83da50b9 100644 --- a/stl/inc/random +++ b/stl/inc/random @@ -1979,6 +1979,7 @@ private: _Yx0 = 0; _Yx1 = 0; } + if (_Nfix == 1 || _Rx - _Yx0 <= _Yx0 / _Nx) { break; // also works if _Rx == 0 (_Mx == all bits) }