aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAustin <zhenhangwang@huawei.com>2025-03-11 09:12:14 +0800
committerGitHub <noreply@github.com>2025-03-11 09:12:14 +0800
commit9d7ca6cdf038dab24fbc5c22a91be36604decb67 (patch)
tree69565f728eef5aaa1840d1c405059c803d397a6f
parent426caf1182caa40a1af8eaa6cf2d88dededa671a (diff)
downloadllvm-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/regex2
-rw-r--r--libcxx/test/std/re/re.alg/re.alg.match/ecma.pass.cpp32
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;