From 125c14392ac8236b18ddd745b6f0e4739c7d7c20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20M=C3=BCller?= Date: Mon, 9 Dec 2024 14:29:51 +0100 Subject: [PATCH 1/4] ``: Fix integer overflow in `_Buf` and implement geometric buffer expansion --- stl/inc/regex | 47 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 35 insertions(+), 12 deletions(-) diff --git a/stl/inc/regex b/stl/inc/regex index 77efc9d32f3..1a3f1bfecc6 100644 --- a/stl/inc/regex +++ b/stl/inc/regex @@ -1257,9 +1257,9 @@ struct _Buf { // character buffer return _Chrs; } - void _Insert(_Elem _Ch) { // append _Ch + void _Insert2(_Elem _Ch) { // append _Ch if (_Sz <= _Nchrs) { - _Expand(_Nchrs + _Buf_incr); + _Expand2(1U); } _Chrs[_Nchrs++] = _Ch; @@ -1270,17 +1270,40 @@ struct _Buf { // character buffer } template - void _Insert(_FwdIt _First, _FwdIt _Last) { // append multiple characters + void _Insert2(_FwdIt _First, _FwdIt _Last) { // append multiple characters while (_First != _Last) { - _Insert(*_First++); + _Insert2(*_First++); } } private: - void _Expand(unsigned int _Len) { // expand buffer to hold _Len characters - _Elem* _Tmp = static_cast<_Elem*>(_CSTD realloc(_Chrs, _Get_size_of_n(_Len))); + unsigned int _Calculate_expansion(unsigned int _Increase) const { + constexpr size_t _Max_size_t = static_cast(-1) / sizeof(_Elem); + constexpr unsigned int _Max_uint = static_cast(-1); + constexpr unsigned int _Max = _Max_size_t < _Max_uint ? static_cast(_Max_size_t) : _Max_uint; + + if (_Increase < _Buf_incr) { + _Increase = _Buf_incr; + } + if (_Increase < (_Sz >> 1)) { + _Increase = _Sz >> 1; + } + + if (_Max <= _Increase || _Max - _Increase <= _Sz) { + return _Max; + } + + return _Sz + _Increase; + } + + void _Expand2(const unsigned int _Min_increase) { // expand buffer by at least _Min_increase + const unsigned int _Len = _Calculate_expansion(_Min_increase); + if (_Len - _Sz < _Min_increase) { + _Xregex_error(regex_constants::error_space); + } + _Elem* _Tmp = static_cast<_Elem*>(_CSTD realloc(_Chrs, sizeof(_Elem) * static_cast(_Len))); if (!_Tmp) { - _Xbad_alloc(); + _Xregex_error(regex_constants::error_space); } _Chrs = _Tmp; @@ -2835,7 +2858,7 @@ void _Builder<_FwdIt, _Elem, _RxTraits>::_Add_char(_Elem _Ch) { // append charac } _Node_str<_Elem>* _Node = static_cast<_Node_str<_Elem>*>(_Current); - _Node->_Data._Insert(_Ch); + _Node->_Data._Insert2(_Ch); } template @@ -2869,7 +2892,7 @@ void _Builder<_FwdIt, _Elem, _RxTraits>::_Add_char_to_array(_Elem _Ch) { // appe _Node->_Large = new _Buf<_Elem>; } - _Node->_Large->_Insert(_Ch); + _Node->_Large->_Insert2(_Ch); } template @@ -2912,8 +2935,8 @@ void _Builder<_FwdIt, _Elem, _RxTraits>::_Add_range(_Elem _Arg0, _Elem _Arg1) { _Node->_Ranges = new _Buf<_Elem>; } - _Node->_Ranges->_Insert(static_cast<_Elem>(_Ex0)); - _Node->_Ranges->_Insert(static_cast<_Elem>(_Ex1)); + _Node->_Ranges->_Insert2(static_cast<_Elem>(_Ex0)); + _Node->_Ranges->_Insert2(static_cast<_Elem>(_Ex1)); } } } @@ -2957,7 +2980,7 @@ void _Builder<_FwdIt, _Elem, _RxTraits>::_Char_to_elts(_FwdIt _First, _FwdIt _La *_Cur = new _Sequence<_Elem>(static_cast(_Diff)); (*_Cur)->_Next = _Node; } - (*_Cur)->_Data._Insert(_First, _Last); + (*_Cur)->_Data._Insert2(_First, _Last); } template From ab982f1d709ed555a30ea4f9dce810525465227c Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Sun, 12 Jan 2025 14:44:10 -0800 Subject: [PATCH 2/4] Style: Add newline between non-chained if-statements. --- stl/inc/regex | 1 + 1 file changed, 1 insertion(+) diff --git a/stl/inc/regex b/stl/inc/regex index a9a86b1cadd..150a936ae3a 100644 --- a/stl/inc/regex +++ b/stl/inc/regex @@ -1285,6 +1285,7 @@ private: if (_Increase < _Buf_incr) { _Increase = _Buf_incr; } + if (_Increase < (_Sz >> 1)) { _Increase = _Sz >> 1; } From 594aeca06edafb196620d895037f11322bc39c7c Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Sun, 12 Jan 2025 14:54:10 -0800 Subject: [PATCH 3/4] Naming nitpick: `_Max_size_t` => `_Max_elems` --- stl/inc/regex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stl/inc/regex b/stl/inc/regex index 150a936ae3a..587901e164b 100644 --- a/stl/inc/regex +++ b/stl/inc/regex @@ -1278,9 +1278,9 @@ struct _Buf { // character buffer private: unsigned int _Calculate_expansion(unsigned int _Increase) const { - constexpr size_t _Max_size_t = static_cast(-1) / sizeof(_Elem); + constexpr size_t _Max_elems = static_cast(-1) / sizeof(_Elem); constexpr unsigned int _Max_uint = static_cast(-1); - constexpr unsigned int _Max = _Max_size_t < _Max_uint ? static_cast(_Max_size_t) : _Max_uint; + constexpr unsigned int _Max = _Max_elems < _Max_uint ? static_cast(_Max_elems) : _Max_uint; if (_Increase < _Buf_incr) { _Increase = _Buf_incr; From fe281eb14abd98cea41cb846c97f1255c2a8a608 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Sun, 12 Jan 2025 15:03:37 -0800 Subject: [PATCH 4/4] Move `_Buf_incr` to its point of use. --- stl/inc/regex | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/stl/inc/regex b/stl/inc/regex index 587901e164b..dec33ab4881 100644 --- a/stl/inc/regex +++ b/stl/inc/regex @@ -1195,7 +1195,6 @@ _INLINE_VAR constexpr unsigned int _Bmp_chrs = 1U << _Bmp_shift; // # of bits t _INLINE_VAR constexpr unsigned int _Bmp_mask = _Bmp_chrs - 1U; _INLINE_VAR constexpr unsigned int _Bmp_size = (_Bmp_max + _Bmp_chrs - 1U) / _Bmp_chrs; -_INLINE_VAR constexpr unsigned int _Buf_incr = 16U; _INLINE_VAR constexpr unsigned int _ARRAY_THRESHOLD = 4U; enum _Node_flags : int { // flags for nfa nodes with special properties @@ -1282,6 +1281,8 @@ private: constexpr unsigned int _Max_uint = static_cast(-1); constexpr unsigned int _Max = _Max_elems < _Max_uint ? static_cast(_Max_elems) : _Max_uint; + constexpr unsigned int _Buf_incr = 16U; + if (_Increase < _Buf_incr) { _Increase = _Buf_incr; }