Regex: negated character class loop followed by \b incorrectly made atomic
Maintainer thường phản hồi trong vòng 1 ngày
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức phù hợp với người mới
- 54/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- csharp
- Lĩnh vực
- testing-qa
Hướng nghiên cứu
Start by reading RegexCharClass.IsKnownWordClassSubset in src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexCharClass.cs and the fix in PR 125636. Add regression coverage for the listed negated character class patterns, including the source generator if the existing test structure supports it. Confirm the tests fail on .NET 10 and pass on the fixed code; the expected matches are given in the issue.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Description
On .NET 10, a + loop over a negated character class followed by \b is incorrectly made atomic,
so the backtracking engines and the source generator fail to find matches that exist. The
NonBacktracking engine is correct. .NET 9 was correct, and .NET 11 is already correct.
The pattern ^[^a-z]+\b(?:\W+|$) matches nothing at all on .NET 10.
PR 125636 fixed this in .net 11 but doesn't have a dedicated test.
This is not the same as https://github.com/dotnet/runtime/issues/135108
Reproduction Steps
using System.Text.RegularExpressions;
Console.WriteLine(new Regex(@"^[^a-z]+\b\W").IsMatch("A ghi")); // False on .NET 10; True on 9 and 11
Full three-runtime Docker repro (one image per SDK, identical source):
docker build --build-arg SDK_TAG=10.0 --build-arg TFM=net10.0 -t r . && docker run --rm r
| Pattern | Input | .NET 9.0.19 | .NET 10.0.11 | .NET 11.0.0-p7 |
|---|---|---|---|---|
^[^a-z]+\b |
A ghi |
"A " |
"A " |
"A " |
^[^a-z]+\b\W |
A ghi |
"A " |
no match | "A " |
^[^a-z]+\b(?:\W+|$) |
A ghi |
"A " |
no match | "A " |
^[^a-z]*\b(?:\W+|$) |
A ghi |
"A " |
"A " |
"A " |
^[^a-z]{1,}\b\W |
A ghi |
"A " |
no match | "A " |
^[^a-z]{1,9}\b\W |
A ghi |
"A " |
no match | "A " |
^[A-Z ]+\b(?:\W+|$) |
A ghi |
"A " |
"A " |
"A " |
^[^0-9]+\b\W |
A ghi |
"A " |
no match | "A " |
^\W+\b\W |
-- ghi |
no match | no match | no match |
Trigger requires both a loop minimum ≥ 1 (the node.M > 0 guard) and a negated set whose stated
characters are all word characters. RegexOptions.None, Compiled and [GeneratedRegex] are all
affected; NonBacktracking is not.
Expected behavior
Expected true
Actual behavior
.NET 10 returns false.
Regression?
Yes, .NET 9 → .NET 10. Introduced by #117892; incidentally fixed on main by #125636, which replaced
IsKnownWordClassSubset with IsSubsetOf guarded by !IsNegated(subset). Root-cause detail and the
proposed one-line patch for release/10.0 are above.
Known Workarounds
RegexOptions.NonBacktracking— correct on all versions, no pattern change.- Move the boundary into the alternation:
^[^a-z]+(?:\b\W+|$). Note^[^a-z]+(?:\b\W+|\b$)still reproduces, so it only helps when not every branch begins with the boundary. - Avoid the negated class, or use
*where semantics permit.
Configuration
.NET 10.0.14 - incorrect
.NET 10.0.11 (SDK 10.0.400) - incorrect
.NET 9.0.19 (SDK 9.0.317) - correct
.NET 11.0.0-preview.7.26381.103 - correct
Reproduced in the official mcr.microsoft.com/dotnet/sdk images on both linux/arm64 and linux/amd64, and on macOS 15 arm64 directly.
Other information
One guard, mirroring what the category path above it already does:
--- a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexCharClass.cs
+++ b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexCharClass.cs
@@ public static bool IsKnownWordClassSubset(string set)
// If we can enumerate every character in the set quickly, do so, checking to see whether they're all in \w.
- if (CanEasilyEnumerateSetContents(set))
+ // Note: for a negated set this would enumerate the characters that are EXCLUDED, so bail.
+ if (!IsNegated(set) && CanEasilyEnumerateSetContents(set))
{
Plus a regression test, which is missing everywhere today:
// [^a-z] is not a subset of \w - it contains spaces, punctuation, digits and uppercase -
// so [^a-z]+ must not be made atomic ahead of the \b.
yield return (@"^[^a-z]+\b(?:\W+|$)", "CA Actress", RegexOptions.None, 0, 10, true, "CA ");
yield return (@"^[^a-z]+\b\W", "A ghi", RegexOptions.None, 0, 5, true, "A ");
yield return (@"^[^0-9]+\b\W", "A ghi", RegexOptions.None, 0, 5, true, "A ");
Worth landing that test on main too, so .NET 11's currently-incidental correctness is actually pinned.
- Ngôn ngữ chính
- C#
- Star
- 18.4k
- Fork
- 5.8k
- Merge trung bình
- 2 ngày 12 giờ
- Pull request đã merge (30 ngày)
- 579
Chuẩn bị môi trường
Khởi chạy dev container của dự án ngay trên trình duyệt, bằng tài khoản GitHub của bạn.
- Không có Dockerfile hay tệp Docker Compose
- Có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của dotnet/runtime
-
Incorrect loop bound in SizeOptIListSelectIterator.ToListCó thể đã có người làm @equmagg đã nhận hôm nay. Đang mởarea-System.Collections untriaged
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 64/100
dotnet/runtime#137126 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
DbTransaction.SupportsSavepoints docs say Release/ReleaseAsync are expected to throw, but they are no-ops by designCó thể đã có người làm @alaricd đã nhận 1 ngày trước. Đang mởarea-System.Transactions untriaged
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
dotnet/runtime#137040 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
FileSystemGlobbing: Matcher throws ArgumentOutOfRangeException when the rootDir is the same value as the fileCó thể đã có người làm @makazeu đã nhận 1 ngày trước. Đang mởarea-Extensions-FileSystem
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
dotnet/runtime#136989 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Configuration binder source generator emits unqualified List<T> when binding arrays without implicit usingsCó thể đã có người làm @makazeu đã nhận 1 ngày trước. Đang mởarea-Extensions-Configuration bug source-generator
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
dotnet/runtime#136972 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
[wasi] .NET 10: WasmEnableSIMD with AOT fails because WasiApp.targets has -msimd128 commented outĐang mởarea-Build-mono untriaged
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của dotnet/runtime
Issue tương tự
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
Facepunch/sbox-public#12305 ·
Maintainer thường phản hồi trong vòng 5 ngày
-
分享 JVC DVD+RW 4.7G (铼德代工) 实测标定预设Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
JiaFeiMiao-K-Cat/DiscImageStudio#205 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
flyingpie/windows-terminal-quake#419 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Show the per-model weekly limitĐang mởenhancement help wanted
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
-
a-corriger documentation
Độ khó 1/5 1-3 giờ Mức phù hợp với người mới 83/100
christian-raj/S-Aloha#272 ·