diff --git a/stl/inc/regex b/stl/inc/regex index 2b041163fa7..e2805021159 100644 --- a/stl/inc/regex +++ b/stl/inc/regex @@ -1524,7 +1524,7 @@ public: void _Add_class(); void _Add_char_to_class(_Elem _Ch); void _Add_range2(_Elem, _Elem); - void _Add_named_class(_Regex_traits_base::char_class_type, bool = false); + void _Add_named_class(typename _RxTraits::char_class_type, bool); void _Add_equiv(_FwdIt, _FwdIt, _Difft); void _Add_coll(_FwdIt, _FwdIt, _Difft); _Node_base* _Begin_group(); @@ -1548,7 +1548,7 @@ private: bool _Beg_expr(_Node_base*) const; void _Add_char_to_bitmap(_Elem _Ch); void _Add_char_to_array(_Elem _Ch); - void _Add_elts(_Node_class<_Elem, _RxTraits>*, _Regex_traits_base::char_class_type, bool); + void _Add_elts(_Node_class<_Elem, _RxTraits>*, typename _RxTraits::char_class_type, bool); void _Char_to_elts(_FwdIt, _FwdIt, _Difft, _Sequence<_Elem>**); _Root_node* _Root; @@ -2935,7 +2935,7 @@ void _Builder<_FwdIt, _Elem, _RxTraits>::_Add_range2(const _Elem _Arg0, const _E template void _Builder<_FwdIt, _Elem, _RxTraits>::_Add_elts( - _Node_class<_Elem, _RxTraits>* _Node, _Regex_traits_base::char_class_type _Cl, bool _Negate) { + _Node_class<_Elem, _RxTraits>* _Node, typename _RxTraits::char_class_type _Cl, bool _Negate) { // add characters in named class to set for (unsigned int _Ch = 0; _Ch < _Bmp_max; ++_Ch) { // add elements or their inverse bool _Matches = _Traits.isctype(static_cast<_Elem>(_Ch), _Cl); @@ -2950,12 +2950,12 @@ void _Builder<_FwdIt, _Elem, _RxTraits>::_Add_elts( } template -void _Builder<_FwdIt, _Elem, _RxTraits>::_Add_named_class(typename _Regex_traits_base::char_class_type _Cl, +void _Builder<_FwdIt, _Elem, _RxTraits>::_Add_named_class(typename _RxTraits::char_class_type _Cl, bool _Negate) { // add contents of named class to bracket expression _Node_class<_Elem, _RxTraits>* _Node = static_cast<_Node_class<_Elem, _RxTraits>*>(_Current); _Add_elts(_Node, _Cl, _Negate); - if (_Bmp_max < static_cast(_STD _Max_limit<_Elem>())) { - _Node->_Classes = static_cast<_Regex_traits_base::char_class_type>(_Node->_Classes | _Cl); + if (_Bmp_max <= _STD _Max_limit() && !_Negate) { + _Node->_Classes = static_cast(_Node->_Classes | _Cl); } } @@ -4023,7 +4023,7 @@ void _Parser<_FwdIt, _Elem, _RxTraits>::_Do_ex_class( _Error(regex_constants::error_ctype); } - _Nfa._Add_named_class(_Cls); + _Nfa._Add_named_class(_Cls, false); } else if (_End_arg == _Meta_equal) { // process = if (_Beg == _Pat) { _Error(regex_constants::error_collate); diff --git a/tests/std/tests/VSO_0000000_regex_use/test.cpp b/tests/std/tests/VSO_0000000_regex_use/test.cpp index c699d678eb5..0efb1979e40 100644 --- a/tests/std/tests/VSO_0000000_regex_use/test.cpp +++ b/tests/std/tests/VSO_0000000_regex_use/test.cpp @@ -730,6 +730,24 @@ void test_gh_5192() { } } +void test_gh_5214() { + // GH-5214 makes negated character class escapes not match characters not included in the negated character class + { + const test_wregex neg_word_regex(&g_regexTester, LR"([\W])"); + neg_word_regex.should_search_fail(L"\u0100"); // U+0100 LATIN CAPITAL LETTER A WITH MACRON + } + + { + const test_wregex neg_space_regex(&g_regexTester, LR"([\S])"); + neg_space_regex.should_search_fail(L"\u2028"); // U+2028 LINE SEPARATOR + } + + { + const test_wregex neg_digit_regex(&g_regexTester, LR"([\D])"); + neg_digit_regex.should_search_fail(L"\u0662"); // U+0662 ARABIC-INDIC DIGIT TWO + } +} + int main() { test_dev10_449367_case_insensitivity_should_work(); test_dev11_462743_regex_collate_should_not_disable_regex_icase(); @@ -763,6 +781,7 @@ int main() { test_gh_5160(); test_gh_5167(); test_gh_5192(); + test_gh_5214(); return g_regexTester.result(); }