diff options
author | Austin <zhenhangwang@huawei.com> | 2025-03-11 09:12:14 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-03-11 09:12:14 +0800 |
commit | 9d7ca6cdf038dab24fbc5c22a91be36604decb67 (patch) | |
tree | 69565f728eef5aaa1840d1c405059c803d397a6f | |
parent | 426caf1182caa40a1af8eaa6cf2d88dededa671a (diff) | |
download | llvm-9d7ca6cdf038dab24fbc5c22a91be36604decb67.zip llvm-9d7ca6cdf038dab24fbc5c22a91be36604decb67.tar.gz llvm-9d7ca6cdf038dab24fbc5c22a91be36604decb67.tar.bz2 |
[regex] fix uncaught exception when string is like "\\_" (#129348)
`\_ `is a valid identity escape in regular expressions, but previously
libc++ incorrectly treated it as invalid. So I deleted this judgment
fixes #129062
-rw-r--r-- | libcxx/include/regex | 2 | ||||
-rw-r--r-- | libcxx/test/std/re/re.alg/re.alg.match/ecma.pass.cpp | 32 |
2 files changed, 33 insertions, 1 deletions
diff --git a/libcxx/include/regex b/libcxx/include/regex index eebd68a..96229c6 100644 --- a/libcxx/include/regex +++ b/libcxx/include/regex @@ -3955,7 +3955,7 @@ _ForwardIterator basic_regex<_CharT, _Traits>::__parse_character_escape( ++__first; break; default: - if (*__first != '_' && !__traits_.isctype(*__first, ctype_base::alnum)) { + if (!__traits_.isctype(*__first, ctype_base::alnum)) { if (__str) *__str = *__first; else diff --git a/libcxx/test/std/re/re.alg/re.alg.match/ecma.pass.cpp b/libcxx/test/std/re/re.alg/re.alg.match/ecma.pass.cpp index 4face8b..a069963 100644 --- a/libcxx/test/std/re/re.alg/re.alg.match/ecma.pass.cpp +++ b/libcxx/test/std/re/re.alg/re.alg.match/ecma.pass.cpp @@ -7,6 +7,8 @@ //===----------------------------------------------------------------------===// // +// XFAIL: FROZEN-CXX03-HEADERS-FIXME + // <regex> // template <class BidirectionalIterator, class Allocator, class charT, class traits> @@ -669,6 +671,21 @@ int main(int, char**) assert(m.position(0) == 0); assert(m.str(0) == s); } + { + std::cmatch m; + const char s[] = "$_se"; + assert(std::regex_match(s, m, std::regex("\\$\\_se"))); + assert(m.size() == 1); + assert(!m.prefix().matched); + assert(m.prefix().first == s); + assert(m.prefix().second == m[0].first); + assert(!m.suffix().matched); + assert(m.suffix().first == m[0].second); + assert(m.suffix().second == s + std::char_traits<char>::length(s)); + assert(m.length(0) >= 0 && static_cast<size_t>(m.length(0)) == std::char_traits<char>::length(s)); + assert(m.position(0) == 0); + assert(m.str(0) == s); + } #ifndef TEST_HAS_NO_WIDE_CHARACTERS { @@ -1305,6 +1322,21 @@ int main(int, char**) assert(m.position(0) == 0); assert(m.str(0) == s); } + { + std::wcmatch m; + const wchar_t s[] = L"$_se"; + assert(std::regex_match(s, m, std::wregex(L"\\$\\_se"))); + assert(m.size() == 1); + assert(!m.prefix().matched); + assert(m.prefix().first == s); + assert(m.prefix().second == m[0].first); + assert(!m.suffix().matched); + assert(m.suffix().first == m[0].second); + assert(m.suffix().second == s + std::char_traits<wchar_t>::length(s)); + assert(m.length(0) >= 0 && static_cast<std::size_t>(m.length(0)) == std::char_traits<wchar_t>::length(s)); + assert(m.position(0) == 0); + assert(m.str(0) == s); + } #endif // TEST_HAS_NO_WIDE_CHARACTERS return 0; |