Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 26 additions & 11 deletions stl/inc/regex
Original file line number Diff line number Diff line change
Expand Up @@ -1202,16 +1202,17 @@ _INLINE_VAR constexpr unsigned int _Bmp_size = (_Bmp_max + _Bmp_chrs - 1U) / _B
_INLINE_VAR constexpr unsigned int _ARRAY_THRESHOLD = 4U;

enum _Node_flags : int { // flags for nfa nodes with special properties
_Fl_none = 0x000,
_Fl_negate = 0x001,
_Fl_greedy = 0x002,
_Fl_longest = 0x008, // TRANSITION, ABI: 0x004 is unused; the parser previously marked some nodes with it
_Fl_class_negated_w = 0x100,
_Fl_class_negated_s = 0x200,
_Fl_class_negated_d = 0x400,
_Fl_begin_needs_w = 0x100,
_Fl_begin_needs_s = 0x200,
_Fl_begin_needs_d = 0x400
_Fl_none = 0x000,
_Fl_negate = 0x001,
_Fl_greedy = 0x002,
_Fl_longest = 0x008, // TRANSITION, ABI: 0x004 is unused; the parser previously marked some nodes with it
_Fl_class_negated_w = 0x100,
_Fl_class_negated_s = 0x200,
_Fl_class_negated_d = 0x400,
_Fl_class_cl_all_bits = 0x800, // TRANSITION, ABI: GH-5242
_Fl_begin_needs_w = 0x100,
_Fl_begin_needs_s = 0x200,
_Fl_begin_needs_d = 0x400
};

