From ca3855dc7ea6c043b533ba4bdcacc765fa679296 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20M=C3=BCller?= Date: Mon, 16 Dec 2024 15:21:15 +0100 Subject: [PATCH 1/4] ``: Correct characters not matched by special character dot --- stl/inc/regex | 18 ++++++++- .../std/tests/VSO_0000000_regex_use/test.cpp | 38 +++++++++++++++++++ tests/tr1/tests/regex3/test.cpp | 17 +++------ 3 files changed, 60 insertions(+), 13 deletions(-) diff --git a/stl/inc/regex b/stl/inc/regex index b5fa6cae395..c467abf7edd 100644 --- a/stl/inc/regex +++ b/stl/inc/regex @@ -79,6 +79,8 @@ enum _Meta_type : int { // meta character representations for parser _Meta_nl = '\n', _Meta_cr = '\r', _Meta_bsp = '\b', + _Meta_ls = L'\u2028', + _Meta_ps = L'\u2029', _Meta_chr = 0, _Esc_bsl = '\\', @@ -3507,10 +3509,22 @@ bool _Matcher<_BidIt, _Elem, _RxTraits, _It>::_Match_pat(_Node_base* _Nx) { // c break; case _N_dot: - if (_Tgt_state._Cur == _End || *_Tgt_state._Cur == _Meta_nl || *_Tgt_state._Cur == _Meta_cr) { + if (_Tgt_state._Cur == _End) { _Failed = true; } else { - ++_Tgt_state._Cur; + const _Elem _Ch = *_Tgt_state._Cur; + if (_Sflags + & (regex_constants::basic | regex_constants::extended | regex_constants::grep + | regex_constants::egrep | regex_constants::awk)) { + if (_Ch == _Elem()) { + _Failed = true; + } + } else if (_Ch == _Meta_nl || _Ch == _Meta_cr || _Ch == _Meta_ls || _Ch == _Meta_ps) { // ECMAScript + _Failed = true; + } + if (!_Failed) { + ++_Tgt_state._Cur; + } } break; diff --git a/tests/std/tests/VSO_0000000_regex_use/test.cpp b/tests/std/tests/VSO_0000000_regex_use/test.cpp index ad2efc0d4a6..98d43549c71 100644 --- a/tests/std/tests/VSO_0000000_regex_use/test.cpp +++ b/tests/std/tests/VSO_0000000_regex_use/test.cpp @@ -669,6 +669,43 @@ void test_gh_5160() { neg_regex.should_search_fail(L"xxxYxx\x2009xxxZxxx"); // U+2009 THIN SPACE } +void test_gh_5192() { + // GH-5192: Correct characters not matched by special character dot + using namespace string_literals; + for (const syntax_option_type option : { + regex_constants::basic, + regex_constants::extended, + regex_constants::awk, + regex_constants::grep, + regex_constants::egrep, + }) { + const test_regex regex(&g_regexTester, "^.*", option); + regex.should_search_match("abc\nd\re\0f"s, "abc\nd\re"s); + regex.should_search_match("abcd\re\ngh\0i"s, "abcd\re\ngh"s); + + const test_wregex wregex(&g_regexTester, L"^.*", option); + wregex.should_search_match(L"abc\nd\re\0f"s, L"abc\nd\re"s); + wregex.should_search_match(L"abcd\re\ngh\0i"s, L"abcd\re\ngh"s); + wregex.should_search_match(L"abc\u2028d\ne\0f"s, L"abc\u2028d\ne"s); // U+2028 LINE SEPARATOR + wregex.should_search_match(L"abc\u2029d\ne\0f"s, L"abc\u2029d\ne"s); // U+2029 PARAGRAPH SEPARATOR + } + + for (const syntax_option_type option : { + regex_constants::ECMAScript, + syntax_option_type(), + }) { + const test_regex regex(&g_regexTester, "^.*", option); + regex.should_search_match("ab\0c\nd\re\0f"s, "ab\0c"s); + regex.should_search_match("ab\0cd\re\ngh\0i"s, "ab\0cd"s); + + const test_wregex wregex(&g_regexTester, L"^.*", option); + wregex.should_search_match(L"abc\0\nd\re\0f"s, L"abc\0"s); + wregex.should_search_match(L"ab\0cd\re\ngh\0i"s, L"ab\0cd"s); + wregex.should_search_match(L"ab\0c\u2028d\ne\0f"s, L"ab\0c"s); // U+2028 LINE SEPARATOR + wregex.should_search_match(L"a\0bc\u2029d\ne\0f"s, L"a\0bc"s); // U+2029 PARAGRAPH SEPARATOR + } +} + int main() { test_dev10_449367_case_insensitivity_should_work(); test_dev11_462743_regex_collate_should_not_disable_regex_icase(); @@ -699,6 +736,7 @@ int main() { test_gh_4995(); test_gh_5058(); test_gh_5160(); + test_gh_5192(); return g_regexTester.result(); } diff --git a/tests/tr1/tests/regex3/test.cpp b/tests/tr1/tests/regex3/test.cpp index 1c9c9465cf4..05cd644c1d0 100644 --- a/tests/tr1/tests/regex3/test.cpp +++ b/tests/tr1/tests/regex3/test.cpp @@ -321,17 +321,12 @@ static void test_uncoveredgrammar() { STDString str2(T("Prime number")); STDString str3(T("aaaqxzbbb")); STDString str4(T("aaa\nxzbbb")); - static const STD regex_constants::syntax_option_type flag[6] = { - STD regex_constants::ECMAScript, - STD regex_constants::basic, - STD regex_constants::extended, - STD regex_constants::awk, - STD regex_constants::grep, - STD regex_constants::egrep, - }; - for (int i = 0; i <= 5; i++) { - rx1.assign(T(".*"), flag[i]); - rx2.assign(T("aaa...bbb"), flag[i]); + for (const STD regex_constants::syntax_option_type flag : { + STD regex_constants::ECMAScript, + STD regex_constants::syntax_option_type(), + }) { + rx1.assign(T(".*"), flag); + rx2.assign(T("aaa...bbb"), flag); CHECK(!STD regex_match(str1, rx1)); CHECK(STD regex_match(str2, rx1)); CHECK(STD regex_match(str3, rx2)); From 3ea98a18b104e474f405e704687a8ebdea65d416 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Sun, 12 Jan 2025 15:58:25 -0800 Subject: [PATCH 2/4] Style: 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 c467abf7edd..8b67a09c58f 100644 --- a/stl/inc/regex +++ b/stl/inc/regex @@ -3522,6 +3522,7 @@ bool _Matcher<_BidIt, _Elem, _RxTraits, _It>::_Match_pat(_Node_base* _Nx) { // c } else if (_Ch == _Meta_nl || _Ch == _Meta_cr || _Ch == _Meta_ls || _Ch == _Meta_ps) { // ECMAScript _Failed = true; } + if (!_Failed) { ++_Tgt_state._Cur; } From 11b81b2f8f86482e655f801016b6b59a7020e9c9 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Sun, 12 Jan 2025 16:06:06 -0800 Subject: [PATCH 3/4] Drop unnecessary using-directive for UDLs. --- tests/std/tests/VSO_0000000_regex_use/test.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/std/tests/VSO_0000000_regex_use/test.cpp b/tests/std/tests/VSO_0000000_regex_use/test.cpp index 98d43549c71..65afd0cf542 100644 --- a/tests/std/tests/VSO_0000000_regex_use/test.cpp +++ b/tests/std/tests/VSO_0000000_regex_use/test.cpp @@ -671,7 +671,6 @@ void test_gh_5160() { void test_gh_5192() { // GH-5192: Correct characters not matched by special character dot - using namespace string_literals; for (const syntax_option_type option : { regex_constants::basic, regex_constants::extended, From dd2f2c656b4e5b315776e642210b250ce6d18675 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Sun, 12 Jan 2025 16:16:48 -0800 Subject: [PATCH 4/4] Rename to caretDotStar, wCaretDotStar to avoid shadowing. --- .../std/tests/VSO_0000000_regex_use/test.cpp | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/tests/std/tests/VSO_0000000_regex_use/test.cpp b/tests/std/tests/VSO_0000000_regex_use/test.cpp index 65afd0cf542..74708ed5561 100644 --- a/tests/std/tests/VSO_0000000_regex_use/test.cpp +++ b/tests/std/tests/VSO_0000000_regex_use/test.cpp @@ -678,30 +678,30 @@ void test_gh_5192() { regex_constants::grep, regex_constants::egrep, }) { - const test_regex regex(&g_regexTester, "^.*", option); - regex.should_search_match("abc\nd\re\0f"s, "abc\nd\re"s); - regex.should_search_match("abcd\re\ngh\0i"s, "abcd\re\ngh"s); - - const test_wregex wregex(&g_regexTester, L"^.*", option); - wregex.should_search_match(L"abc\nd\re\0f"s, L"abc\nd\re"s); - wregex.should_search_match(L"abcd\re\ngh\0i"s, L"abcd\re\ngh"s); - wregex.should_search_match(L"abc\u2028d\ne\0f"s, L"abc\u2028d\ne"s); // U+2028 LINE SEPARATOR - wregex.should_search_match(L"abc\u2029d\ne\0f"s, L"abc\u2029d\ne"s); // U+2029 PARAGRAPH SEPARATOR + const test_regex caretDotStar(&g_regexTester, "^.*", option); + caretDotStar.should_search_match("abc\nd\re\0f"s, "abc\nd\re"s); + caretDotStar.should_search_match("abcd\re\ngh\0i"s, "abcd\re\ngh"s); + + const test_wregex wCaretDotStar(&g_regexTester, L"^.*", option); + wCaretDotStar.should_search_match(L"abc\nd\re\0f"s, L"abc\nd\re"s); + wCaretDotStar.should_search_match(L"abcd\re\ngh\0i"s, L"abcd\re\ngh"s); + wCaretDotStar.should_search_match(L"abc\u2028d\ne\0f"s, L"abc\u2028d\ne"s); // U+2028 LINE SEPARATOR + wCaretDotStar.should_search_match(L"abc\u2029d\ne\0f"s, L"abc\u2029d\ne"s); // U+2029 PARAGRAPH SEPARATOR } for (const syntax_option_type option : { regex_constants::ECMAScript, syntax_option_type(), }) { - const test_regex regex(&g_regexTester, "^.*", option); - regex.should_search_match("ab\0c\nd\re\0f"s, "ab\0c"s); - regex.should_search_match("ab\0cd\re\ngh\0i"s, "ab\0cd"s); - - const test_wregex wregex(&g_regexTester, L"^.*", option); - wregex.should_search_match(L"abc\0\nd\re\0f"s, L"abc\0"s); - wregex.should_search_match(L"ab\0cd\re\ngh\0i"s, L"ab\0cd"s); - wregex.should_search_match(L"ab\0c\u2028d\ne\0f"s, L"ab\0c"s); // U+2028 LINE SEPARATOR - wregex.should_search_match(L"a\0bc\u2029d\ne\0f"s, L"a\0bc"s); // U+2029 PARAGRAPH SEPARATOR + const test_regex caretDotStar(&g_regexTester, "^.*", option); + caretDotStar.should_search_match("ab\0c\nd\re\0f"s, "ab\0c"s); + caretDotStar.should_search_match("ab\0cd\re\ngh\0i"s, "ab\0cd"s); + + const test_wregex wCaretDotStar(&g_regexTester, L"^.*", option); + wCaretDotStar.should_search_match(L"abc\0\nd\re\0f"s, L"abc\0"s); + wCaretDotStar.should_search_match(L"ab\0cd\re\ngh\0i"s, L"ab\0cd"s); + wCaretDotStar.should_search_match(L"ab\0c\u2028d\ne\0f"s, L"ab\0c"s); // U+2028 LINE SEPARATOR + wCaretDotStar.should_search_match(L"a\0bc\u2029d\ne\0f"s, L"a\0bc"s); // U+2029 PARAGRAPH SEPARATOR } }