Skip to content

Commit 205baa4

Browse files
committed
fix(prefer-includes): prevent false positive on regex metacharacters like \d, \w, \s (#462)
Fixes oxc-project/oxc#16001
1 parent a5c2f9a commit 205baa4

File tree

2 files changed

+32
-1
lines changed

2 files changed

+32
-1
lines changed

internal/rules/prefer_includes/prefer_includes.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,23 @@ var PreferIncludesRule = rule.Rule{
3838

3939
// Check if a pattern string contains only simple literal characters
4040
// The TypeScript version uses a proper ECMAScript regex parser (@eslint-community/regexpp),
41-
// but we just check for unescaped metacharacters.
41+
// but we just check for unescaped metacharacters and escaped special sequences.
4242
isSimpleLiteralPattern := func(pattern string) bool {
4343
prevRune := rune(0)
4444
for _, ch := range pattern {
4545
if prevRune != '\\' {
46+
// Unescaped regex metacharacters
4647
switch ch {
4748
case '.', '*', '+', '?', '|', '^', '$', '[', ']', '(', ')', '{', '}':
4849
return false
4950
}
51+
} else {
52+
// Escaped sequences that are regex metacharacters (not simple literals)
53+
// \d, \D, \w, \W, \s, \S, \b, \B, \0, \n, \r, \t, \v, \f, \cX, \xHH, \uHHHH, \u{HHHH}
54+
switch ch {
55+
case 'd', 'D', 'w', 'W', 's', 'S', 'b', 'B', 'c', 'x', 'u':
56+
return false
57+
}
5058
}
5159
prevRune = ch
5260
}

internal/rules/prefer_includes/prefer_includes_test.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,29 @@ func TestPreferIncludesRule(t *testing.T) {
8989
function f(a) {
9090
return pattern.test(a);
9191
}
92+
`},
93+
{Code: `
94+
const numbers = /\d/;
95+
function f(password: string): void {
96+
if (numbers.test(password)) {
97+
// Should not be flagged - \d is a regex metacharacter
98+
}
99+
}
100+
`},
101+
{Code: `
102+
function f(password: string): void {
103+
/\d/.test(password);
104+
}
105+
`},
106+
{Code: `
107+
function f(text: string): void {
108+
/\w+/.test(text);
109+
}
110+
`},
111+
{Code: `
112+
function f(text: string): void {
113+
/\s/.test(text);
114+
}
92115
`},
93116
}, []rule_tester.InvalidTestCase{
94117
{

0 commit comments

Comments
 (0)