_BITMASK_OPS(_EMPTY_ARGUMENT, _Node_flags)
Expand Down Expand Up @@ -2961,11 +2962,19 @@ template <class _FwdIt, class _Elem, class _RxTraits>
void _Builder<_FwdIt, _Elem, _RxTraits>::_Add_named_class(
typename _RxTraits::char_class_type _Cl, const _Rx_char_class_kind _Kind) {
// add contents of named class to bracket expression
using _Char_class_type = typename _RxTraits::char_class_type;
_Node_class<_Elem, _RxTraits>* _Node = static_cast<_Node_class<_Elem, _RxTraits>*>(_Current);
_Add_elts(_Node, _Cl, _Kind != _Rx_char_class_kind::_Positive);
if (_Bmp_max <= _STD _Max_limit<typename _RxTraits::_Uelem>()) {
if (_Kind == _Rx_char_class_kind::_Positive) {
_Node->_Classes = static_cast<typename _RxTraits::char_class_type>(_Node->_Classes | _Cl);
auto _Cl_all_bits_set = static_cast<_Char_class_type>(-1);
if ((_Node->_Classes != _Cl_all_bits_set && _Cl != _Cl_all_bits_set)
|| _Node->_Classes == _Char_class_type{}) {
_Node->_Classes = static_cast<_Char_class_type>(_Node->_Classes | _Cl);
} else if (_Node->_Classes != _Cl) {
_Node->_Classes = static_cast<_Char_class_type>(_Node->_Classes & _Cl);
_Node->_Flags |= _Fl_class_cl_all_bits;
}
} else {
auto _Node_flag = static_cast<_Node_flags>(_Kind);
_Node->_Flags |= _Node_flag;
Expand Down Expand Up @@ -3514,6 +3523,9 @@ bool _Matcher<_BidIt, _Elem, _RxTraits, _It>::_Do_class(_Node_base* _Nx) { // ap
_Found = true;
} else if (_Node->_Classes != typename _RxTraits::char_class_type{} && _Traits.isctype(_Ch, _Node->_Classes)) {
_Found = true;
} else if ((_Node->_Flags & _Fl_class_cl_all_bits)
&& _Traits.isctype(_Ch, static_cast<typename _RxTraits::char_class_type>(-1))) {
_Found = true;
} else if (_Node->_Equiv && _STD _Lookup_equiv2(_Ch, _Node->_Equiv, _Traits)) {
_Found = true;
} else if ((_Node->_Flags & _Fl_class_negated_w)
Expand Down Expand Up @@ -3890,6 +3902,9 @@ _BidIt _Matcher<_BidIt, _Elem, _RxTraits, _It>::_Skip(_BidIt _First_arg, _BidIt
} else if (_Node->_Classes != typename _RxTraits::char_class_type{}
&& _Traits.isctype(_Ch, _Node->_Classes)) {
_Found = true;
} else if ((_Node->_Flags & _Fl_class_cl_all_bits)
&& _Traits.isctype(_Ch, static_cast<typename _RxTraits::char_class_type>(-1))) {
_Found = true;
} else if (_Node->_Equiv && _STD _Lookup_equiv2(_Ch, _Node->_Equiv, _Traits)) {
_Found = true;
} else if ((_Node->_Flags & _Fl_class_negated_w)
Expand Down
45 changes: 45 additions & 0 deletions tests/std/tests/VSO_0000000_regex_use/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1275,6 +1275,50 @@ void test_gh_5214() {
}
}

void test_gh_5243() {
// GH-5243: <regex>: wregex with regular expression [\w\s] fails to match some spaces
for (wstring pattern : {LR"([\w])", LR"([\w\w])"}) {
const test_wregex word_regex(&g_regexTester, pattern);
word_regex.should_search_match(L"a", L"a");
word_regex.should_search_match(L"2", L"2");
word_regex.should_search_match(L"_", L"_");
word_regex.should_search_match(L"\u00e4", L"\u00e4"); // U+00E4 LATIN SMALL LETTER A WITH DIAERESIS
word_regex.should_search_match(L"\u0662", L"\u0662"); // U+0662 ARABIC-INDIC DIGIT TWO
word_regex.should_search_fail(L" ");
word_regex.should_search_fail(L"\u2028"); // U+2028 LINE SEPARATOR
word_regex.should_search_fail(L".");
word_regex.should_search_fail(L"-");
word_regex.should_search_fail(L"\u203d"); // U+203D INTERROBANG
}
{
const test_wregex space_regex(&g_regexTester, LR"([\s])");
space_regex.should_search_fail(L"a");
space_regex.should_search_fail(L"2");
space_regex.should_search_fail(L"_");
space_regex.should_search_fail(L"\u00e4"); // U+00E4 LATIN SMALL LETTER A WITH DIAERESIS
space_regex.should_search_fail(L"\u0662"); // U+0662 ARABIC-INDIC DIGIT TWO
space_regex.should_search_match(L" ", L" ");
space_regex.should_search_match(L"\u2028", L"\u2028"); // U+2028 LINE SEPARATOR
space_regex.should_search_fail(L".");
space_regex.should_search_fail(L"-");
space_regex.should_search_fail(L"\u203d"); // U+203D INTERROBANG
}
for (wstring pattern : {LR"([\w\s])", LR"([\s\w])"}) {
const test_wregex word_or_space_regex(&g_regexTester, pattern);
word_or_space_regex.should_search_match(L"a", L"a");
word_or_space_regex.should_search_match(L"2", L"2");
word_or_space_regex.should_search_match(L"_", L"_");
word_or_space_regex.should_search_match(L"\u00e4", L"\u00e4"); // U+00E4 LATIN SMALL LETTER A WITH DIAERESIS
word_or_space_regex.should_search_match(L"\u0662", L"\u0662"); // U+0662 ARABIC-INDIC DIGIT TWO
word_or_space_regex.should_search_match(L" ", L" ");
word_or_space_regex.should_search_match(L"\u2028", L"\u2028"); // U+2028 LINE SEPARATOR
word_or_space_regex.should_search_fail(L".");
word_or_space_regex.should_search_fail(L"-");
word_or_space_regex.should_search_fail(L"\u203d"); // U+203D INTERROBANG
}
}


void test_gh_5245() {
// GH-5245: <regex>: Successful negative lookahead assertions
// sometimes mistakenly assign matches to capture groups
Expand Down Expand Up @@ -1660,6 +1704,7 @@ int main() {
test_gh_5167();
test_gh_5192();
test_gh_5214();
test_gh_5243();
test_gh_5245();
test_gh_5253();
test_gh_5362();
Expand Down