Skip to content

Commit 9d7ca6c

Browse files
authored
[regex] fix uncaught exception when string is like "\\_" (llvm#129348)
`\_ `is a valid identity escape in regular expressions, but previously libc++ incorrectly treated it as invalid. So I deleted this judgment fixes llvm#129062
1 parent 426caf1 commit 9d7ca6c

File tree

2 files changed

+33
-1
lines changed

2 files changed

+33
-1
lines changed

libcxx/include/regex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3955,7 +3955,7 @@ _ForwardIterator basic_regex<_CharT, _Traits>::__parse_character_escape(
39553955
++__first;
39563956
break;
39573957
default:
3958-
if (*__first != '_' && !__traits_.isctype(*__first, ctype_base::alnum)) {
3958+
if (!__traits_.isctype(*__first, ctype_base::alnum)) {
39593959
if (__str)
39603960
*__str = *__first;
39613961
else

libcxx/test/std/re/re.alg/re.alg.match/ecma.pass.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
//===----------------------------------------------------------------------===//
88
//
99

10+
// XFAIL: FROZEN-CXX03-HEADERS-FIXME
11+
1012
// <regex>
1113

1214
// template <class BidirectionalIterator, class Allocator, class charT, class traits>
@@ -669,6 +671,21 @@ int main(int, char**)
669671
assert(m.position(0) == 0);
670672
assert(m.str(0) == s);
671673
}
674+
{
675+
std::cmatch m;
676+
const char s[] = "$_se";
677+
assert(std::regex_match(s, m, std::regex("\\$\\_se")));
678+
assert(m.size() == 1);
679+
assert(!m.prefix().matched);
680+
assert(m.prefix().first == s);
681+
assert(m.prefix().second == m[0].first);
682+
assert(!m.suffix().matched);
683+
assert(m.suffix().first == m[0].second);
684+
assert(m.suffix().second == s + std::char_traits<char>::length(s));
685+
assert(m.length(0) >= 0 && static_cast<size_t>(m.length(0)) == std::char_traits<char>::length(s));
686+
assert(m.position(0) == 0);
687+
assert(m.str(0) == s);
688+
}
672689

673690
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
674691
{
@@ -1305,6 +1322,21 @@ int main(int, char**)
13051322
assert(m.position(0) == 0);
13061323
assert(m.str(0) == s);
13071324
}
1325+
{
1326+
std::wcmatch m;
1327+
const wchar_t s[] = L"$_se";
1328+
assert(std::regex_match(s, m, std::wregex(L"\\$\\_se")));
1329+
assert(m.size() == 1);
1330+
assert(!m.prefix().matched);
1331+
assert(m.prefix().first == s);
1332+
assert(m.prefix().second == m[0].first);
1333+
assert(!m.suffix().matched);
1334+
assert(m.suffix().first == m[0].second);
1335+
assert(m.suffix().second == s + std::char_traits<wchar_t>::length(s));
1336+
assert(m.length(0) >= 0 && static_cast<std::size_t>(m.length(0)) == std::char_traits<wchar_t>::length(s));
1337+
assert(m.position(0) == 0);
1338+
assert(m.str(0) == s);
1339+
}
13081340
#endif // TEST_HAS_NO_WIDE_CHARACTERS
13091341

13101342
return 0;

0 commit comments

Comments
 (0)